/*------------------------------------------------------------------------
 * 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 Test for VK_EXT_multi_draw
 *//*--------------------------------------------------------------------*/

#include "vktDrawMultiExtTests.hpp"

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

#include "tcuTexture.hpp"
#include "tcuMaybe.hpp"
#include "tcuImageCompare.hpp"

#include "deUniquePtr.hpp"
#include "deMath.h"
#include "deRandom.hpp"

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

using namespace vk;

namespace vkt
{
namespace Draw
{

namespace
{

// Normal or indexed draws.
enum class DrawType { NORMAL = 0, INDEXED };

// How to apply the vertex offset in indexed draws.
enum class VertexOffsetType
{
	MIXED = 0,			// Do not use pVertexOffset and mix values in struct-indicated offsets.
	CONSTANT_RANDOM,	// Use a constant value for pVertexOffset and fill offset struct members with random values.
	CONSTANT_PACK,		// Use a constant value for pVertexOffset and a stride that removes the vertex offset member in structs.
};

// Triangle mesh type.
enum class MeshType { MOSAIC = 0, OVERLAPPING };

// Vertex offset parameters.
struct VertexOffsetParams
{
	VertexOffsetType	offsetType;
	deUint32			offset;
};

// Test parameters.
struct TestParams
{
	MeshType						meshType;
	DrawType						drawType;
	deUint32						drawCount;
	deUint32						instanceCount;
	deUint32						firstInstance;
	deUint32						stride;
	tcu::Maybe<VertexOffsetParams>	vertexOffset;	// Only used for indexed draws.
	deUint32						seed;
	bool							useTessellation;
	bool							useGeometry;
	bool							multiview;

	deUint32 maxInstanceIndex () const
	{
		if (instanceCount == 0u)
			return 0u;
		return (firstInstance + instanceCount - 1u);
	}
};

// For the color attachment. Must match what the fragment shader expects.
VkFormat getColorFormat ()
{
	return VK_FORMAT_R8G8B8A8_UINT;
}

// Compatible with getColorFormat() but better when used with the image logging facilities.
VkFormat getVerificationFormat ()
{
	return VK_FORMAT_R8G8B8A8_UNORM;
}

// Find a suitable format for the depth/stencil buffer.
VkFormat chooseDepthStencilFormat (const InstanceInterface& vki, VkPhysicalDevice physDev)
{
	// The spec mandates support for one of these two formats.
	const VkFormat candidates[] = { VK_FORMAT_D32_SFLOAT_S8_UINT, VK_FORMAT_D24_UNORM_S8_UINT };

	for (const auto& format : candidates)
	{
		const auto properties = getPhysicalDeviceFormatProperties(vki, physDev, format);
		if ((properties.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) != 0u)
			return format;
	}

	TCU_FAIL("No suitable depth/stencil format found");
	return VK_FORMAT_UNDEFINED; // Unreachable.
}

// Format used when verifying the stencil aspect.
VkFormat getStencilVerificationFormat ()
{
	return VK_FORMAT_S8_UINT;
}

deUint32 getTriangleCount ()
{
	return 1024u;	// This matches the minumum allowed limit for maxMultiDrawCount, so we can submit a single triangle per draw call.
}

// Base class for creating triangles.
class TriangleGenerator
{
public:
	// Append a new triangle for ID (x, y).
	virtual void appendTriangle(deUint32 x, deUint32 y, std::vector<tcu::Vec4>& vertices) = 0;
};

// Class that helps creating triangle vertices for each framebuffer pixel, forming a mosaic of triangles.
class TriangleMosaicGenerator : public TriangleGenerator
{
private:
	// Normalized width and height taking into account the framebuffer's width and height are two units (from -1 to 1).
	float	m_pixelWidth;
	float	m_pixelHeight;

	float	m_deltaX;
	float	m_deltaY;

public:
	TriangleMosaicGenerator (deUint32 width, deUint32 height)
		: m_pixelWidth	(2.0f / static_cast<float>(width))
		, m_pixelHeight	(2.0f / static_cast<float>(height))
		, m_deltaX		(m_pixelWidth * 0.25f)
		, m_deltaY		(m_pixelHeight * 0.25f)
	{}

	// Creates a triangle for framebuffer pixel (x, y) around its center. Appends the triangle vertices to the given list.
	void appendTriangle(deUint32 x, deUint32 y, std::vector<tcu::Vec4>& vertices) override
	{
		// Pixel center.
		const float coordX	= (static_cast<float>(x) + 0.5f) * m_pixelWidth - 1.0f;
		const float coordY	= (static_cast<float>(y) + 0.5f) * m_pixelHeight - 1.0f;

		// Triangle around it.
		const float topY	= coordY - m_deltaY;
		const float bottomY	= coordY + m_deltaY;

		const float leftX	= coordX - m_deltaX;
		const float rightX	= coordX + m_deltaX;

		// Note: clockwise.
		vertices.emplace_back(leftX,	bottomY,	0.0f, 1.0f);
		vertices.emplace_back(coordX,	topY,		0.0f, 1.0f);
		vertices.emplace_back(rightX,	bottomY,	0.0f, 1.0f);
	}
};

// Class that helps create full-screen triangles that overlap each other.
// This generator will generate width*height full-screen triangles with decreasing depth from 0.75 to 0.25.
class TriangleOverlapGenerator : public TriangleGenerator
{
private:
	// Normalized width and height taking into account the framebuffer's width and height are two units (from -1 to 1).
	deUint32	m_width;
	deUint32	m_totalPixels;
	float		m_depthStep;

	static constexpr float kMinDepth	= 0.25f;
	static constexpr float kMaxDepth	= 0.75f;
	static constexpr float kDepthRange	= kMaxDepth - kMinDepth;

public:
	TriangleOverlapGenerator (deUint32 width, deUint32 height)
		: m_width		(width)
		, m_totalPixels (width * height)
		, m_depthStep	(kDepthRange / static_cast<float>(m_totalPixels))
	{}

	// Creates full-screen triangle with 2D id (x, y) and decreasing depth with increasing ids.
	void appendTriangle(deUint32 x, deUint32 y, std::vector<tcu::Vec4>& vertices) override
	{
		const auto pixelId	= static_cast<float>(y * m_width + x);
		const auto depth	= kMaxDepth - m_depthStep * pixelId;

		// Note: clockwise.
		vertices.emplace_back(-1.0f,	-1.0f,	depth, 1.0f);
		vertices.emplace_back(4.0f,		-1.0f,	depth, 1.0f);
		vertices.emplace_back(-1.0f,	4.0f,	depth, 1.0f);
	}
};

// Class that helps creating a suitable draw info vector.
class DrawInfoPacker
{
private:
	DrawType						m_drawType;
	tcu::Maybe<VertexOffsetType>	m_offsetType;	// Offset type when m_drawType is DrawType::INDEXED.
	deUint32						m_stride;		// Desired stride. Must be zero or at least as big as the needed VkMultiDraw*InfoExt.
	deUint32						m_extraBytes;	// Used to match the desired stride.
	de::Random						m_random;		// Used to generate random offsets.
	deUint32						m_infoCount;	// How many infos have we appended so far?
	std::vector<deUint8>			m_dataVec;		// Data vector in generic form.

	// Are draws indexed and using the offset member of VkMultiDrawIndexedInfoEXT?
	static bool indexedWithOffset (DrawType drawType, const tcu::Maybe<VertexOffsetType>& offsetType)
	{
		return (drawType == DrawType::INDEXED && *offsetType != VertexOffsetType::CONSTANT_PACK);
	}

	// Size in bytes for the base structure used with the given draw type.
	static deUint32 baseSize (DrawType drawType, const tcu::Maybe<VertexOffsetType>& offsetType)
	{
		return static_cast<deUint32>(indexedWithOffset(drawType, offsetType) ? sizeof(VkMultiDrawIndexedInfoEXT) : sizeof(VkMultiDrawInfoEXT));
	}

	// Number of extra bytes per entry according to the given stride.
	static deUint32 calcExtraBytes (DrawType drawType, const tcu::Maybe<VertexOffsetType>& offsetType, deUint32 stride)
	{
		// Stride 0 is a special allowed case.
		if (stride == 0u)
			return 0u;

		const auto minStride = baseSize(drawType, offsetType);
		DE_ASSERT(stride >= minStride);
		return (stride - minStride);
	}

	// Entry size in bytes taking into account the number of extra bytes due to stride.
	deUint32 entrySize () const
	{
		return baseSize(m_drawType, m_offsetType) + m_extraBytes;
	}

public:
	DrawInfoPacker	(DrawType drawType, const tcu::Maybe<VertexOffsetType>& offsetType, deUint32 stride, deUint32 estimatedInfoCount, deUint32 seed)
		: m_drawType	(drawType)
		, m_offsetType	(offsetType)
		, m_stride		(stride)
		, m_extraBytes	(calcExtraBytes(drawType, offsetType, stride))
		, m_random		(seed)
		, m_infoCount	(0u)
		, m_dataVec		()
	{
		// estimatedInfoCount is used to avoid excessive reallocation.
		if (estimatedInfoCount > 0u)
			m_dataVec.reserve(estimatedInfoCount * entrySize());
	}

	void addDrawInfo (deUint32 first, deUint32 count, deInt32 offset)
	{
		std::vector<deUint8> entry(entrySize(), 0);

		if (indexedWithOffset(m_drawType, m_offsetType))
		{
			const auto usedOffset = ((*m_offsetType == VertexOffsetType::CONSTANT_RANDOM) ? m_random.getInt32() : offset);
			const VkMultiDrawIndexedInfoEXT info = { first, count, usedOffset };
			deMemcpy(entry.data(), &info, sizeof(info));
		}
		else
		{
			const VkMultiDrawInfoEXT info = { first, count };
			deMemcpy(entry.data(), &info, sizeof(info));
		}

		std::copy(begin(entry), end(entry), std::back_inserter(m_dataVec));
		++m_infoCount;
	}

	deUint32 drawInfoCount () const
	{
		return m_infoCount;
	}

	const void* drawInfoData () const
	{
		return m_dataVec.data();
	}

	deUint32 stride () const
	{
		return m_stride;
	}
};

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

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

private:
	TestParams		m_params;
};

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

	tcu::TestStatus		iterate				(void) override;

private:
	TestParams			m_params;
};

MultiDrawTest::MultiDrawTest (tcu::TestContext& testCtx, const std::string& name, const std::string& description, const TestParams& params)
	: vkt::TestCase	(testCtx, name, description)
	, m_params		(params)
{}

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

void MultiDrawTest::checkSupport (Context& context) const
{
	context.requireDeviceFunctionality("VK_EXT_multi_draw");

	if (m_params.useTessellation)
		context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_TESSELLATION_SHADER);

	if (m_params.useGeometry)
		context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_GEOMETRY_SHADER);

	if (m_params.multiview)
	{
		const auto& multiviewFeatures = context.getMultiviewFeatures();

		if (!multiviewFeatures.multiview)
			TCU_THROW(NotSupportedError, "Multiview not supported");

		if (m_params.useTessellation && !multiviewFeatures.multiviewTessellationShader)
			TCU_THROW(NotSupportedError, "Multiview not supported with tesellation shaders");

		if (m_params.useGeometry && !multiviewFeatures.multiviewGeometryShader)
			TCU_THROW(NotSupportedError, "Multiview not supported with geometry shaders");
	}
}

void MultiDrawTest::initPrograms (vk::SourceCollections& programCollection) const
{
	// The general idea behind these tests is to have a 32x32 framebuffer with 1024 pixels and 1024 triangles to draw.
	//
	// When using a mosaic mesh, the tests will generally draw a single triangle around the center of each of these pixels. When
	// using an overlapping mesh, each single triangle will cover the whole framebuffer using a different depth value, and the depth
	// test will be enabled.
	//
	// The color of each triangle will depend on the instance index, the draw index and, when using multiview, the view index. This
	// way, it's possible to draw those 1024 triangles with a single draw call or to draw each triangle with a separate draw call,
	// with up to 1024 draw calls. Combinations in between are possible.
	//
	// With overlapping meshes, the resulting color buffer will be uniform in color. With mosaic meshes, it depends on the submitted
	// draw count. In some cases, all pixels will be slightly different in color.
	//
	// The color buffer will be cleared to transparent black when beginning the render pass, and in some special cases some or all
	// pixels will preserve that clear color because they will not be drawn into. This happens, for example, if the instance count
	// or draw count is zero and in some cases of meshed geometry with stride zero.
	//
	// The output color for each pixel will:
	// - Have the draw index split into the R and G components.
	// - Have the instance index I stored into the B component as 255-I.
	//
	// In addition, the tests will use a depth/stencil buffer. The stencil buffer will be cleared to zero and the depth buffer to an
	// appropriate initial value (0.0 or 1.0, depending on triangle order). The stencil component will be increased with each draw
	// on each pixel. This will allow us to verify that not only the last draw for the last instance has set the proper color, but
	// that all draw operations have taken place.

	// Make sure the blue channel can be calculated without issues.
	DE_ASSERT(m_params.maxInstanceIndex() <= 255u);

	std::ostringstream vert;
	vert
		<< "#version 460\n"
		<< (m_params.multiview ? "#extension GL_EXT_multiview : enable\n" : "")
		<< "\n"
		<< "out gl_PerVertex\n"
		<< "{\n"
		<< "    vec4 gl_Position;\n"
		<< "};\n"
		<< "\n"
		<< "layout (location=0) in vec4 inPos;\n"
		<< "layout (location=0) out uvec4 outColor;\n"
		<< "\n"
		<< "void main()\n"
		<< "{\n"
		<< "    gl_Position = inPos;\n"
		<< "    const uint uDrawIndex = uint(gl_DrawID);\n"
		<< "    outColor.r = ((uDrawIndex >> 8u) & 0xFFu);\n"
		<< "    outColor.g = ((uDrawIndex      ) & 0xFFu);\n"
		<< "    outColor.b = 255u - uint(gl_InstanceIndex);\n"
		<< "    outColor.a = 255u" << (m_params.multiview ? " - uint(gl_ViewIndex)" : "") << ";\n"
		<< "}\n"
		;
	programCollection.glslSources.add("vert") << glu::VertexSource(vert.str());

	std::ostringstream frag;
	frag
		<< "#version 460\n"
		<< "\n"
		<< "layout (location=0) flat in uvec4 inColor;\n"
		<< "layout (location=0) out uvec4 outColor;\n"
		<< "\n"
		<< "void main ()\n"
		<< "{\n"
		<< "    outColor = inColor;\n"
		<< "}\n"
		;
	programCollection.glslSources.add("frag") << glu::FragmentSource(frag.str());

	if (m_params.useTessellation)
	{
		std::ostringstream tesc;
		tesc
			<< "#version 460\n"
			<< "\n"
			<< "layout (vertices=3) out;\n"
			<< "in gl_PerVertex\n"
			<< "{\n"
			<< "    vec4 gl_Position;\n"
			<< "} gl_in[gl_MaxPatchVertices];\n"
			<< "out gl_PerVertex\n"
			<< "{\n"
			<< "    vec4 gl_Position;\n"
			<< "} gl_out[];\n"
			<< "\n"
			<< "layout (location=0) in uvec4 inColor[gl_MaxPatchVertices];\n"
			<< "layout (location=0) out uvec4 outColor[];\n"
			<< "\n"
			<< "void main (void)\n"
			<< "{\n"
			<< "    gl_TessLevelInner[0] = 1.0;\n"
			<< "    gl_TessLevelInner[1] = 1.0;\n"
			<< "    gl_TessLevelOuter[0] = 1.0;\n"
			<< "    gl_TessLevelOuter[1] = 1.0;\n"
			<< "    gl_TessLevelOuter[2] = 1.0;\n"
			<< "    gl_TessLevelOuter[3] = 1.0;\n"
			<< "    gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
			<< "    outColor[gl_InvocationID] = inColor[gl_InvocationID];\n"
			<< "}\n"
			;
		programCollection.glslSources.add("tesc") << glu::TessellationControlSource(tesc.str());

		std::ostringstream tese;
		tese
			<< "#version 460\n"
			<< "\n"
			<< "layout (triangles, fractional_odd_spacing, cw) in;\n"
			<< "in gl_PerVertex\n"
			<< "{\n"
			<< "    vec4 gl_Position;\n"
			<< "} gl_in[gl_MaxPatchVertices];\n"
			<< "out gl_PerVertex\n"
			<< "{\n"
			<< "    vec4 gl_Position;\n"
			<< "};\n"
			<< "\n"
			<< "layout (location=0) in uvec4 inColor[gl_MaxPatchVertices];\n"
			<< "layout (location=0) out uvec4 outColor;\n"
			<< "\n"
			<< "void main (void)\n"
			<< "{\n"
			<< "    gl_Position = (gl_TessCoord.x * gl_in[0].gl_Position) +\n"
			<< "                  (gl_TessCoord.y * gl_in[1].gl_Position) +\n"
			<< "                  (gl_TessCoord.z * gl_in[2].gl_Position);\n"
			<< "    outColor = inColor[0];\n"
			<< "}\n"
			;
		programCollection.glslSources.add("tese") << glu::TessellationEvaluationSource(tese.str());
	}

	if (m_params.useGeometry)
	{
		std::ostringstream geom;
		geom
			<< "#version 460\n"
			<< "\n"
			<< "layout (triangles) in;\n"
			<< "layout (triangle_strip, max_vertices=3) out;\n"
			<< "in gl_PerVertex\n"
			<< "{\n"
			<< "    vec4 gl_Position;\n"
			<< "} gl_in[3];\n"
			<< "out gl_PerVertex\n"
			<< "{\n"
			<< "    vec4 gl_Position;\n"
			<< "};\n"
			<< "\n"
			<< "layout (location=0) in uvec4 inColor[3];\n"
			<< "layout (location=0) out uvec4 outColor;\n"
			<< "\n"
			<< "void main ()\n"
			<< "{\n"
			<< "    gl_Position = gl_in[0].gl_Position; outColor = inColor[0]; EmitVertex();\n"
			<< "    gl_Position = gl_in[1].gl_Position; outColor = inColor[1]; EmitVertex();\n"
			<< "    gl_Position = gl_in[2].gl_Position; outColor = inColor[2]; EmitVertex();\n"
			<< "}\n"
			;
		programCollection.glslSources.add("geom") << glu::GeometrySource(geom.str());
	}
}

MultiDrawInstance::MultiDrawInstance (Context& context, const TestParams& params)
	: vkt::TestInstance	(context)
	, m_params			(params)
{}

void appendPaddingVertices (std::vector<tcu::Vec4>& vertices, deUint32 count)
{
	for (deUint32 i = 0u; i < count; ++i)
		vertices.emplace_back(0.0f, 0.0f, 0.0f, 1.0f);
}

// Creates a render pass with multiple subpasses, one per layer.
Move<VkRenderPass> makeMultidrawRenderPass (const DeviceInterface&	vk,
											VkDevice				device,
											VkFormat				colorFormat,
											VkFormat				depthStencilFormat,
											deUint32				layerCount)
{
	const VkAttachmentDescription colorAttachmentDescription =
	{
		0u,											// VkAttachmentDescriptionFlags    flags
		colorFormat,								// VkFormat                        format
		VK_SAMPLE_COUNT_1_BIT,						// VkSampleCountFlagBits           samples
		VK_ATTACHMENT_LOAD_OP_CLEAR,				// VkAttachmentLoadOp              loadOp
		VK_ATTACHMENT_STORE_OP_STORE,				// VkAttachmentStoreOp             storeOp
		VK_ATTACHMENT_LOAD_OP_DONT_CARE,			// VkAttachmentLoadOp              stencilLoadOp
		VK_ATTACHMENT_STORE_OP_DONT_CARE,			// VkAttachmentStoreOp             stencilStoreOp
		VK_IMAGE_LAYOUT_UNDEFINED,					// VkImageLayout                   initialLayout
		VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,	// VkImageLayout                   finalLayout
	};

	const VkAttachmentDescription depthStencilAttachmentDescription =
	{
		0u,													// VkAttachmentDescriptionFlags    flags
		depthStencilFormat,									// VkFormat                        format
		VK_SAMPLE_COUNT_1_BIT,								// VkSampleCountFlagBits           samples
		VK_ATTACHMENT_LOAD_OP_CLEAR,						// VkAttachmentLoadOp              loadOp
		VK_ATTACHMENT_STORE_OP_STORE,						// VkAttachmentStoreOp             storeOp
		VK_ATTACHMENT_LOAD_OP_CLEAR,						// VkAttachmentLoadOp              stencilLoadOp
		VK_ATTACHMENT_STORE_OP_STORE,						// VkAttachmentStoreOp             stencilStoreOp
		VK_IMAGE_LAYOUT_UNDEFINED,							// VkImageLayout                   initialLayout
		VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,	// VkImageLayout                   finalLayout
	};

	const std::vector<VkAttachmentDescription>	attachmentDescriptions		= { colorAttachmentDescription, depthStencilAttachmentDescription };
	const VkAttachmentReference					colorAttachmentRef			= makeAttachmentReference(0u, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
	const VkAttachmentReference					depthStencilAttachmentRef	= makeAttachmentReference(1u, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);

	const VkSubpassDescription subpassDescription =
	{
		0u,									// VkSubpassDescriptionFlags       flags
		VK_PIPELINE_BIND_POINT_GRAPHICS,	// VkPipelineBindPoint             pipelineBindPoint
		0u,									// deUint32                        inputAttachmentCount
		nullptr,							// const VkAttachmentReference*    pInputAttachments
		1u,									// deUint32                        colorAttachmentCount
		&colorAttachmentRef,				// const VkAttachmentReference*    pColorAttachments
		nullptr,							// const VkAttachmentReference*    pResolveAttachments
		&depthStencilAttachmentRef,			// const VkAttachmentReference*    pDepthStencilAttachment
		0u,									// deUint32                        preserveAttachmentCount
		nullptr								// const deUint32*                 pPreserveAttachments
	};

	std::vector<VkSubpassDescription> subpassDescriptions;

	subpassDescriptions.reserve(layerCount);
	for (deUint32 subpassIdx = 0u; subpassIdx < layerCount; ++subpassIdx)
		subpassDescriptions.push_back(subpassDescription);

	using MultiviewInfoPtr = de::MovePtr<VkRenderPassMultiviewCreateInfo>;

	MultiviewInfoPtr multiviewCreateInfo;
	std::vector<deUint32> viewMasks;

	if (layerCount > 1u)
	{
		multiviewCreateInfo		= MultiviewInfoPtr(new VkRenderPassMultiviewCreateInfo);
		*multiviewCreateInfo	= initVulkanStructure();

		viewMasks.resize(subpassDescriptions.size());
		for (deUint32 subpassIdx = 0u; subpassIdx < static_cast<deUint32>(viewMasks.size()); ++subpassIdx)
			viewMasks[subpassIdx] = (1u << subpassIdx);

		multiviewCreateInfo->subpassCount	= static_cast<deUint32>(viewMasks.size());
		multiviewCreateInfo->pViewMasks		= de::dataOrNull(viewMasks);
	}

	// Dependencies between subpasses for color and depth/stencil read/writes.
	std::vector<VkSubpassDependency> dependencies;
	if (layerCount > 1u)
		dependencies.reserve((layerCount - 1u) * 2u);

	const auto fragmentTestStages	= (VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT);
	const auto dsWrites				= VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
	const auto dsReadWrites			= (VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT);
	const auto colorStage			= VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
	const auto colorWrites			= VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
	const auto colorReadWrites		= (VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_COLOR_ATTACHMENT_READ_BIT);

	for (deUint32 subpassIdx = 1u; subpassIdx < layerCount; ++subpassIdx)
	{
		const auto prev = subpassIdx - 1u;

		const VkSubpassDependency dsDep =
		{
			prev,							//	deUint32				srcSubpass;
			subpassIdx,						//	deUint32				dstSubpass;
			fragmentTestStages,				//	VkPipelineStageFlags	srcStageMask;
			fragmentTestStages,				//	VkPipelineStageFlags	dstStageMask;
			dsWrites,						//	VkAccessFlags			srcAccessMask;
			dsReadWrites,					//	VkAccessFlags			dstAccessMask;
			VK_DEPENDENCY_BY_REGION_BIT,	//	VkDependencyFlags		dependencyFlags;
		};
		dependencies.push_back(dsDep);

		const VkSubpassDependency colorDep =
		{
			prev,							//	deUint32				srcSubpass;
			subpassIdx,						//	deUint32				dstSubpass;
			colorStage,						//	VkPipelineStageFlags	srcStageMask;
			colorStage,						//	VkPipelineStageFlags	dstStageMask;
			colorWrites,					//	VkAccessFlags			srcAccessMask;
			colorReadWrites,				//	VkAccessFlags			dstAccessMask;
			VK_DEPENDENCY_BY_REGION_BIT,	//	VkDependencyFlags		dependencyFlags;
		};
		dependencies.push_back(colorDep);
	}

	const VkRenderPassCreateInfo renderPassInfo =
	{
		VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,				// VkStructureType                   sType
		multiviewCreateInfo.get(),								// const void*                       pNext
		0u,														// VkRenderPassCreateFlags           flags
		static_cast<deUint32>(attachmentDescriptions.size()),	// deUint32                          attachmentCount
		de::dataOrNull(attachmentDescriptions),					// const VkAttachmentDescription*    pAttachments
		static_cast<deUint32>(subpassDescriptions.size()),		// deUint32                          subpassCount
		de::dataOrNull(subpassDescriptions),					// const VkSubpassDescription*       pSubpasses
		static_cast<deUint32>(dependencies.size()),				// deUint32                          dependencyCount
		de::dataOrNull(dependencies),							// const VkSubpassDependency*        pDependencies
	};

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

tcu::TestStatus MultiDrawInstance::iterate (void)
{
	const auto&	vki				= m_context.getInstanceInterface();
	const auto	physDev			= m_context.getPhysicalDevice();
	const auto&	vkd				= m_context.getDeviceInterface();
	const auto	device			= m_context.getDevice();
	auto&		alloc			= m_context.getDefaultAllocator();
	const auto	queue			= m_context.getUniversalQueue();
	const auto	qIndex			= m_context.getUniversalQueueFamilyIndex();

	const auto	colorFormat		= getColorFormat();
	const auto	dsFormat		= chooseDepthStencilFormat(vki, physDev);
	const auto	tcuColorFormat	= mapVkFormat(colorFormat);
	const auto	triangleCount	= getTriangleCount();
	const auto	imageDim		= static_cast<deUint32>(deSqrt(static_cast<double>(triangleCount)));
	const auto	imageExtent		= makeExtent3D(imageDim, imageDim, 1u);
	const auto	imageLayers		= (m_params.multiview ? 2u : 1u);
	const auto	imageViewType	= ((imageLayers > 1u) ? VK_IMAGE_VIEW_TYPE_2D_ARRAY : VK_IMAGE_VIEW_TYPE_2D);
	const auto	colorUsage		= (VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT);
	const auto	dsUsage			= (VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT);
	const auto	pixelCount		= imageExtent.width * imageExtent.height;
	const auto	vertexCount		= pixelCount * 3u; // Triangle list.
	const auto	isIndexed		= (m_params.drawType == DrawType::INDEXED);
	const auto	isMixedMode		= (isIndexed && m_params.vertexOffset && m_params.vertexOffset->offsetType == VertexOffsetType::MIXED);
	const auto	extraVertices	= (m_params.vertexOffset ? m_params.vertexOffset->offset : 0u);
	const auto	isMosaic		= (m_params.meshType == MeshType::MOSAIC);

	// Make sure we're providing a vertex offset for indexed cases.
	DE_ASSERT(!isIndexed || static_cast<bool>(m_params.vertexOffset));

	// Make sure overlapping draws use a single instance.
	DE_ASSERT(isMosaic || m_params.instanceCount <= 1u);

	// Color buffer.
	const VkImageCreateInfo imageCreateInfo =
	{
		VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,	//	VkStructureType			sType;
		nullptr,								//	const void*				pNext;
		0u,										//	VkImageCreateFlags		flags;
		VK_IMAGE_TYPE_2D,						//	VkImageType				imageType;
		colorFormat,							//	VkFormat				format;
		imageExtent,							//	VkExtent3D				extent;
		1u,										//	deUint32				mipLevels;
		imageLayers,							//	deUint32				arrayLayers;
		VK_SAMPLE_COUNT_1_BIT,					//	VkSampleCountFlagBits	samples;
		VK_IMAGE_TILING_OPTIMAL,				//	VkImageTiling			tiling;
		colorUsage,								//	VkImageUsageFlags		usage;
		VK_SHARING_MODE_EXCLUSIVE,				//	VkSharingMode			sharingMode;
		0u,										//	deUint32				queueFamilyIndexCount;
		nullptr,								//	const deUint32*			pQueueFamilyIndices;
		VK_IMAGE_LAYOUT_UNDEFINED,				//	VkImageLayout			initialLayout;
	};

	ImageWithMemory	colorBuffer				(vkd, device, alloc, imageCreateInfo, MemoryRequirement::Any);
	const auto		colorSubresourceRange	= makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, imageLayers);
	const auto		colorBufferView			= makeImageView(vkd, device, colorBuffer.get(), imageViewType, colorFormat, colorSubresourceRange);

	// Depth/stencil buffer.
	const VkImageCreateInfo dsCreateInfo =
	{
		VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,	//	VkStructureType			sType;
		nullptr,								//	const void*				pNext;
		0u,										//	VkImageCreateFlags		flags;
		VK_IMAGE_TYPE_2D,						//	VkImageType				imageType;
		dsFormat,								//	VkFormat				format;
		imageExtent,							//	VkExtent3D				extent;
		1u,										//	deUint32				mipLevels;
		imageLayers,							//	deUint32				arrayLayers;
		VK_SAMPLE_COUNT_1_BIT,					//	VkSampleCountFlagBits	samples;
		VK_IMAGE_TILING_OPTIMAL,				//	VkImageTiling			tiling;
		dsUsage,								//	VkImageUsageFlags		usage;
		VK_SHARING_MODE_EXCLUSIVE,				//	VkSharingMode			sharingMode;
		0u,										//	deUint32				queueFamilyIndexCount;
		nullptr,								//	const deUint32*			pQueueFamilyIndices;
		VK_IMAGE_LAYOUT_UNDEFINED,				//	VkImageLayout			initialLayout;
	};

	ImageWithMemory dsBuffer			(vkd, device, alloc, dsCreateInfo, MemoryRequirement::Any);
	const auto		dsSubresourceRange	= makeImageSubresourceRange((VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT), 0u, 1u, 0u, imageLayers);
	const auto		dsBufferView		= makeImageView(vkd, device, dsBuffer.get(), imageViewType, dsFormat, dsSubresourceRange);

	// Output buffers to verify attachments.
	using BufferWithMemoryPtr = de::MovePtr<BufferWithMemory>;

	// Buffers to read color attachment.
	const auto outputBufferSize = pixelCount * static_cast<VkDeviceSize>(tcu::getPixelSize(tcuColorFormat));
	const auto bufferCreateInfo = makeBufferCreateInfo(outputBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT);

	std::vector<BufferWithMemoryPtr> outputBuffers;
	for (deUint32 i = 0u; i < imageLayers; ++i)
		outputBuffers.push_back(BufferWithMemoryPtr(new BufferWithMemory(vkd, device, alloc, bufferCreateInfo, MemoryRequirement::HostVisible)));

	// Buffer to read depth/stencil attachment. Note: this supposes we'll only copy the stencil aspect. See below.
	const auto			tcuStencilFmt			= mapVkFormat(getStencilVerificationFormat());
	const auto			stencilOutBufferSize	= pixelCount * static_cast<VkDeviceSize>(tcu::getPixelSize(tcuStencilFmt));
	const auto			stencilOutCreateInfo	= makeBufferCreateInfo(stencilOutBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT);

	std::vector<BufferWithMemoryPtr> stencilOutBuffers;
	for (deUint32 i = 0u; i < imageLayers; ++i)
		stencilOutBuffers.push_back(BufferWithMemoryPtr(new BufferWithMemory(vkd, device, alloc, stencilOutCreateInfo, MemoryRequirement::HostVisible)));

	// Shaders.
	const auto				vertModule = createShaderModule(vkd, device, m_context.getBinaryCollection().get("vert"), 0u);
	const auto				fragModule = createShaderModule(vkd, device, m_context.getBinaryCollection().get("frag"), 0u);
	Move<VkShaderModule>	tescModule;
	Move<VkShaderModule>	teseModule;
	Move<VkShaderModule>	geomModule;

	if (m_params.useGeometry)
		geomModule = createShaderModule(vkd, device, m_context.getBinaryCollection().get("geom"), 0u);

	if (m_params.useTessellation)
	{
		tescModule = createShaderModule(vkd, device, m_context.getBinaryCollection().get("tesc"), 0u);
		teseModule = createShaderModule(vkd, device, m_context.getBinaryCollection().get("tese"), 0u);
	}

	DescriptorSetLayoutBuilder	layoutBuilder;
	const auto					descriptorSetLayout	= layoutBuilder.build(vkd, device);
	const auto					pipelineLayout		= makePipelineLayout(vkd, device, descriptorSetLayout.get());

	// Render pass.
	const auto renderPass = makeMultidrawRenderPass(vkd, device, colorFormat, dsFormat, imageLayers);

	// Framebuffer (note layers is always 1 as required by the spec).
	const std::vector<VkImageView> attachments { colorBufferView.get(), dsBufferView.get() };
	const auto framebuffer = makeFramebuffer(vkd, device, renderPass.get(), static_cast<deUint32>(attachments.size()), de::dataOrNull(attachments), imageExtent.width, imageExtent.height, 1u);

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

	// Indexed draws will have triangle vertices in reverse order. See index buffer creation below.
	const auto										frontFace			= (isIndexed ? VK_FRONT_FACE_COUNTER_CLOCKWISE : VK_FRONT_FACE_CLOCKWISE);
	const VkPipelineRasterizationStateCreateInfo	rasterizationInfo	=
	{
		VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,	//	VkStructureType							sType;
		nullptr,													//	const void*								pNext;
		0u,															//	VkPipelineRasterizationStateCreateFlags	flags;
		VK_FALSE,													//	VkBool32								depthClampEnable;
		VK_FALSE,													//	VkBool32								rasterizerDiscardEnable;
		VK_POLYGON_MODE_FILL,										//	VkPolygonMode							polygonMode;
		VK_CULL_MODE_BACK_BIT,										//	VkCullModeFlags							cullMode;
		frontFace,													//	VkFrontFace								frontFace;
		VK_FALSE,													//	VkBool32								depthBiasEnable;
		0.0f,														//	float									depthBiasConstantFactor;
		0.0f,														//	float									depthBiasClamp;
		0.0f,														//	float									depthBiasSlopeFactor;
		1.0f,														//	float									lineWidth;
	};

	const auto frontStencilState	= makeStencilOpState(VK_STENCIL_OP_KEEP, VK_STENCIL_OP_INCREMENT_AND_WRAP, VK_STENCIL_OP_KEEP, VK_COMPARE_OP_ALWAYS, 0xFFu, 0xFFu, 0u);
	const auto backStencilState		= makeStencilOpState(VK_STENCIL_OP_KEEP, VK_STENCIL_OP_KEEP, VK_STENCIL_OP_KEEP, VK_COMPARE_OP_NEVER, 0xFFu, 0xFFu, 0u);
	const auto depthTestEnable		= (isMosaic ? VK_FALSE : VK_TRUE);
	const auto depthWriteEnable		= depthTestEnable;
	const auto depthCompareOp		= (isMosaic ? VK_COMPARE_OP_ALWAYS : (isIndexed ? VK_COMPARE_OP_GREATER : VK_COMPARE_OP_LESS));

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

	const auto primitiveTopology	= (m_params.useTessellation ? VK_PRIMITIVE_TOPOLOGY_PATCH_LIST : VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST);
	const auto patchControlPoints	= (m_params.useTessellation ? 3u : 0u);

	// Pipelines.
	std::vector<Move<VkPipeline>> pipelines;
	pipelines.reserve(imageLayers);
	for (deUint32 subpassIdx = 0u; subpassIdx < imageLayers; ++subpassIdx)
	{
		pipelines.emplace_back(makeGraphicsPipeline(vkd, device, pipelineLayout.get(),
			vertModule.get(), tescModule.get(), teseModule.get(), geomModule.get(), fragModule.get(),
			renderPass.get(), viewports, scissors, primitiveTopology, subpassIdx, patchControlPoints,
			nullptr/*vertexInputStateCreateInfo*/, &rasterizationInfo, nullptr/*multisampleStateCreateInfo*/, &depthStencilInfo));
	}

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

	// Create vertex buffer.
	std::vector<tcu::Vec4> triangleVertices;
	triangleVertices.reserve(vertexCount + extraVertices);

	// Vertex count per draw call.
	const bool atLeastOneDraw	= (m_params.drawCount > 0u);
	const bool moreThanOneDraw	= (m_params.drawCount > 1u);
	const auto trianglesPerDraw	= (atLeastOneDraw ? pixelCount / m_params.drawCount : 0u);
	const auto verticesPerDraw	= trianglesPerDraw * 3u;

	if (atLeastOneDraw)
		DE_ASSERT(pixelCount % m_params.drawCount == 0u);

	{
		using TriangleGeneratorPtr = de::MovePtr<TriangleGenerator>;
		TriangleGeneratorPtr triangleGen;

		if (m_params.meshType == MeshType::MOSAIC)
			triangleGen = TriangleGeneratorPtr(new TriangleMosaicGenerator(imageExtent.width, imageExtent.height));
		else if (m_params.meshType == MeshType::OVERLAPPING)
			triangleGen = TriangleGeneratorPtr(new TriangleOverlapGenerator(imageExtent.width, imageExtent.height));
		else
			DE_ASSERT(false);

		// When applying a vertex offset in nonmixed modes, there will be a few extra vertices at the start of the vertex buffer.
		if (isIndexed && !isMixedMode)
			appendPaddingVertices(triangleVertices, extraVertices);

		for (deUint32 y = 0u; y < imageExtent.height; ++y)
		for (deUint32 x = 0u; x < imageExtent.width; ++x)
		{
			// When applying a vertex offset in mixed mode, there will be some extra padding between the triangles for the first
			// block and the rest, so that the vertex offset will not be constant in all draw info structures. This way, the first
			// triangles will always have offset zero, and the number of them depends on the given draw count.
			const auto pixelIndex = y * imageExtent.width + x;
			if (isIndexed && isMixedMode && moreThanOneDraw && pixelIndex == trianglesPerDraw)
				appendPaddingVertices(triangleVertices, extraVertices);

			triangleGen->appendTriangle(x, y, triangleVertices);
		}
	}

	const auto			vertexBufferSize	= static_cast<VkDeviceSize>(de::dataSize(triangleVertices));
	const auto			vertexBufferInfo	= makeBufferCreateInfo(vertexBufferSize, (VK_BUFFER_USAGE_VERTEX_BUFFER_BIT));
	BufferWithMemory	vertexBuffer		(vkd, device, alloc, vertexBufferInfo, MemoryRequirement::HostVisible);
	auto&				vertexBufferAlloc	= vertexBuffer.getAllocation();
	const auto			vertexBufferOffset	= vertexBufferAlloc.getOffset();
	void*				vertexBufferData	= vertexBufferAlloc.getHostPtr();

	deMemcpy(vertexBufferData, triangleVertices.data(), de::dataSize(triangleVertices));
	flushAlloc(vkd, device, vertexBufferAlloc);

	// Index buffer if needed.
	de::MovePtr<BufferWithMemory>	indexBuffer;
	VkDeviceSize					indexBufferOffset = 0ull;

	if (isIndexed)
	{
		// Indices will be given in reverse order, so they effectively also make the triangles have reverse winding order.
		std::vector<deUint32> indices;
		indices.reserve(vertexCount);
		for (deUint32 i = 0u; i < vertexCount; ++i)
			indices.push_back(vertexCount - i - 1u);

		const auto	indexBufferSize		= static_cast<VkDeviceSize>(de::dataSize(indices));
		const auto	indexBufferInfo		= makeBufferCreateInfo(indexBufferSize, VK_BUFFER_USAGE_INDEX_BUFFER_BIT);
					indexBuffer			= de::MovePtr<BufferWithMemory>(new BufferWithMemory(vkd, device, alloc, indexBufferInfo, MemoryRequirement::HostVisible));
		auto&		indexBufferAlloc	= indexBuffer->getAllocation();
					indexBufferOffset	= indexBufferAlloc.getOffset();
		void*		indexBufferData		= indexBufferAlloc.getHostPtr();

		deMemcpy(indexBufferData, indices.data(), de::dataSize(indices));
		flushAlloc(vkd, device, indexBufferAlloc);
	}

	// Prepare draw information.
	const auto offsetType	= (m_params.vertexOffset ? tcu::just(m_params.vertexOffset->offsetType) : tcu::Nothing);
	const auto vertexOffset	= static_cast<deInt32>(extraVertices);

	DrawInfoPacker drawInfos(m_params.drawType, offsetType, m_params.stride, m_params.drawCount, m_params.seed);

	if (m_params.drawCount > 0u)
	{
		deUint32 vertexIndex = 0u;
		for (deUint32 drawIdx = 0u; drawIdx < m_params.drawCount; ++drawIdx)
		{
			// For indexed draws in mixed offset mode, taking into account vertex indices have been stored in reversed order and
			// there may be a padding in the vertex buffer after the first verticesPerDraw vertices, we need to use offset 0 in the
			// last draw call. That draw will contain the indices for the first verticesPerDraw vertices, which are stored without
			// any offset, while other draw calls will use indices which are off by extraVertices vertices. This will make sure not
			// every draw call will use the same offset and the implementation handles that.
			const auto drawOffset = ((isIndexed && (!isMixedMode || (moreThanOneDraw && drawIdx < m_params.drawCount - 1u))) ? vertexOffset : 0);
			drawInfos.addDrawInfo(vertexIndex, verticesPerDraw, drawOffset);
			vertexIndex += verticesPerDraw;
		}
	}

	beginCommandBuffer(vkd, cmdBuffer);

	// Draw stuff.
	std::vector<VkClearValue> clearValues;
	clearValues.reserve(2u);
	clearValues.push_back(makeClearValueColorU32(0u, 0u, 0u, 0u));
	clearValues.push_back(makeClearValueDepthStencil(((isMosaic || isIndexed) ? 0.0f : 1.0f), 0u));

	beginRenderPass(vkd, cmdBuffer, renderPass.get(), framebuffer.get(), scissor, static_cast<deUint32>(clearValues.size()), de::dataOrNull(clearValues));

	for (deUint32 layerIdx = 0u; layerIdx < imageLayers; ++layerIdx)
	{
		if (layerIdx > 0u)
			vkd.cmdNextSubpass(cmdBuffer, VK_SUBPASS_CONTENTS_INLINE);

		vkd.cmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelines[layerIdx].get());
		vkd.cmdBindVertexBuffers(cmdBuffer, 0u, 1u, &vertexBuffer.get(), &vertexBufferOffset);
		if (isIndexed)
			vkd.cmdBindIndexBuffer(cmdBuffer, indexBuffer->get(), indexBufferOffset, VK_INDEX_TYPE_UINT32);

		if (isIndexed)
		{
			const auto drawInfoPtr	= reinterpret_cast<const VkMultiDrawIndexedInfoEXT*>(drawInfos.drawInfoData());
			const auto offsetPtr	= (isMixedMode ? nullptr : &vertexOffset);
			vkd.cmdDrawMultiIndexedEXT(cmdBuffer, drawInfos.drawInfoCount(), drawInfoPtr, m_params.instanceCount, m_params.firstInstance, drawInfos.stride(), offsetPtr);
		}
		else
		{
			const auto drawInfoPtr = reinterpret_cast<const VkMultiDrawInfoEXT*>(drawInfos.drawInfoData());
			vkd.cmdDrawMultiEXT(cmdBuffer, drawInfos.drawInfoCount(), drawInfoPtr, m_params.instanceCount, m_params.firstInstance, drawInfos.stride());
		}
	}

	endRenderPass(vkd, cmdBuffer);

	// Prepare images for copying.
	const auto colorBufferBarrier = makeImageMemoryBarrier(
		VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
		VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
		colorBuffer.get(), colorSubresourceRange);
	vkd.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, nullptr, 0u, nullptr, 1u, &colorBufferBarrier);

	const auto dsBufferBarrier = makeImageMemoryBarrier(
		VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
		VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
		dsBuffer.get(), dsSubresourceRange);
	vkd.cmdPipelineBarrier(cmdBuffer, (VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT), VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, nullptr, 0u, nullptr, 1u, &dsBufferBarrier);

	// Copy images to output buffers.
	for (deUint32 layerIdx = 0u; layerIdx < imageLayers; ++layerIdx)
	{
		const auto colorSubresourceLayers	= makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, layerIdx, 1u);
		const auto colorCopyRegion			= makeBufferImageCopy(imageExtent, colorSubresourceLayers);
		vkd.cmdCopyImageToBuffer(cmdBuffer, colorBuffer.get(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, outputBuffers[layerIdx]->get(), 1u, &colorCopyRegion);
	}

	// Note: this only copies the stencil aspect. See stencilOutBuffer creation.
	for (deUint32 layerIdx = 0u; layerIdx < imageLayers; ++layerIdx)
	{
		const auto stencilSubresourceLayers	= makeImageSubresourceLayers(VK_IMAGE_ASPECT_STENCIL_BIT, 0u, layerIdx, 1u);
		const auto stencilCopyRegion		= makeBufferImageCopy(imageExtent, stencilSubresourceLayers);
		vkd.cmdCopyImageToBuffer(cmdBuffer, dsBuffer.get(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, stencilOutBuffers[layerIdx]->get(), 1u, &stencilCopyRegion);
	}

	// Prepare buffers for host reading.
	const auto outputBufferBarrier		= makeMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT);
	vkd.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 1u, &outputBufferBarrier, 0u, nullptr, 0u, nullptr);

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

	// Read output buffers and verify their contents.

	// With stride zero, mosaic meshes increment the stencil buffer as many times as draw operations for affected pixels and
	// overlapping meshes increment the stencil buffer only in the first draw operation (the rest fail the depth test) as many times
	// as triangles per draw.
	//
	// With nonzero stride, mosaic meshes increment the stencil buffer once per pixel. Overlapping meshes increment it once per
	// triangle.
	const auto	stencilIncrements		=	((m_params.stride == 0u)
											? (isMosaic ? drawInfos.drawInfoCount() : trianglesPerDraw)
											: (isMosaic ? 1u : triangleCount));
	const auto	maxInstanceIndex		= m_params.maxInstanceIndex();
	const auto	colorVerificationFormat	= mapVkFormat(getVerificationFormat());
	const auto	iWidth					= static_cast<int>(imageExtent.width);
	const auto	iHeight					= static_cast<int>(imageExtent.height);
	auto&		log						= m_context.getTestContext().getLog();
	const auto	logMode					= tcu::CompareLogMode::COMPARE_LOG_ON_ERROR;

	for (deUint32 layerIdx = 0u; layerIdx < imageLayers; ++layerIdx)
	{
		auto& outputBufferAlloc = outputBuffers[layerIdx]->getAllocation();
		invalidateAlloc(vkd, device, outputBufferAlloc);
		const void* outputBufferData = outputBufferAlloc.getHostPtr();

		auto& stencilOutBufferAlloc = stencilOutBuffers[layerIdx]->getAllocation();
		invalidateAlloc(vkd, device, stencilOutBufferAlloc);
		const void* stencilOutBufferData = stencilOutBufferAlloc.getHostPtr();

		tcu::ConstPixelBufferAccess	colorAccess				(colorVerificationFormat, iWidth, iHeight, 1, outputBufferData);
		tcu::ConstPixelBufferAccess	stencilAccess			(tcuStencilFmt, iWidth, iHeight, 1, stencilOutBufferData);

		// Generate reference images.
		tcu::TextureLevel			refColorLevel		(colorVerificationFormat, iWidth, iHeight);
		tcu::PixelBufferAccess		refColorAccess		= refColorLevel.getAccess();
		tcu::TextureLevel			refStencilLevel		(tcuStencilFmt, iWidth, iHeight);
		tcu::PixelBufferAccess		refStencilAccess	= refStencilLevel.getAccess();
		tcu::IVec4					referenceColor;
		int							referenceStencil;

		for (int y = 0; y < iHeight; ++y)
		for (int x = 0; x < iWidth; ++x)
		{
			const auto pixelNumber		= static_cast<deUint32>(y * iWidth + x);
			const auto triangleIndex	= (isIndexed ? (pixelCount - 1u - pixelNumber) : pixelNumber); // Reverse order for indexed draws.

			if (m_params.instanceCount == 0u || drawInfos.drawInfoCount() == 0u ||
				(m_params.stride == 0u && triangleIndex >= trianglesPerDraw && isMosaic))
			{
				// Some pixels may not be drawn into when there are no instances or draws, or when the stride is zero in mosaic mode.
				referenceColor		= tcu::IVec4(0, 0, 0, 0);
				referenceStencil	= 0;
			}
			else
			{
				// This must match the vertex shader.
				//
				// With stride zero, the same block is drawn over and over again in each draw call. This affects both the draw index and
				// the values in the depth/stencil buffer and, with overlapping meshes, only the first draw passes the depth test.
				//
				// With nonzero stride, the draw index depends on the triangle index and the number of triangles per draw and, for
				// overlapping meshes, the draw index is always the last one.
				const auto drawIndex =	(m_params.stride == 0u
										? (isMosaic ? (drawInfos.drawInfoCount() - 1u) : 0u)
										: (isMosaic ? (triangleIndex / trianglesPerDraw) : (drawInfos.drawInfoCount() - 1u)));
				referenceColor = tcu::IVec4(
					static_cast<int>((drawIndex >> 8) & 0xFFu),
					static_cast<int>((drawIndex     ) & 0xFFu),
					static_cast<int>(255u - maxInstanceIndex),
					static_cast<int>(255u - layerIdx));

				referenceStencil = static_cast<int>((m_params.instanceCount * stencilIncrements) % 256u); // VK_STENCIL_OP_INCREMENT_AND_WRAP.
			}

			refColorAccess.setPixel(referenceColor, x, y);
			refStencilAccess.setPixStencil(referenceStencil, x, y);
		}

		const auto layerIdxStr		= de::toString(layerIdx);
		const auto colorSetName		= "ColorTestResultLayer" + layerIdxStr;
		const auto stencilSetName	= "StencilTestResultLayer" + layerIdxStr;

		if (!tcu::intThresholdCompare(log, colorSetName.c_str(), "", refColorAccess, colorAccess, tcu::UVec4(0u, 0u, 0u, 0u), logMode))
			return tcu::TestStatus::fail("Color image comparison failed; check log for more details");

		if (!tcu::dsThresholdCompare(log, stencilSetName.c_str(), "", refStencilAccess, stencilAccess, 0.0f, logMode))
			return tcu::TestStatus::fail("Stencil image comparison failed; check log for more details");
	}

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

} // anonymous

tcu::TestCaseGroup*	createDrawMultiExtTests (tcu::TestContext& testCtx)
{
	using GroupPtr = de::MovePtr<tcu::TestCaseGroup>;

	GroupPtr drawMultiGroup (new tcu::TestCaseGroup(testCtx, "multi_draw", "VK_EXT_multi_draw tests"));

	const struct
	{
		MeshType	meshType;
		const char*	name;
	} meshTypeCases[] =
	{
		{ MeshType::MOSAIC,			"mosaic"		},
		{ MeshType::OVERLAPPING,	"overlapping"	},
	};

	const struct
	{
		DrawType	drawType;
		const char*	name;
	} drawTypeCases[] =
	{
		{ DrawType::NORMAL,		"normal"	},
		{ DrawType::INDEXED,	"indexed"	},
	};

	const struct
	{
		tcu::Maybe<VertexOffsetType>	vertexOffsetType;
		const char*						name;
	} offsetTypeCases[] =
	{
		{ tcu::Nothing,							""			},
		{ VertexOffsetType::MIXED,				"mixed"		},
		{ VertexOffsetType::CONSTANT_RANDOM,	"random"	},
		{ VertexOffsetType::CONSTANT_PACK,		"packed"	},
	};

	const struct
	{
		deUint32	drawCount;
		const char*	name;
	} drawCountCases[] =
	{
		{ 0u,					"no_draws"	},
		{ 1u,					"one_draw"	},
		{ 16u,					"16_draws"	},
		{ getTriangleCount(),	"max_draws"	},
	};

	const struct
	{
		int			extraBytes;
		const char*	name;
	} strideCases[] =
	{
		{ -1,		"stride_zero"		},
		{  0,		"standard_stride"	},
		{  4,		"stride_extra_4"	},
		{ 12,		"stride_extra_12"	},
	};

	const struct
	{
		deUint32	firstInstance;
		deUint32	instanceCount;
		const char*	name;
	} instanceCases[] =
	{
		{	0u,		0u,		"no_instances"			},
		{	0u,		1u,		"1_instance"			},
		{	0u,		10u,	"10_instances"			},
		{	3u,		2u,		"2_instances_base_3"	},
	};

	const struct
	{
		bool		useTessellation;
		bool		useGeometry;
		const char*	name;
	} shaderCases[] =
	{
		{ false,	false,		"vert_only"	},
		{ false,	true,		"with_geom"	},
		{ true,		false,		"with_tess"	},
		{ true,		true,		"tess_geom"	},
	};

	const struct
	{
		bool		multiview;
		const char*	name;
	} multiviewCases[] =
	{
		{ false,	"single_view"	},
		{ true,		"multiview"		},
	};

	constexpr deUint32 kSeed = 1621260419u;

	for (const auto& meshTypeCase : meshTypeCases)
	{
		GroupPtr meshTypeGroup(new tcu::TestCaseGroup(testCtx, meshTypeCase.name, ""));

		for (const auto& drawTypeCase : drawTypeCases)
		{
			for (const auto& offsetTypeCase : offsetTypeCases)
			{
				const auto hasOffsetType = static_cast<bool>(offsetTypeCase.vertexOffsetType);
				if ((drawTypeCase.drawType == DrawType::NORMAL && hasOffsetType) ||
					(drawTypeCase.drawType == DrawType::INDEXED && !hasOffsetType))
				{
					continue;
				}

				std::string drawGroupName = drawTypeCase.name;
				if (hasOffsetType)
					drawGroupName += std::string("_") + offsetTypeCase.name;

				GroupPtr drawTypeGroup(new tcu::TestCaseGroup(testCtx, drawGroupName.c_str(), ""));

				for (const auto& drawCountCase : drawCountCases)
				{
					GroupPtr drawCountGroup(new tcu::TestCaseGroup(testCtx, drawCountCase.name, ""));

					for (const auto& strideCase : strideCases)
					{
						GroupPtr strideGroup(new tcu::TestCaseGroup(testCtx, strideCase.name, ""));

						for (const auto& instanceCase : instanceCases)
						{
							GroupPtr instanceGroup(new tcu::TestCaseGroup(testCtx, instanceCase.name, ""));

							for (const auto& shaderCase : shaderCases)
							{
								GroupPtr shaderGroup(new tcu::TestCaseGroup(testCtx, shaderCase.name, ""));

								for (const auto& multiviewCase : multiviewCases)
								{
									GroupPtr multiviewGroup(new tcu::TestCaseGroup(testCtx, multiviewCase.name, ""));

									const auto	isIndexed	= (drawTypeCase.drawType == DrawType::INDEXED);
									const auto	isPacked	= (offsetTypeCase.vertexOffsetType && *offsetTypeCase.vertexOffsetType == VertexOffsetType::CONSTANT_PACK);
									const auto	baseStride	= ((isIndexed && !isPacked) ? sizeof(VkMultiDrawIndexedInfoEXT) : sizeof(VkMultiDrawInfoEXT));
									const auto&	extraBytes	= strideCase.extraBytes;
									const auto	testOffset	= (isIndexed ? tcu::just(VertexOffsetParams{*offsetTypeCase.vertexOffsetType, 0u }) : tcu::Nothing);
									deUint32	testStride	= 0u;

									if (extraBytes >= 0)
										testStride = static_cast<deUint32>(baseStride) + static_cast<deUint32>(extraBytes);

									// For overlapping triangles we will skip instanced drawing.
									if (instanceCase.instanceCount > 1u && meshTypeCase.meshType == MeshType::OVERLAPPING)
										continue;

									TestParams params =
									{
										meshTypeCase.meshType,			//	MeshType						meshType;
										drawTypeCase.drawType,			//	DrawType						drawType;
										drawCountCase.drawCount,		//	deUint32						drawCount;
										instanceCase.instanceCount,		//	deUint32						instanceCount;
										instanceCase.firstInstance,		//	deUint32						firstInstance;
										testStride,						//	deUint32						stride;
										testOffset,						//	tcu::Maybe<VertexOffsetParams>>	vertexOffset;	// Only used for indexed draws.
										kSeed,							//	deUint32						seed;
										shaderCase.useTessellation,		//	bool							useTessellation;
										shaderCase.useGeometry,			//	bool							useGeometry;
										multiviewCase.multiview,		//	bool							multiview;
									};

									multiviewGroup->addChild(new MultiDrawTest(testCtx, "no_offset", "", params));

									if (isIndexed)
									{
										params.vertexOffset->offset = 6u;
										multiviewGroup->addChild(new MultiDrawTest(testCtx, "offset_6", "", params));
									}

									shaderGroup->addChild(multiviewGroup.release());
								}

								instanceGroup->addChild(shaderGroup.release());
							}

							strideGroup->addChild(instanceGroup.release());
						}

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

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

				meshTypeGroup->addChild(drawTypeGroup.release());
			}
		}

		drawMultiGroup->addChild(meshTypeGroup.release());
	}

	return drawMultiGroup.release();
}

} // Draw
} // vkt
