/*------------------------------------------------------------------------
 * Vulkan Conformance Tests
 * ------------------------
 *
 * Copyright (c) 2015 The Khronos Group Inc.
 * Copyright (c) 2015 Imagination Technologies Ltd.
 *
 * 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 Stencil Tests
 *//*--------------------------------------------------------------------*/

#include "vktPipelineStencilTests.hpp"
#include "vktPipelineClearUtil.hpp"
#include "vktPipelineImageUtil.hpp"
#include "vktPipelineVertexUtil.hpp"
#include "vktPipelineReferenceRenderer.hpp"
#include "vktPipelineUniqueRandomIterator.hpp"
#include "vktTestCase.hpp"
#include "vkImageUtil.hpp"
#include "vkMemUtil.hpp"
#include "vkPrograms.hpp"
#include "vkQueryUtil.hpp"
#include "vkRef.hpp"
#include "vkRefUtil.hpp"
#include "vkTypeUtil.hpp"
#include "vkCmdUtil.hpp"
#include "vkObjUtil.hpp"
#include "tcuImageCompare.hpp"
#include "deMemory.h"
#include "deRandom.hpp"
#include "deStringUtil.hpp"
#include "deUniquePtr.hpp"

#include <algorithm>
#include <sstream>
#include <vector>

namespace vkt
{
namespace pipeline
{

using namespace vk;

namespace
{

bool isSupportedDepthStencilFormat (const InstanceInterface& instanceInterface, VkPhysicalDevice device, VkFormat format)
{
	VkFormatProperties formatProps;

	instanceInterface.getPhysicalDeviceFormatProperties(device, format, &formatProps);

	return (formatProps.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) != 0;
}

class StencilOpStateUniqueRandomIterator : public UniqueRandomIterator<VkStencilOpState>
{
public:
								StencilOpStateUniqueRandomIterator	(int seed);
	virtual						~StencilOpStateUniqueRandomIterator	(void) {}
	virtual VkStencilOpState	getIndexedValue						(deUint32 index);

private:

	// Pre-calculated constants
	const static deUint32		s_stencilOpsLength;
	const static deUint32		s_stencilOpsLength2;
	const static deUint32		s_stencilOpsLength3;
	const static deUint32		s_compareOpsLength;

	// Total number of cross-combinations of (stencilFailOp x stencilPassOp x stencilDepthFailOp x stencilCompareOp)
	const static deUint32		s_totalStencilOpStates;
};


class StencilTest : public vkt::TestCase
{
public:
	enum
	{
		QUAD_COUNT = 4
	};

	struct StencilStateConfig
	{
		deUint32	frontReadMask;
		deUint32	frontWriteMask;
		deUint32	frontRef;

		deUint32	backReadMask;
		deUint32	backWriteMask;
		deUint32	backRef;
	};

	const static StencilStateConfig			s_stencilStateConfigs[QUAD_COUNT];
	const static float						s_quadDepths[QUAD_COUNT];


											StencilTest				(tcu::TestContext&			testContext,
																	 const std::string&			name,
																	 const std::string&			description,
																	 VkFormat					stencilFormat,
																	 const VkStencilOpState&	stencilOpStateFront,
																	 const VkStencilOpState&	stencilOpStateBack,
																	 const bool					colorAttachmentEnable);
	virtual									~StencilTest			(void);
	virtual void							initPrograms			(SourceCollections& sourceCollections) const;
	virtual void							checkSupport			(Context& context) const;
	virtual TestInstance*					createInstance			(Context& context) const;

private:
	VkFormat								m_stencilFormat;
	const VkStencilOpState					m_stencilOpStateFront;
	const VkStencilOpState					m_stencilOpStateBack;
	const bool								m_colorAttachmentEnable;
};

class StencilTestInstance : public vkt::TestInstance
{
public:
										StencilTestInstance		(Context&					context,
																 VkFormat					stencilFormat,
																 const VkStencilOpState&	stencilOpStatesFront,
																 const VkStencilOpState&	stencilOpStatesBack,
																 const bool					colorAttachmentEnable);
	virtual								~StencilTestInstance	(void);
	virtual tcu::TestStatus				iterate					(void);

private:
	tcu::TestStatus						verifyImage				(void);

	VkStencilOpState					m_stencilOpStateFront;
	VkStencilOpState					m_stencilOpStateBack;
	const bool							m_colorAttachmentEnable;
	const tcu::UVec2					m_renderSize;
	const VkFormat						m_colorFormat;
	const VkFormat						m_stencilFormat;
	VkImageSubresourceRange				m_stencilImageSubresourceRange;

	VkImageCreateInfo					m_colorImageCreateInfo;
	Move<VkImage>						m_colorImage;
	de::MovePtr<Allocation>				m_colorImageAlloc;
	Move<VkImage>						m_stencilImage;
	de::MovePtr<Allocation>				m_stencilImageAlloc;
	Move<VkImageView>					m_colorAttachmentView;
	Move<VkImageView>					m_stencilAttachmentView;
	Move<VkRenderPass>					m_renderPass;
	Move<VkFramebuffer>					m_framebuffer;

	Move<VkShaderModule>				m_vertexShaderModule;
	Move<VkShaderModule>				m_fragmentShaderModule;

	Move<VkBuffer>						m_vertexBuffer;
	std::vector<Vertex4RGBA>			m_vertices;
	de::MovePtr<Allocation>				m_vertexBufferAlloc;

	Move<VkPipelineLayout>				m_pipelineLayout;
	Move<VkPipeline>					m_graphicsPipelines[StencilTest::QUAD_COUNT];

	Move<VkCommandPool>					m_cmdPool;
	Move<VkCommandBuffer>				m_cmdBuffer;
};

const VkStencilOp stencilOps[] =
{
	VK_STENCIL_OP_KEEP,
	VK_STENCIL_OP_ZERO,
	VK_STENCIL_OP_REPLACE,
	VK_STENCIL_OP_INCREMENT_AND_CLAMP,
	VK_STENCIL_OP_DECREMENT_AND_CLAMP,
	VK_STENCIL_OP_INVERT,
	VK_STENCIL_OP_INCREMENT_AND_WRAP,
	VK_STENCIL_OP_DECREMENT_AND_WRAP
};

const VkCompareOp compareOps[] =
{
	VK_COMPARE_OP_NEVER,
	VK_COMPARE_OP_LESS,
	VK_COMPARE_OP_EQUAL,
	VK_COMPARE_OP_LESS_OR_EQUAL,
	VK_COMPARE_OP_GREATER,
	VK_COMPARE_OP_NOT_EQUAL,
	VK_COMPARE_OP_GREATER_OR_EQUAL,
	VK_COMPARE_OP_ALWAYS
};

// StencilOpStateUniqueRandomIterator

const deUint32 StencilOpStateUniqueRandomIterator::s_stencilOpsLength		= DE_LENGTH_OF_ARRAY(stencilOps);
const deUint32 StencilOpStateUniqueRandomIterator::s_stencilOpsLength2		= s_stencilOpsLength * s_stencilOpsLength;
const deUint32 StencilOpStateUniqueRandomIterator::s_stencilOpsLength3		= s_stencilOpsLength2 * s_stencilOpsLength;
const deUint32 StencilOpStateUniqueRandomIterator::s_compareOpsLength		= DE_LENGTH_OF_ARRAY(compareOps);
const deUint32 StencilOpStateUniqueRandomIterator::s_totalStencilOpStates	= s_stencilOpsLength3 * s_compareOpsLength;

StencilOpStateUniqueRandomIterator::StencilOpStateUniqueRandomIterator (int seed)
	: UniqueRandomIterator<VkStencilOpState>(s_totalStencilOpStates, s_totalStencilOpStates, seed)
{
}

VkStencilOpState StencilOpStateUniqueRandomIterator::getIndexedValue (deUint32 index)
{
	const deUint32 stencilCompareOpIndex = index / s_stencilOpsLength3;
	const deUint32 stencilCompareOpSeqIndex = stencilCompareOpIndex * s_stencilOpsLength3;

	const deUint32 stencilDepthFailOpIndex = (index - stencilCompareOpSeqIndex) / s_stencilOpsLength2;
	const deUint32 stencilDepthFailOpSeqIndex = stencilDepthFailOpIndex * s_stencilOpsLength2;

	const deUint32 stencilPassOpIndex = (index - stencilCompareOpSeqIndex - stencilDepthFailOpSeqIndex) / s_stencilOpsLength;
	const deUint32 stencilPassOpSeqIndex = stencilPassOpIndex * s_stencilOpsLength;

	const deUint32 stencilFailOpIndex = index - stencilCompareOpSeqIndex - stencilDepthFailOpSeqIndex - stencilPassOpSeqIndex;

	const VkStencilOpState stencilOpState =
	{
		stencilOps[stencilFailOpIndex],			// VkStencilOp	failOp;
		stencilOps[stencilPassOpIndex],			// VkStencilOp	passOp;
		stencilOps[stencilDepthFailOpIndex],	// VkStencilOp	depthFailOp;
		compareOps[stencilCompareOpIndex],		// VkCompareOp	compareOp;
		0x0,									// deUint32		compareMask;
		0x0,									// deUint32		writeMask;
		0x0										// deUint32		reference;
	};

	return stencilOpState;
}


// StencilTest

const StencilTest::StencilStateConfig StencilTest::s_stencilStateConfigs[QUAD_COUNT] =
{
	//	frontReadMask	frontWriteMask		frontRef		backReadMask	backWriteMask	backRef
	{	0xFF,			0xFF,				0xAB,			0xF0,			0xFF,			0xFF	},
	{	0xFF,			0xF0,				0xCD,			0xF0,			0xF0,			0xEF	},
	{	0xF0,			0x0F,				0xEF,			0xFF,			0x0F,			0xCD	},
	{	0xF0,			0x01,				0xFF,			0xFF,			0x01,			0xAB	}
};

const float StencilTest::s_quadDepths[QUAD_COUNT] =
{
	0.1f,
	0.0f,
	0.3f,
	0.2f
};

StencilTest::StencilTest (tcu::TestContext&			testContext,
						  const std::string&		name,
						  const std::string&		description,
						  VkFormat					stencilFormat,
						  const VkStencilOpState&	stencilOpStateFront,
						  const VkStencilOpState&	stencilOpStateBack,
						  const bool				colorAttachmentEnable)
	: vkt::TestCase				(testContext, name, description)
	, m_stencilFormat			(stencilFormat)
	, m_stencilOpStateFront		(stencilOpStateFront)
	, m_stencilOpStateBack		(stencilOpStateBack)
	, m_colorAttachmentEnable	(colorAttachmentEnable)
{
}

StencilTest::~StencilTest (void)
{
}

void StencilTest::checkSupport (Context& context) const
{
	if (!isSupportedDepthStencilFormat(context.getInstanceInterface(), context.getPhysicalDevice(), m_stencilFormat))
		throw tcu::NotSupportedError(std::string("Unsupported depth/stencil format: ") + getFormatName(m_stencilFormat));
}

TestInstance* StencilTest::createInstance (Context& context) const
{
	return new StencilTestInstance(context, m_stencilFormat, m_stencilOpStateFront, m_stencilOpStateBack, m_colorAttachmentEnable);
}

void StencilTest::initPrograms (SourceCollections& sourceCollections) const
{
	if (m_colorAttachmentEnable)
	{
		sourceCollections.glslSources.add("color_vert") << glu::VertexSource(
			"#version 310 es\n"
			"layout(location = 0) in vec4 position;\n"
			"layout(location = 1) in vec4 color;\n"
			"layout(location = 0) out highp vec4 vtxColor;\n"
			"void main (void)\n"
			"{\n"
			"	gl_Position = position;\n"
			"	vtxColor = color;\n"
			"}\n");

		sourceCollections.glslSources.add("color_frag") << glu::FragmentSource(
			"#version 310 es\n"
			"layout(location = 0) in highp vec4 vtxColor;\n"
			"layout(location = 0) out highp vec4 fragColor;\n"
			"void main (void)\n"
			"{\n"
			"	fragColor = vtxColor;\n"
			"}\n");
	}
	else
	{
		sourceCollections.glslSources.add("color_vert") << glu::VertexSource(
			"#version 310 es\n"
			"layout(location = 0) in vec4 position;\n"
			"layout(location = 1) in vec4 color;\n"
			"void main (void)\n"
			"{\n"
			"	gl_Position = position;\n"
			"}\n");

		sourceCollections.glslSources.add("color_frag") << glu::FragmentSource(
			"#version 310 es\n"
			"void main (void)\n"
			"{\n"
			"}\n");
	}
}


// StencilTestInstance

StencilTestInstance::StencilTestInstance (Context&					context,
										  VkFormat					stencilFormat,
										  const VkStencilOpState&	stencilOpStateFront,
										  const VkStencilOpState&	stencilOpStateBack,
										  const bool				colorAttachmentEnable)
	: vkt::TestInstance			(context)
	, m_stencilOpStateFront		(stencilOpStateFront)
	, m_stencilOpStateBack		(stencilOpStateBack)
	, m_colorAttachmentEnable	(colorAttachmentEnable)
	, m_renderSize				(32, 32)
	, m_colorFormat				(colorAttachmentEnable ? VK_FORMAT_R8G8B8A8_UNORM : VK_FORMAT_UNDEFINED)
	, m_stencilFormat			(stencilFormat)
{
	const DeviceInterface&		vk						= context.getDeviceInterface();
	const VkDevice				vkDevice				= context.getDevice();
	const deUint32				queueFamilyIndex		= context.getUniversalQueueFamilyIndex();
	SimpleAllocator				memAlloc				(vk, vkDevice, getPhysicalDeviceMemoryProperties(context.getInstanceInterface(), context.getPhysicalDevice()));
	const VkComponentMapping	componentMappingRGBA	= { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A };

	// Create color image
	if (m_colorAttachmentEnable)
	{
		const VkImageCreateInfo colorImageParams =
		{
			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,										// VkStructureType			sType;
			DE_NULL,																	// const void*				pNext;
			0u,																			// VkImageCreateFlags		flags;
			VK_IMAGE_TYPE_2D,															// VkImageType				imageType;
			m_colorFormat,																// VkFormat					format;
			{ m_renderSize.x(), m_renderSize.y(), 1u },									// VkExtent3D				extent;
			1u,																			// deUint32					mipLevels;
			1u,																			// deUint32					arrayLayers;
			VK_SAMPLE_COUNT_1_BIT,														// VkSampleCountFlagBits	samples;
			VK_IMAGE_TILING_OPTIMAL,													// VkImageTiling			tiling;
			VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT,		// VkImageUsageFlags		usage;
			VK_SHARING_MODE_EXCLUSIVE,													// VkSharingMode			sharingMode;
			1u,																			// deUint32					queueFamilyIndexCount;
			&queueFamilyIndex,															// const deUint32*			pQueueFamilyIndices;
			VK_IMAGE_LAYOUT_UNDEFINED													// VkImageLayout			initialLayout;
		};

		m_colorImageCreateInfo	= colorImageParams;
		m_colorImage			= createImage(vk, vkDevice, &m_colorImageCreateInfo);

		// Allocate and bind color image memory
		m_colorImageAlloc		= memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_colorImage), MemoryRequirement::Any);
		VK_CHECK(vk.bindImageMemory(vkDevice, *m_colorImage, m_colorImageAlloc->getMemory(), m_colorImageAlloc->getOffset()));
	}

	// Create stencil image
	{
		const VkImageUsageFlags	usageFlags			= VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;

		const VkImageCreateInfo	stencilImageParams	=
		{
			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,			// VkStructureType			sType;
			DE_NULL,										// const void*				pNext;
			0u,												// VkImageCreateFlags		flags;
			VK_IMAGE_TYPE_2D,								// VkImageType				imageType;
			m_stencilFormat,								// VkFormat					format;
			{ m_renderSize.x(), m_renderSize.y(), 1u },		// VkExtent3D				extent;
			1u,												// deUint32					mipLevels;
			1u,												// deUint32					arrayLayers;
			VK_SAMPLE_COUNT_1_BIT,							// VkSampleCountFlagBits	samples;
			VK_IMAGE_TILING_OPTIMAL,						// VkImageTiling			tiling;
			usageFlags,										// VkImageUsageFlags		usage;
			VK_SHARING_MODE_EXCLUSIVE,						// VkSharingMode			sharingMode;
			1u,												// deUint32					queueFamilyIndexCount;
			&queueFamilyIndex,								// const deUint32*			pQueueFamilyIndices;
			VK_IMAGE_LAYOUT_UNDEFINED						// VkImageLayout			initialLayout;
		};

		m_stencilImage = createImage(vk, vkDevice, &stencilImageParams);

		// Allocate and bind stencil image memory
		m_stencilImageAlloc = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_stencilImage), MemoryRequirement::Any);
		VK_CHECK(vk.bindImageMemory(vkDevice, *m_stencilImage, m_stencilImageAlloc->getMemory(), m_stencilImageAlloc->getOffset()));

		const VkImageAspectFlags aspect = (mapVkFormat(m_stencilFormat).order == tcu::TextureFormat::DS ? VK_IMAGE_ASPECT_STENCIL_BIT | VK_IMAGE_ASPECT_DEPTH_BIT
																										: VK_IMAGE_ASPECT_STENCIL_BIT);
		m_stencilImageSubresourceRange  = makeImageSubresourceRange(aspect, 0u, stencilImageParams.mipLevels, 0u, stencilImageParams.arrayLayers);
	}

	// Create color attachment view
	if (m_colorAttachmentEnable)
	{
		const VkImageViewCreateInfo colorAttachmentViewParams =
		{
			VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,			// VkStructureType			sType;
			DE_NULL,											// const void*				pNext;
			0u,													// VkImageViewCreateFlags	flags;
			*m_colorImage,										// VkImage					image;
			VK_IMAGE_VIEW_TYPE_2D,								// VkImageViewType			viewType;
			m_colorFormat,										// VkFormat					format;
			componentMappingRGBA,								// VkComponentMapping		components;
			{ VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u }		// VkImageSubresourceRange	subresourceRange;
		};

		m_colorAttachmentView = createImageView(vk, vkDevice, &colorAttachmentViewParams);
	}

	// Create stencil attachment view
	{
		const VkImageViewCreateInfo stencilAttachmentViewParams =
		{
			VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,			// VkStructureType			sType;
			DE_NULL,											// const void*				pNext;
			0u,													// VkImageViewCreateFlags	flags;
			*m_stencilImage,									// VkImage					image;
			VK_IMAGE_VIEW_TYPE_2D,								// VkImageViewType			viewType;
			m_stencilFormat,									// VkFormat					format;
			componentMappingRGBA,								// VkComponentMapping		components;
			m_stencilImageSubresourceRange,						// VkImageSubresourceRange	subresourceRange;
		};

		m_stencilAttachmentView = createImageView(vk, vkDevice, &stencilAttachmentViewParams);
	}

	// Create render pass
	m_renderPass = makeRenderPass(vk, vkDevice, m_colorFormat, m_stencilFormat);

	// Create framebuffer
	{
		std::vector<VkImageView>		attachmentBindInfos;

		if (m_colorAttachmentEnable)
			attachmentBindInfos.push_back(*m_colorAttachmentView);

		attachmentBindInfos.push_back(*m_stencilAttachmentView);

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

		m_framebuffer = createFramebuffer(vk, vkDevice, &framebufferParams);
	}

	// Create pipeline layout
	{
		const VkPipelineLayoutCreateInfo pipelineLayoutParams =
		{
			VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,		// VkStructureType				sType;
			DE_NULL,											// const void*					pNext;
			0u,													// VkPipelineLayoutCreateFlags	flags;
			0u,													// deUint32						setLayoutCount;
			DE_NULL,											// const VkDescriptorSetLayout*	pSetLayouts;
			0u,													// deUint32						pushConstantRangeCount;
			DE_NULL												// const VkPushConstantRange*	pPushConstantRanges;
		};

		m_pipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams);
	}

	m_vertexShaderModule	= createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("color_vert"), 0);
	m_fragmentShaderModule	= createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("color_frag"), 0);

	// Create pipeline
	{
		const VkVertexInputBindingDescription vertexInputBindingDescription =
		{
			0u,										// deUint32					binding;
			sizeof(Vertex4RGBA),					// deUint32					strideInBytes;
			VK_VERTEX_INPUT_RATE_VERTEX				// VkVertexInputStepRate	inputRate;
		};

		const VkVertexInputAttributeDescription vertexInputAttributeDescriptions[2] =
		{
			{
				0u,									// deUint32	location;
				0u,									// deUint32	binding;
				VK_FORMAT_R32G32B32A32_SFLOAT,		// VkFormat	format;
				0u									// deUint32	offsetInBytes;
			},
			{
				1u,									// deUint32	location;
				0u,									// deUint32	binding;
				VK_FORMAT_R32G32B32A32_SFLOAT,		// VkFormat	format;
				DE_OFFSET_OF(Vertex4RGBA, color),	// deUint32	offsetInBytes;
			}
		};

		const VkPipelineVertexInputStateCreateInfo vertexInputStateParams =
		{
			VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,		// VkStructureType							sType;
			DE_NULL,														// const void*								pNext;
			0u,																// VkPipelineVertexInputStateCreateFlags	flags;
			1u,																// deUint32									vertexBindingDescriptionCount;
			&vertexInputBindingDescription,									// const VkVertexInputBindingDescription*	pVertexBindingDescriptions;
			2u,																// deUint32									vertexAttributeDescriptionCount;
			vertexInputAttributeDescriptions								// const VkVertexInputAttributeDescription*	pVertexAttributeDescriptions;
		};

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

		const bool isDepthEnabled = (vk::mapVkFormat(m_stencilFormat).order != tcu::TextureFormat::S);

		VkPipelineDepthStencilStateCreateInfo depthStencilStateParams =
		{
			VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,	// VkStructureType							sType;
			DE_NULL,													// const void*								pNext;
			0u,															// VkPipelineDepthStencilStateCreateFlags	flags;
			isDepthEnabled,												// VkBool32									depthTestEnable;
			isDepthEnabled,												// VkBool32									depthWriteEnable;
			VK_COMPARE_OP_LESS,											// VkCompareOp								depthCompareOp;
			false,														// VkBool32									depthBoundsTestEnable;
			true,														// VkBool32									stencilTestEnable;
			m_stencilOpStateFront,										// VkStencilOpState							front;
			m_stencilOpStateBack,										// VkStencilOpState							back;
			0.0f,														// float									minDepthBounds;
			1.0f														// float									maxDepthBounds;
		};

		// Setup different stencil masks and refs in each quad
		for (int quadNdx = 0; quadNdx < StencilTest::QUAD_COUNT; quadNdx++)
		{
			const StencilTest::StencilStateConfig&	config	= StencilTest::s_stencilStateConfigs[quadNdx];
			VkStencilOpState&						front	= depthStencilStateParams.front;
			VkStencilOpState&						back	= depthStencilStateParams.back;

			front.compareMask	= config.frontReadMask;
			front.writeMask		= config.frontWriteMask;
			front.reference		= config.frontRef;

			back.compareMask	= config.backReadMask;
			back.writeMask		= config.backWriteMask;
			back.reference		= config.backRef;

			m_graphicsPipelines[quadNdx] = makeGraphicsPipeline(vk,										// const DeviceInterface&                        vk
																vkDevice,								// const VkDevice                                device
																*m_pipelineLayout,						// const VkPipelineLayout                        pipelineLayout
																*m_vertexShaderModule,					// const VkShaderModule                          vertexShaderModule
																DE_NULL,								// const VkShaderModule                          tessellationControlModule
																DE_NULL,								// const VkShaderModule                          tessellationEvalModule
																DE_NULL,								// const VkShaderModule                          geometryShaderModule
																*m_fragmentShaderModule,				// const VkShaderModule                          fragmentShaderModule
																*m_renderPass,							// const VkRenderPass                            renderPass
																viewports,								// const std::vector<VkViewport>&                viewports
																scissors,								// const std::vector<VkRect2D>&                  scissors
																VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,	// const VkPrimitiveTopology                     topology
																0u,										// const deUint32                                subpass
																0u,										// const deUint32                                patchControlPoints
																&vertexInputStateParams,				// const VkPipelineVertexInputStateCreateInfo*   vertexInputStateCreateInfo
																DE_NULL,								// const VkPipelineRasterizationStateCreateInfo* rasterizationStateCreateInfo
																DE_NULL,								// const VkPipelineMultisampleStateCreateInfo*   multisampleStateCreateInfo
																&depthStencilStateParams);				// const VkPipelineDepthStencilStateCreateInfo*  depthStencilStateCreateInfo
		}
	}


	// Create vertex buffer
	{
		const VkBufferCreateInfo vertexBufferParams =
		{
			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,		// VkStructureType		sType;
			DE_NULL,									// const void*			pNext;
			0u,											// VkBufferCreateFlags	flags;
			1024u,										// VkDeviceSize			size;
			VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,			// VkBufferUsageFlags	usage;
			VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode		sharingMode;
			1u,											// deUint32				queueFamilyIndexCount;
			&queueFamilyIndex							// const deUint32*		pQueueFamilyIndices;
		};

		m_vertices			= createOverlappingQuads();
		m_vertexBuffer		= createBuffer(vk, vkDevice, &vertexBufferParams);
		m_vertexBufferAlloc	= memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *m_vertexBuffer), MemoryRequirement::HostVisible);

		VK_CHECK(vk.bindBufferMemory(vkDevice, *m_vertexBuffer, m_vertexBufferAlloc->getMemory(), m_vertexBufferAlloc->getOffset()));

		// Adjust depths
		for (int quadNdx = 0; quadNdx < 4; quadNdx++)
			for (int vertexNdx = 0; vertexNdx < 6; vertexNdx++)
				m_vertices[quadNdx * 6 + vertexNdx].position.z() = StencilTest::s_quadDepths[quadNdx];

		// Load vertices into vertex buffer
		deMemcpy(m_vertexBufferAlloc->getHostPtr(), m_vertices.data(), m_vertices.size() * sizeof(Vertex4RGBA));
		flushAlloc(vk, vkDevice, *m_vertexBufferAlloc);
	}

	// Create command pool
	m_cmdPool = createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);

	// Create command buffer
	{
		const VkImageMemoryBarrier	colorImageBarrier	=
		{
			VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,			// VkStructureType            sType;
			DE_NULL,										// const void*                pNext;
			(VkAccessFlags)0,								// VkAccessFlags              srcAccessMask;
			VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,			// VkAccessFlags              dstAccessMask;
			VK_IMAGE_LAYOUT_UNDEFINED,						// VkImageLayout              oldLayout;
			VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,		// VkImageLayout              newLayout;
			VK_QUEUE_FAMILY_IGNORED,						// uint32_t                   srcQueueFamilyIndex;
			VK_QUEUE_FAMILY_IGNORED,						// uint32_t                   dstQueueFamilyIndex;
			*m_colorImage,									// VkImage                    image;
			{ VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u }	// VkImageSubresourceRange    subresourceRange;
		};

		const VkImageMemoryBarrier	stencilImageBarrier	=
		{
			VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,				// VkStructureType            sType;
			DE_NULL,											// const void*                pNext;
			(VkAccessFlags)0,									// VkAccessFlags              srcAccessMask;
			VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,		// VkAccessFlags              dstAccessMask;
			VK_IMAGE_LAYOUT_UNDEFINED,							// VkImageLayout              oldLayout;
			VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,	// VkImageLayout              newLayout;
			VK_QUEUE_FAMILY_IGNORED,							// uint32_t                   srcQueueFamilyIndex;
			VK_QUEUE_FAMILY_IGNORED,							// uint32_t                   dstQueueFamilyIndex;
			*m_stencilImage,									// VkImage                    image;
			m_stencilImageSubresourceRange,						// VkImageSubresourceRange    subresourceRange;
		};

		std::vector<VkClearValue>			attachmentClearValues;
		std::vector<VkImageMemoryBarrier>	imageLayoutBarriers;

		if (m_colorAttachmentEnable)
		{
			attachmentClearValues.push_back(defaultClearValue(m_colorFormat));
			imageLayoutBarriers.push_back(colorImageBarrier);
		}

		attachmentClearValues.push_back(defaultClearValue(m_stencilFormat));
		imageLayoutBarriers.push_back(stencilImageBarrier);

		m_cmdBuffer = allocateCommandBuffer(vk, vkDevice, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);

		beginCommandBuffer(vk, *m_cmdBuffer, 0u);

		vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT, (VkDependencyFlags)0,
			0u, DE_NULL, 0u, DE_NULL, (deUint32)imageLayoutBarriers.size(), imageLayoutBarriers.data());

		beginRenderPass(vk, *m_cmdBuffer, *m_renderPass, *m_framebuffer, makeRect2D(0, 0, m_renderSize.x(), m_renderSize.y()), (deUint32)attachmentClearValues.size(), attachmentClearValues.data());

		const VkDeviceSize		quadOffset		= (m_vertices.size() / StencilTest::QUAD_COUNT) * sizeof(Vertex4RGBA);

		for (int quadNdx = 0; quadNdx < StencilTest::QUAD_COUNT; quadNdx++)
		{
			VkDeviceSize vertexBufferOffset = quadOffset * quadNdx;

			vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_graphicsPipelines[quadNdx]);
			vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &m_vertexBuffer.get(), &vertexBufferOffset);
			vk.cmdDraw(*m_cmdBuffer, (deUint32)(m_vertices.size() / StencilTest::QUAD_COUNT), 1, 0, 0);
		}

		endRenderPass(vk, *m_cmdBuffer);
		endCommandBuffer(vk, *m_cmdBuffer);
	}
}

StencilTestInstance::~StencilTestInstance (void)
{
}

tcu::TestStatus StencilTestInstance::iterate (void)
{
	const DeviceInterface&		vk			= m_context.getDeviceInterface();
	const VkDevice				vkDevice	= m_context.getDevice();
	const VkQueue				queue		= m_context.getUniversalQueue();

	submitCommandsAndWait(vk, vkDevice, queue, m_cmdBuffer.get());

	return verifyImage();
}

tcu::TestStatus StencilTestInstance::verifyImage (void)
{
	const tcu::TextureFormat	tcuColorFormat		= mapVkFormat(VK_FORMAT_R8G8B8A8_UNORM);
	const tcu::TextureFormat	tcuStencilFormat	= mapVkFormat(m_stencilFormat);
	const ColorVertexShader		vertexShader;
	const ColorFragmentShader	fragmentShader		(tcuColorFormat, tcuStencilFormat);
	const rr::Program			program				(&vertexShader, &fragmentShader);
	ReferenceRenderer			refRenderer			(m_renderSize.x(), m_renderSize.y(), 1, tcuColorFormat, tcuStencilFormat, &program);
	bool						colorCompareOk		= false;
	bool						stencilCompareOk	= false;

	// Render reference image
	{
		// Set depth state
		rr::RenderState renderState(refRenderer.getViewportState(), m_context.getDeviceProperties().limits.subPixelPrecisionBits);

		renderState.fragOps.depthTestEnabled	= true;
		renderState.fragOps.depthFunc			= mapVkCompareOp(VK_COMPARE_OP_LESS);
		renderState.fragOps.stencilTestEnabled	= true;

		rr::StencilState& refStencilFront	= renderState.fragOps.stencilStates[rr::FACETYPE_FRONT];
		rr::StencilState& refStencilBack	= renderState.fragOps.stencilStates[rr::FACETYPE_BACK];

		refStencilFront.sFail		= mapVkStencilOp(m_stencilOpStateFront.failOp);
		refStencilFront.dpFail		= mapVkStencilOp(m_stencilOpStateFront.depthFailOp);
		refStencilFront.dpPass		= mapVkStencilOp(m_stencilOpStateFront.passOp);
		refStencilFront.func		= mapVkCompareOp(m_stencilOpStateFront.compareOp);

		refStencilBack.sFail		= mapVkStencilOp(m_stencilOpStateBack.failOp);
		refStencilBack.dpPass		= mapVkStencilOp(m_stencilOpStateBack.passOp);
		refStencilBack.dpFail		= mapVkStencilOp(m_stencilOpStateBack.depthFailOp);
		refStencilBack.func			= mapVkCompareOp(m_stencilOpStateBack.compareOp);

		// Reverse winding of vertices, as Vulkan screen coordinates start at upper left
		std::vector<Vertex4RGBA> cwVertices(m_vertices);
		for (size_t vertexNdx = 0; vertexNdx < cwVertices.size() - 2; vertexNdx += 3)
		{
			const Vertex4RGBA cwVertex1	= cwVertices[vertexNdx + 1];

			cwVertices[vertexNdx + 1]	= cwVertices[vertexNdx + 2];
			cwVertices[vertexNdx + 2]	= cwVertex1;
		}

		for (int quadNdx = 0; quadNdx < StencilTest::QUAD_COUNT; quadNdx++)
		{
			refStencilFront.ref			= (int)StencilTest::s_stencilStateConfigs[quadNdx].frontRef;
			refStencilFront.compMask	= StencilTest::s_stencilStateConfigs[quadNdx].frontReadMask;
			refStencilFront.writeMask	= StencilTest::s_stencilStateConfigs[quadNdx].frontWriteMask;

			refStencilBack.ref			= (int)StencilTest::s_stencilStateConfigs[quadNdx].backRef;
			refStencilBack.compMask		= StencilTest::s_stencilStateConfigs[quadNdx].backReadMask;
			refStencilBack.writeMask	= StencilTest::s_stencilStateConfigs[quadNdx].backWriteMask;

			refRenderer.draw(renderState,
							 rr::PRIMITIVETYPE_TRIANGLES,
							 std::vector<Vertex4RGBA>(cwVertices.begin() + quadNdx * 6,
													  cwVertices.begin() + (quadNdx + 1) * 6));
		}
	}

	// Compare result with reference image
	if (m_colorAttachmentEnable)
	{
		const DeviceInterface&				vk					= m_context.getDeviceInterface();
		const VkDevice						vkDevice			= m_context.getDevice();
		const VkQueue						queue				= m_context.getUniversalQueue();
		const deUint32						queueFamilyIndex	= m_context.getUniversalQueueFamilyIndex();
		SimpleAllocator						allocator			(vk, vkDevice, getPhysicalDeviceMemoryProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice()));
		de::UniquePtr<tcu::TextureLevel>	result				(readColorAttachment(vk, vkDevice, queue, queueFamilyIndex, allocator, *m_colorImage, m_colorFormat, m_renderSize).release());

		colorCompareOk = tcu::intThresholdPositionDeviationCompare(m_context.getTestContext().getLog(),
																   "IntImageCompare",
																   "Image comparison",
																   refRenderer.getAccess(),
																   result->getAccess(),
																   tcu::UVec4(2, 2, 2, 2),
																   tcu::IVec3(1, 1, 0),
																   true,
																   tcu::COMPARE_LOG_RESULT);
	}
	else
	{
		colorCompareOk = true;
	}

	// Compare stencil result with reference image
	{
		const DeviceInterface&				vk					= m_context.getDeviceInterface();
		const VkDevice						vkDevice			= m_context.getDevice();
		const VkQueue						queue				= m_context.getUniversalQueue();
		const deUint32						queueFamilyIndex	= m_context.getUniversalQueueFamilyIndex();
		SimpleAllocator						allocator			(vk, vkDevice, getPhysicalDeviceMemoryProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice()));
		de::UniquePtr<tcu::TextureLevel>	result				(readStencilAttachment(vk, vkDevice, queue, queueFamilyIndex, allocator, *m_stencilImage, m_stencilFormat, m_renderSize).release());

		{
			const tcu::PixelBufferAccess stencilAccess (tcu::getEffectiveDepthStencilAccess(refRenderer.getDepthStencilAccess(), tcu::Sampler::MODE_STENCIL));
			stencilCompareOk = tcu::intThresholdPositionDeviationCompare(m_context.getTestContext().getLog(),
																		 "StencilImageCompare",
																		 "Stencil image comparison",
																		 stencilAccess,
																		 result->getAccess(),
																		 tcu::UVec4(2, 2, 2, 2),
																		 tcu::IVec3(1, 1, 0),
																		 true,
																		 tcu::COMPARE_LOG_RESULT);
		}
	}

	if (colorCompareOk && stencilCompareOk)
		return tcu::TestStatus::pass("Result image matches reference");
	else
		return tcu::TestStatus::fail("Image mismatch");
}


// Utilities for test names

const char* getShortName (VkStencilOp stencilOp)
{
	switch (stencilOp)
	{
		case VK_STENCIL_OP_KEEP:					return "keep";
		case VK_STENCIL_OP_ZERO:					return "zero";
		case VK_STENCIL_OP_REPLACE:					return "repl";
		case VK_STENCIL_OP_INCREMENT_AND_CLAMP:		return "incc";
		case VK_STENCIL_OP_DECREMENT_AND_CLAMP:		return "decc";
		case VK_STENCIL_OP_INVERT:					return "inv";
		case VK_STENCIL_OP_INCREMENT_AND_WRAP:		return "wrap";
		case VK_STENCIL_OP_DECREMENT_AND_WRAP:		return "decw";

		default:
			DE_FATAL("Invalid VkStencilOpState value");
	}
	return DE_NULL;
}

std::string getStencilStateSetDescription(const VkStencilOpState& stencilOpStateFront,
										  const VkStencilOpState& stencilOpStateBack)
{
	std::ostringstream desc;

	desc << "\nFront faces:\n" << stencilOpStateFront;
	desc << "Back faces:\n" << stencilOpStateBack;

	return desc.str();
}

std::string getFormatCaseName (VkFormat format)
{
	const std::string fullName = getFormatName(format);

	DE_ASSERT(de::beginsWith(fullName, "VK_FORMAT_"));

	return de::toLower(fullName.substr(10));
}

} // anonymous

tcu::TestCaseGroup* createStencilTests (tcu::TestContext& testCtx)
{
	const VkFormat stencilFormats[] =
	{
		VK_FORMAT_S8_UINT,
		VK_FORMAT_D16_UNORM_S8_UINT,
		VK_FORMAT_D24_UNORM_S8_UINT,
		VK_FORMAT_D32_SFLOAT_S8_UINT
	};

	DE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(compareOps) == 8);
	DE_STATIC_ASSERT(vk::VK_COMPARE_OP_LAST == 8);

	static const char* compareOpNames[8] =
	{
		"comp_never",
		"comp_less",
		"comp_equal",
		"comp_less_or_equal",
		"comp_greater",
		"comp_not_equal",
		"comp_greater_or_equal",
		"comp_always"
	};

	de::MovePtr<tcu::TestCaseGroup>		stencilTests				(new tcu::TestCaseGroup(testCtx, "stencil", "Stencil tests"));
	de::MovePtr<tcu::TestCaseGroup>		noColorAttachmentTests		(new tcu::TestCaseGroup(testCtx, "nocolor", "Stencil tests with no color attachment"));
	const bool							colorAttachmentEnabled[]	= { true, false };

	for (deUint32 colorAttachmentEnabledIdx = 0; colorAttachmentEnabledIdx < DE_LENGTH_OF_ARRAY(colorAttachmentEnabled); colorAttachmentEnabledIdx++)
	{
		const bool							colorEnabled				= colorAttachmentEnabled[colorAttachmentEnabledIdx];
		de::MovePtr<tcu::TestCaseGroup>		formatTests					(new tcu::TestCaseGroup(testCtx, "format", "Uses different stencil formats"));
		StencilOpStateUniqueRandomIterator	stencilOpItr				(123);

		for (size_t formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(stencilFormats); formatNdx++)
		{
			const VkFormat					stencilFormat	= stencilFormats[formatNdx];
			de::MovePtr<tcu::TestCaseGroup>	formatTest		(new tcu::TestCaseGroup(testCtx,
																					getFormatCaseName(stencilFormat).c_str(),
																					(std::string("Uses format ") + getFormatName(stencilFormat)).c_str()));

			de::MovePtr<tcu::TestCaseGroup>	stencilStateTests;
			{
				std::ostringstream desc;
				desc << "Draws 4 quads with the following depths and dynamic stencil states: ";

				for (int quadNdx = 0; quadNdx < StencilTest::QUAD_COUNT; quadNdx++)
				{
					const StencilTest::StencilStateConfig& stencilConfig = StencilTest::s_stencilStateConfigs[quadNdx];

					desc << "(" << quadNdx << ") "
						 << "z = " << StencilTest::s_quadDepths[quadNdx] << ", "
						 << "frontReadMask = " << stencilConfig.frontReadMask << ", "
						 << "frontWriteMask = " << stencilConfig.frontWriteMask << ", "
						 << "frontRef = " << stencilConfig.frontRef << ", "
						 << "backReadMask = " << stencilConfig.backReadMask << ", "
						 << "backWriteMask = " << stencilConfig.backWriteMask << ", "
						 << "backRef = " << stencilConfig.backRef;
				}

				stencilStateTests = de::MovePtr<tcu::TestCaseGroup>(new tcu::TestCaseGroup(testCtx, "states", desc.str().c_str()));
			}

			stencilOpItr.reset();

			for (deUint32 failOpNdx = 0u; failOpNdx < DE_LENGTH_OF_ARRAY(stencilOps); failOpNdx++)
			{
				const std::string				failOpName	= std::string("fail_") + getShortName(stencilOps[failOpNdx]);
				de::MovePtr<tcu::TestCaseGroup>	failOpTest	(new tcu::TestCaseGroup(testCtx, failOpName.c_str(), ""));

				for (deUint32 passOpNdx = 0u; passOpNdx < DE_LENGTH_OF_ARRAY(stencilOps); passOpNdx++)
				{
					const std::string				passOpName	= std::string("pass_") + getShortName(stencilOps[passOpNdx]);
					de::MovePtr<tcu::TestCaseGroup>	passOpTest	(new tcu::TestCaseGroup(testCtx, passOpName.c_str(), ""));

					for (deUint32 dFailOpNdx = 0u; dFailOpNdx < DE_LENGTH_OF_ARRAY(stencilOps); dFailOpNdx++)
					{
						const std::string				dFailOpName	= std::string("dfail_") + getShortName(stencilOps[dFailOpNdx]);
						de::MovePtr<tcu::TestCaseGroup>	dFailOpTest	(new tcu::TestCaseGroup(testCtx, dFailOpName.c_str(), ""));

						for (deUint32 compareOpNdx = 0u; compareOpNdx < DE_LENGTH_OF_ARRAY(compareOps); compareOpNdx++)
						{
							// Iterate front set of stencil state in ascending order
							const VkStencilOpState	stencilStateFront	=
							{
								stencilOps[failOpNdx],		// failOp
								stencilOps[passOpNdx],		// passOp
								stencilOps[dFailOpNdx],		// depthFailOp
								compareOps[compareOpNdx],	// compareOp
								0x0,						// compareMask
								0x0,						// writeMask
								0x0							// reference
							};

							// Iterate back set of stencil state in random order
							const VkStencilOpState	stencilStateBack	= stencilOpItr.next();
							const std::string		caseName			= compareOpNames[compareOpNdx];
							const std::string		caseDesc			= getStencilStateSetDescription(stencilStateFront, stencilStateBack);

							dFailOpTest->addChild(new StencilTest(testCtx, caseName, caseDesc, stencilFormat, stencilStateFront, stencilStateBack, colorEnabled));
						}
						passOpTest->addChild(dFailOpTest.release());
					}
					failOpTest->addChild(passOpTest.release());
				}
				stencilStateTests->addChild(failOpTest.release());
			}

			formatTest->addChild(stencilStateTests.release());
			formatTests->addChild(formatTest.release());
		}

		if (colorEnabled)
			stencilTests->addChild(formatTests.release());
		else
			noColorAttachmentTests->addChild(formatTests.release());
	}

	stencilTests->addChild(noColorAttachmentTests.release());

	return stencilTests.release();
}

} // pipeline
} // vkt
