/*-------------------------------------------------------------------------
 * Vulkan Conformance Tests
 * ------------------------
 *
 * Copyright (c) 2018 The Khronos Group Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 *//*!
 * \file
 * \brief VK_KHR_depth_stencil_resolve tests.
 *//*--------------------------------------------------------------------*/

#include "vktRenderPassDepthStencilResolveTests.hpp"
#include "vktRenderPassTestsUtil.hpp"

#include "vktTestCaseUtil.hpp"
#include "vktTestGroupUtil.hpp"

#include "vkDefs.hpp"
#include "vkDeviceUtil.hpp"
#include "vkImageUtil.hpp"
#include "vkMemUtil.hpp"
#include "vkPlatform.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 "tcuFormatUtil.hpp"
#include "tcuResultCollector.hpp"
#include "tcuTestLog.hpp"
#include "tcuTextureUtil.hpp"

#include "deUniquePtr.hpp"
#include "deSharedPtr.hpp"
#include "deMath.h"
#include <limits>

using namespace vk;

using tcu::Vec4;
using tcu::TestLog;

typedef de::SharedPtr<vk::Unique<VkImage> >		VkImageSp;
typedef de::SharedPtr<vk::Unique<VkImageView> >	VkImageViewSp;
typedef de::SharedPtr<vk::Unique<VkBuffer> >	VkBufferSp;
typedef de::SharedPtr<vk::Unique<VkPipeline> >	VkPipelineSp;
typedef de::SharedPtr<Allocation>				AllocationSp;

namespace vkt
{
namespace
{

using namespace renderpass;

template<typename T>
de::SharedPtr<T> safeSharedPtr (T* ptr)
{
	try
	{
		return de::SharedPtr<T>(ptr);
	}
	catch (...)
	{
		delete ptr;
		throw;
	}
}

enum VerifyBuffer
{
	VB_DEPTH = 0,
	VB_STENCIL
};

struct TestConfig
{
	VkFormat					format;
	deUint32					width;
	deUint32					height;
	deUint32					imageLayers;
	deUint32					viewLayers;
	deUint32					resolveBaseLayer;
	VkRect2D					renderArea;
	VkImageAspectFlags			aspectFlag;
	deUint32					sampleCount;
	VkResolveModeFlagBitsKHR	depthResolveMode;
	VkResolveModeFlagBitsKHR	stencilResolveMode;
	VerifyBuffer				verifyBuffer;
	VkClearDepthStencilValue	clearValue;
	float						depthExpectedValue;
	deUint8						stencilExpectedValue;
};

float get16bitDepthComponent(deUint8* pixelPtr)
{
	deUint16* value = reinterpret_cast<deUint16*>(pixelPtr);
	return static_cast<float>(*value) / 65535.0f;
}

float get24bitDepthComponent(deUint8* pixelPtr)
{
	const bool littleEndian = (DE_ENDIANNESS == DE_LITTLE_ENDIAN);
	deUint32 value = (((deUint32)pixelPtr[0]) << (!littleEndian * 16u)) |
						(((deUint32)pixelPtr[1]) <<  8u) |
						(((deUint32)pixelPtr[2]) << ( littleEndian * 16u));
	return static_cast<float>(value) / 16777215.0f;
}

float get32bitDepthComponent(deUint8* pixelPtr)
{
	return *(reinterpret_cast<float*>(pixelPtr));
}

class DepthStencilResolveTest : public TestInstance
{
public:
								DepthStencilResolveTest		(Context& context, TestConfig config);
	virtual						~DepthStencilResolveTest	(void);

	virtual tcu::TestStatus		iterate (void);

protected:
	bool						isFeaturesSupported				(void);
	VkSampleCountFlagBits		sampleCountBitFromSampleCount	(deUint32 count) const;

	VkImageSp					createImage						(deUint32 sampleCount, VkImageUsageFlags additionalUsage = 0u);
	AllocationSp				createImageMemory				(VkImageSp image);
	VkImageViewSp				createImageView					(VkImageSp image, deUint32 baseArrayLayer);
	AllocationSp				createBufferMemory				(void);
	VkBufferSp					createBuffer					(void);

	Move<VkRenderPass>			createRenderPass				(void);
	Move<VkFramebuffer>			createFramebuffer				(VkRenderPass renderPass, VkImageViewSp multisampleImageView, VkImageViewSp singlesampleImageView);
	Move<VkPipelineLayout>		createRenderPipelineLayout		(void);
	Move<VkPipeline>			createRenderPipeline			(VkRenderPass renderPass, VkPipelineLayout renderPipelineLayout);

	void						submit							(void);
	bool						verifyDepth						(void);
	bool						verifyStencil					(void);

protected:
	const TestConfig				m_config;
	const bool						m_featureSupported;

	const InstanceInterface&		m_vki;
	const DeviceInterface&			m_vkd;
	VkDevice						m_device;
	VkPhysicalDevice				m_physicalDevice;

	VkImageSp						m_multisampleImage;
	AllocationSp					m_multisampleImageMemory;
	VkImageViewSp					m_multisampleImageView;
	VkImageSp						m_singlesampleImage;
	AllocationSp					m_singlesampleImageMemory;
	VkImageViewSp					m_singlesampleImageView;
	VkBufferSp						m_buffer;
	AllocationSp					m_bufferMemory;

	Unique<VkRenderPass>			m_renderPass;
	Unique<VkFramebuffer>			m_framebuffer;
	Unique<VkPipelineLayout>		m_renderPipelineLayout;
	Unique<VkPipeline>				m_renderPipeline;

	const Unique<VkCommandPool>		m_commandPool;
};

DepthStencilResolveTest::DepthStencilResolveTest (Context& context, TestConfig config)
	: TestInstance				(context)
	, m_config					(config)
	, m_featureSupported		(isFeaturesSupported())
	, m_vki						(context.getInstanceInterface())
	, m_vkd						(context.getDeviceInterface())
	, m_device					(context.getDevice())
	, m_physicalDevice			(context.getPhysicalDevice())

	, m_multisampleImage		(createImage(m_config.sampleCount, VK_IMAGE_USAGE_TRANSFER_SRC_BIT))
	, m_multisampleImageMemory	(createImageMemory(m_multisampleImage))
	, m_multisampleImageView	(createImageView(m_multisampleImage, 0u))

	, m_singlesampleImage		(createImage(1, VK_IMAGE_USAGE_TRANSFER_SRC_BIT))
	, m_singlesampleImageMemory	(createImageMemory(m_singlesampleImage))
	, m_singlesampleImageView	(createImageView(m_singlesampleImage, m_config.resolveBaseLayer))

	, m_buffer					(createBuffer())
	, m_bufferMemory			(createBufferMemory())

	, m_renderPass				(createRenderPass())
	, m_framebuffer				(createFramebuffer(*m_renderPass, m_multisampleImageView, m_singlesampleImageView))
	, m_renderPipelineLayout	(createRenderPipelineLayout())
	, m_renderPipeline			(createRenderPipeline(*m_renderPass, *m_renderPipelineLayout))


	, m_commandPool				(createCommandPool(context.getDeviceInterface(), context.getDevice(), VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, context.getUniversalQueueFamilyIndex()))
{
}

DepthStencilResolveTest::~DepthStencilResolveTest (void)
{
}

bool DepthStencilResolveTest::isFeaturesSupported()
{
	m_context.requireDeviceExtension("VK_KHR_depth_stencil_resolve");
	if (m_config.imageLayers > 1)
		m_context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_GEOMETRY_SHADER);

	VkPhysicalDeviceDepthStencilResolvePropertiesKHR dsResolveProperties;
	deMemset(&dsResolveProperties, 0, sizeof(VkPhysicalDeviceDepthStencilResolvePropertiesKHR));
	dsResolveProperties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_STENCIL_RESOLVE_PROPERTIES_KHR;
	dsResolveProperties.pNext = DE_NULL;

	VkPhysicalDeviceProperties2 deviceProperties;
	deviceProperties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
	deviceProperties.pNext = &dsResolveProperties;

	// perform query to get supported float control properties
	const VkPhysicalDevice			physicalDevice		= m_context.getPhysicalDevice();
	const vk::InstanceInterface&	instanceInterface	= m_context.getInstanceInterface();
	instanceInterface.getPhysicalDeviceProperties2(physicalDevice, &deviceProperties);

	// check if both modes are supported
	VkResolveModeFlagBitsKHR depthResolveMode		= m_config.depthResolveMode;
	VkResolveModeFlagBitsKHR stencilResolveMode		= m_config.stencilResolveMode;
	if ((depthResolveMode != VK_RESOLVE_MODE_NONE_KHR) &&
		!(depthResolveMode & dsResolveProperties.supportedDepthResolveModes))
		TCU_THROW(NotSupportedError, "Depth resolve mode not supported");
	if ((stencilResolveMode != VK_RESOLVE_MODE_NONE_KHR) &&
		!(stencilResolveMode & dsResolveProperties.supportedStencilResolveModes))
		TCU_THROW(NotSupportedError, "Stencil resolve mode not supported");

	// check if the implementation supports setting the depth and stencil resolve
	// modes to different values when one of those modes is VK_RESOLVE_MODE_NONE_KHR
	if (dsResolveProperties.independentResolveNone)
	{
		if ((!dsResolveProperties.independentResolve) &&
			(depthResolveMode != stencilResolveMode) &&
			(depthResolveMode != VK_RESOLVE_MODE_NONE_KHR) &&
			(stencilResolveMode != VK_RESOLVE_MODE_NONE_KHR))
			TCU_THROW(NotSupportedError, "Implementation doesn't support diferent resolve modes");
	}
	else if (depthResolveMode != stencilResolveMode)
	{
		// when independentResolveNone is VK_FALSE then both modes must be the same
		TCU_THROW(NotSupportedError, "Implementation doesn't support diferent resolve modes");
	}

	// check if the implementation supports all combinations of the supported depth and stencil resolve modes
	if (!dsResolveProperties.independentResolve && (depthResolveMode != stencilResolveMode))
		TCU_THROW(NotSupportedError, "Implementation doesn't support diferent resolve modes");

	return true;
}

VkSampleCountFlagBits DepthStencilResolveTest::sampleCountBitFromSampleCount (deUint32 count) const
{
	switch (count)
	{
		case 1:  return VK_SAMPLE_COUNT_1_BIT;
		case 2:  return VK_SAMPLE_COUNT_2_BIT;
		case 4:  return VK_SAMPLE_COUNT_4_BIT;
		case 8:  return VK_SAMPLE_COUNT_8_BIT;
		case 16: return VK_SAMPLE_COUNT_16_BIT;
		case 32: return VK_SAMPLE_COUNT_32_BIT;
		case 64: return VK_SAMPLE_COUNT_64_BIT;

		default:
			DE_FATAL("Invalid sample count");
			return (VkSampleCountFlagBits)0x0;
	}
}

VkImageSp DepthStencilResolveTest::createImage (deUint32 sampleCount, VkImageUsageFlags additionalUsage)
{
	const tcu::TextureFormat	format(mapVkFormat(m_config.format));
	const VkImageTiling			imageTiling(VK_IMAGE_TILING_OPTIMAL);
	VkSampleCountFlagBits		sampleCountBit(sampleCountBitFromSampleCount(sampleCount));
	VkImageUsageFlags			usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | additionalUsage;

	VkImageFormatProperties imageFormatProperties;
	if (m_vki.getPhysicalDeviceImageFormatProperties(m_physicalDevice, m_config.format, VK_IMAGE_TYPE_2D, imageTiling,
													 usage, 0u, &imageFormatProperties) == VK_ERROR_FORMAT_NOT_SUPPORTED)
	{
		TCU_THROW(NotSupportedError, "Format not supported");
	}
	if (imageFormatProperties.sampleCounts < sampleCount)
	{
		TCU_THROW(NotSupportedError, "Sample count not supported");
	}
	if (imageFormatProperties.maxArrayLayers < m_config.imageLayers)
	{
		TCU_THROW(NotSupportedError, "Layers count not supported");
	}

	const VkExtent3D imageExtent =
	{
		m_config.width,
		m_config.height,
		1u
	};

	if (!(tcu::hasDepthComponent(format.order) || tcu::hasStencilComponent(format.order)))
		TCU_THROW(NotSupportedError, "Format can't be used as depth/stencil attachment");

	if (imageFormatProperties.maxExtent.width < imageExtent.width
		|| imageFormatProperties.maxExtent.height < imageExtent.height
		|| ((imageFormatProperties.sampleCounts & sampleCountBit) == 0)
		|| imageFormatProperties.maxArrayLayers < m_config.imageLayers)
	{
		TCU_THROW(NotSupportedError, "Image type not supported");
	}

	const VkImageCreateInfo pCreateInfo =
	{
		VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
		DE_NULL,
		0u,
		VK_IMAGE_TYPE_2D,
		m_config.format,
		imageExtent,
		1u,
		m_config.imageLayers,
		sampleCountBit,
		imageTiling,
		usage,
		VK_SHARING_MODE_EXCLUSIVE,
		0u,
		DE_NULL,
		VK_IMAGE_LAYOUT_UNDEFINED
	};

	return safeSharedPtr(new Unique<VkImage>(vk::createImage(m_vkd, m_device, &pCreateInfo)));
}

AllocationSp DepthStencilResolveTest::createImageMemory (VkImageSp image)
{
	Allocator& allocator = m_context.getDefaultAllocator();

	de::MovePtr<Allocation> allocation (allocator.allocate(getImageMemoryRequirements(m_vkd, m_device, **image), MemoryRequirement::Any));
	VK_CHECK(m_vkd.bindImageMemory(m_device, **image, allocation->getMemory(), allocation->getOffset()));
	return safeSharedPtr(allocation.release());
}

VkImageViewSp DepthStencilResolveTest::createImageView (VkImageSp image, deUint32 baseArrayLayer)
{
	const VkImageSubresourceRange range =
	{
		m_config.aspectFlag,
		0u,
		1u,
		baseArrayLayer,
		m_config.viewLayers
	};

	const VkImageViewCreateInfo pCreateInfo =
	{
		VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
		DE_NULL,
		0u,
		**image,
		(m_config.viewLayers > 1) ? VK_IMAGE_VIEW_TYPE_2D_ARRAY : VK_IMAGE_VIEW_TYPE_2D,
		m_config.format,
		makeComponentMappingRGBA(),
		range,
	};
	return safeSharedPtr(new Unique<VkImageView>(vk::createImageView(m_vkd, m_device, &pCreateInfo)));
}

Move<VkRenderPass> DepthStencilResolveTest::createRenderPass (void)
{
	const VkSampleCountFlagBits samples(sampleCountBitFromSampleCount(m_config.sampleCount));

	const AttachmentDescription2 multisampleAttachment		// VkAttachmentDescription2KHR
	(
															// VkStructureType					sType;
		DE_NULL,											// const void*						pNext;
		0u,													// VkAttachmentDescriptionFlags		flags;
		m_config.format,									// VkFormat							format;
		samples,											// VkSampleCountFlagBits			samples;
		VK_ATTACHMENT_LOAD_OP_CLEAR,						// VkAttachmentLoadOp				loadOp;
		VK_ATTACHMENT_STORE_OP_DONT_CARE,					// VkAttachmentStoreOp				storeOp;
		VK_ATTACHMENT_LOAD_OP_CLEAR,						// VkAttachmentLoadOp				stencilLoadOp;
		VK_ATTACHMENT_STORE_OP_DONT_CARE,					// VkAttachmentStoreOp				stencilStoreOp;
		VK_IMAGE_LAYOUT_UNDEFINED,							// VkImageLayout					initialLayout;
		VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL				// VkImageLayout					finalLayout;
	);
	const AttachmentReference2 multisampleAttachmentRef		// VkAttachmentReference2KHR
	(
															// VkStructureType					sType;
		DE_NULL,											// const void*						pNext;
		0u,													// deUint32							attachment;
		VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,	// VkImageLayout					layout;
		0u													// VkImageAspectFlags				aspectMask;
	);

	const AttachmentDescription2 singlesampleAttachment		// VkAttachmentDescription2KHR
	(
															// VkStructureType					sType;
		DE_NULL,											// const void*						pNext;
		0u,													// VkAttachmentDescriptionFlags		flags;
		m_config.format,									// 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_TRANSFER_SRC_OPTIMAL				// VkImageLayout					finalLayout;
	);
	AttachmentReference2 singlesampleAttachmentRef			// VkAttachmentReference2KHR
	(
															// VkStructureType					sType;
		DE_NULL,											// const void*						pNext;
		1u,													// deUint32							attachment;
		VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,	// VkImageLayout					layout;
		0u													// VkImageAspectFlags				aspectMask;
	);

	std::vector<AttachmentDescription2> attachments;
	attachments.push_back(multisampleAttachment);
	attachments.push_back(singlesampleAttachment);

	VkSubpassDescriptionDepthStencilResolveKHR dsResolveDescription =
	{
		VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_DEPTH_STENCIL_RESOLVE_KHR,
		DE_NULL,																// const void*						pNext;
		m_config.depthResolveMode,												// VkResolveModeFlagBitsKHR			depthResolveMode;
		m_config.stencilResolveMode,											// VkResolveModeFlagBitsKHR			stencilResolveMode;
		&singlesampleAttachmentRef												// VkAttachmentReference2KHR		pDepthStencilResolveAttachment;
	};

	const SubpassDescription2 subpass					// VkSubpassDescription2KHR
	(
														// VkStructureType						sType;
		&dsResolveDescription,							// const void*							pNext;
		(VkSubpassDescriptionFlags)0,					// VkSubpassDescriptionFlags			flags;
		VK_PIPELINE_BIND_POINT_GRAPHICS,				// VkPipelineBindPoint					pipelineBindPoint;
		0u,												// deUint32								viewMask;
		0u,												// deUint32								inputAttachmentCount;
		DE_NULL,										// const VkAttachmentReference2KHR*		pInputAttachments;
		0u,												// deUint32								colorAttachmentCount;
		DE_NULL,										// const VkAttachmentReference2KHR*		pColorAttachments;
		DE_NULL,										// const VkAttachmentReference2KHR*		pResolveAttachments;
		&multisampleAttachmentRef,						// const VkAttachmentReference2KHR*		pDepthStencilAttachment;
		0u,												// deUint32								preserveAttachmentCount;
		DE_NULL											// const deUint32*						pPreserveAttachments;
	);

	const RenderPassCreateInfo2 renderPassCreator		// VkRenderPassCreateInfo2KHR
	(
														// VkStructureType						sType;
		DE_NULL,										// const void*							pNext;
		(VkRenderPassCreateFlags)0u,					// VkRenderPassCreateFlags				flags;
		(deUint32)attachments.size(),					// deUint32								attachmentCount;
		&attachments[0],								// const VkAttachmentDescription2KHR*	pAttachments;
		1u,												// deUint32								subpassCount;
		&subpass,										// const VkSubpassDescription2KHR*		pSubpasses;
		0u,												// deUint32								dependencyCount;
		DE_NULL,										// const VkSubpassDependency2KHR*		pDependencies;
		0u,												// deUint32								correlatedViewMaskCount;
		DE_NULL											// const deUint32*						pCorrelatedViewMasks;
	);

	return renderPassCreator.createRenderPass(m_vkd, m_device);
}

Move<VkFramebuffer> DepthStencilResolveTest::createFramebuffer (VkRenderPass renderPass, VkImageViewSp multisampleImageView, VkImageViewSp singlesampleImageView)
{
	std::vector<VkImageView> attachments;
	attachments.push_back(**multisampleImageView);
	attachments.push_back(**singlesampleImageView);

	const VkFramebufferCreateInfo createInfo =
	{
		VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
		DE_NULL,
		0u,

		renderPass,
		(deUint32)attachments.size(),
		&attachments[0],

		m_config.width,
		m_config.height,
		m_config.viewLayers
	};

	return vk::createFramebuffer(m_vkd, m_device, &createInfo);
}

Move<VkPipelineLayout> DepthStencilResolveTest::createRenderPipelineLayout (void)
{
	VkPushConstantRange pushConstant =
	{
		VK_SHADER_STAGE_FRAGMENT_BIT,
		0u,
		4u
	};

	deUint32				pushConstantRangeCount	= 0u;
	VkPushConstantRange*	pPushConstantRanges		= DE_NULL;
	if (m_config.verifyBuffer == VB_STENCIL)
	{
		pushConstantRangeCount	= 1u;
		pPushConstantRanges		= &pushConstant;
	}

	const VkPipelineLayoutCreateInfo createInfo	=
	{
		VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
		DE_NULL,
		(vk::VkPipelineLayoutCreateFlags)0,

		0u,
		DE_NULL,

		pushConstantRangeCount,
		pPushConstantRanges
	};

	return vk::createPipelineLayout(m_vkd, m_device, &createInfo);
}

Move<VkPipeline> DepthStencilResolveTest::createRenderPipeline (VkRenderPass renderPass, VkPipelineLayout renderPipelineLayout)
{
	const bool testingStencil = (m_config.verifyBuffer == VB_STENCIL);
	const vk::BinaryCollection& binaryCollection = m_context.getBinaryCollection();

	const Unique<VkShaderModule>	vertexShaderModule		(createShaderModule(m_vkd, m_device, binaryCollection.get("quad-vert"), 0u));
	const Unique<VkShaderModule>	fragmentShaderModule	(createShaderModule(m_vkd, m_device, binaryCollection.get("quad-frag"), 0u));
	const Move<VkShaderModule>		geometryShaderModule	(m_config.imageLayers == 1 ? Move<VkShaderModule>() : createShaderModule(m_vkd, m_device, binaryCollection.get("quad-geom"), 0u));

	const VkPipelineVertexInputStateCreateInfo vertexInputState =
	{
		VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
		DE_NULL,
		(VkPipelineVertexInputStateCreateFlags)0u,

		0u,
		DE_NULL,

		0u,
		DE_NULL
	};
	const tcu::UVec2				view		(m_config.width, m_config.height);
	const std::vector<VkViewport>	viewports	(1, makeViewport(view));
	const std::vector<VkRect2D>		scissors	(1, m_config.renderArea);

	const VkPipelineMultisampleStateCreateInfo multisampleState =
	{
		VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
		DE_NULL,
		(VkPipelineMultisampleStateCreateFlags)0u,

		sampleCountBitFromSampleCount(m_config.sampleCount),
		VK_FALSE,
		0.0f,
		DE_NULL,
		VK_FALSE,
		VK_FALSE,
	};
	const VkPipelineDepthStencilStateCreateInfo depthStencilState =
	{
		VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,
		DE_NULL,
		(VkPipelineDepthStencilStateCreateFlags)0u,

		VK_TRUE,							// depthTestEnable
		VK_TRUE,
		VK_COMPARE_OP_ALWAYS,
		VK_FALSE,
		testingStencil,						// stencilTestEnable
		{
			VK_STENCIL_OP_REPLACE,			// failOp
			VK_STENCIL_OP_REPLACE,			// passOp
			VK_STENCIL_OP_REPLACE,			// depthFailOp
			VK_COMPARE_OP_ALWAYS,			// compareOp
			0xFFu,							// compareMask
			0xFFu,							// writeMask
			1								// reference
		},
		{
			VK_STENCIL_OP_REPLACE,
			VK_STENCIL_OP_REPLACE,
			VK_STENCIL_OP_REPLACE,
			VK_COMPARE_OP_ALWAYS,
			0xFFu,
			0xFFu,
			1
		},
		0.0f,
		1.0f
	};

	std::vector<VkDynamicState> dynamicState;
	dynamicState.push_back(VK_DYNAMIC_STATE_STENCIL_REFERENCE);
	const VkPipelineDynamicStateCreateInfo dynamicStateCreateInfo =
	{
		VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,	// VkStructureType                      sType;
		DE_NULL,												// const void*                          pNext;
		(VkPipelineDynamicStateCreateFlags)0u,					// VkPipelineDynamicStateCreateFlags    flags;
		static_cast<deUint32>(dynamicState.size()),				// deUint32                             dynamicStateCount;
		&dynamicState[0]										// const VkDynamicState*                pDynamicStates;
	};

	return makeGraphicsPipeline(m_vkd,															// const DeviceInterface&                        vk
								m_device,														// const VkDevice                                device
								renderPipelineLayout,											// const VkPipelineLayout                        pipelineLayout
								*vertexShaderModule,											// const VkShaderModule                          vertexShaderModule
								DE_NULL,														// const VkShaderModule                          tessellationControlShaderModule
								DE_NULL,														// const VkShaderModule                          tessellationEvalShaderModule
								m_config.imageLayers == 1 ? DE_NULL : *geometryShaderModule,	// const VkShaderModule                          geometryShaderModule
								*fragmentShaderModule,											// const VkShaderModule                          fragmentShaderModule
								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
								&vertexInputState,												// const VkPipelineVertexInputStateCreateInfo*   vertexInputStateCreateInfo
								DE_NULL,														// const VkPipelineRasterizationStateCreateInfo* rasterizationStateCreateInfo
								&multisampleState,												// const VkPipelineMultisampleStateCreateInfo*   multisampleStateCreateInfo
								&depthStencilState,												// const VkPipelineDepthStencilStateCreateInfo*  depthStencilStateCreateInfo
								DE_NULL,														// const VkPipelineColorBlendStateCreateInfo*    colorBlendStateCreateInfo
								testingStencil ? &dynamicStateCreateInfo : DE_NULL);			// const VkPipelineDynamicStateCreateInfo*       dynamicStateCreateInfo
}

AllocationSp DepthStencilResolveTest::createBufferMemory (void)
{
	Allocator&				allocator = m_context.getDefaultAllocator();
	de::MovePtr<Allocation> allocation(allocator.allocate(getBufferMemoryRequirements(m_vkd, m_device, **m_buffer), MemoryRequirement::HostVisible));
	VK_CHECK(m_vkd.bindBufferMemory(m_device, **m_buffer, allocation->getMemory(), allocation->getOffset()));
	return safeSharedPtr(allocation.release());
}

VkBufferSp DepthStencilResolveTest::createBuffer (void)
{
	const VkBufferUsageFlags	bufferUsage			(VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT);
	const tcu::TextureFormat	textureFormat		(mapVkFormat(m_config.format));
	const VkDeviceSize			pixelSize			(textureFormat.getPixelSize());
	const VkBufferCreateInfo	createInfo			=
	{
		VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
		DE_NULL,
		0u,

		m_config.width * m_config.height * m_config.imageLayers * pixelSize,
		bufferUsage,

		VK_SHARING_MODE_EXCLUSIVE,
		0u,
		DE_NULL
	};
	return safeSharedPtr(new Unique<VkBuffer>(vk::createBuffer(m_vkd, m_device, &createInfo)));
}

void DepthStencilResolveTest::submit (void)
{
	const DeviceInterface&						vkd					(m_context.getDeviceInterface());
	const VkDevice								device				(m_context.getDevice());
	const Unique<VkCommandBuffer>				commandBuffer		(allocateCommandBuffer(vkd, device, *m_commandPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
	const RenderpassSubpass2::SubpassBeginInfo	subpassBeginInfo	(DE_NULL, VK_SUBPASS_CONTENTS_INLINE);
	const RenderpassSubpass2::SubpassEndInfo	subpassEndInfo		(DE_NULL);

	beginCommandBuffer(vkd, *commandBuffer);

	{
		VkClearValue clearValues[2];
		clearValues[0].depthStencil = m_config.clearValue;
		clearValues[1].depthStencil = m_config.clearValue;

		const VkRenderPassBeginInfo beginInfo =
		{
			VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
			DE_NULL,

			*m_renderPass,
			*m_framebuffer,

			{
				{ 0u, 0u },
				{ m_config.width, m_config.height }
			},

			2u,
			clearValues
		};
		RenderpassSubpass2::cmdBeginRenderPass(vkd, *commandBuffer, &beginInfo, &subpassBeginInfo);
	}

	// Render
	bool testingDepth = (m_config.verifyBuffer == VB_DEPTH);
	if (testingDepth)
	{
		vkd.cmdBindPipeline(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_renderPipeline);
		vkd.cmdDraw(*commandBuffer, 6u, 1u, 0u, 0u);
	}
	else
	{
		// For stencil we can set reference value for just one sample at a time
		// so we need to do as many passes as there are samples, first half
		// of samples is initialized with 1 and second half with 255
		const deUint32 halfOfSamples = m_config.sampleCount >> 1;
		for (deUint32 renderPass = 0 ; renderPass < m_config.sampleCount ; renderPass++)
		{
			deUint32 stencilReference = 1 + 254 * (renderPass >= halfOfSamples);
			vkd.cmdBindPipeline(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_renderPipeline);
			vkd.cmdPushConstants(*commandBuffer, *m_renderPipelineLayout, VK_SHADER_STAGE_FRAGMENT_BIT, 0u, sizeof(renderPass), &renderPass);
			vkd.cmdSetStencilReference(*commandBuffer, VK_STENCIL_FRONT_AND_BACK, stencilReference);
			vkd.cmdDraw(*commandBuffer, 6u, 1u, 0u, 0u);
		}
	}

	RenderpassSubpass2::cmdEndRenderPass(vkd, *commandBuffer, &subpassEndInfo);

	// Memory barriers between rendering and copying
	{
		const VkImageMemoryBarrier barrier =
		{
			VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
			DE_NULL,

			VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
			VK_ACCESS_TRANSFER_READ_BIT,

			VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
			VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,

			VK_QUEUE_FAMILY_IGNORED,
			VK_QUEUE_FAMILY_IGNORED,

			**m_singlesampleImage,
			{
				m_config.aspectFlag,
				0u,
				1u,
				0u,
				m_config.viewLayers
			}
		};

		vkd.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &barrier);
	}

	// Copy image memory to buffers
	const VkBufferImageCopy region =
	{
		0u,
		0u,
		0u,
		{
			testingDepth ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_STENCIL_BIT,
			0u,
			0u,
			m_config.viewLayers,
		},
		{ 0u, 0u, 0u },
		{ m_config.width, m_config.height, 1u }
	};

	vkd.cmdCopyImageToBuffer(*commandBuffer, **m_singlesampleImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, **m_buffer, 1u, &region);

	// Memory barriers between copies and host access
	{
		const VkBufferMemoryBarrier barrier =
		{
			VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
			DE_NULL,

			VK_ACCESS_TRANSFER_WRITE_BIT,
			VK_ACCESS_HOST_READ_BIT,

			VK_QUEUE_FAMILY_IGNORED,
			VK_QUEUE_FAMILY_IGNORED,

			**m_buffer,
			0u,
			VK_WHOLE_SIZE
		};

		vkd.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 0u, DE_NULL, 1u, &barrier, 0u, DE_NULL);
	}

	endCommandBuffer(vkd, *commandBuffer);

	submitCommandsAndWait(vkd, device, m_context.getUniversalQueue(), *commandBuffer);
}

bool DepthStencilResolveTest::verifyDepth (void)
{
	deUint32			layerSize	= m_config.width * m_config.height;
	deUint32			valuesCount	= layerSize * m_config.viewLayers;
	deUint8*			pixelPtr	= static_cast<deUint8*>(m_bufferMemory->getHostPtr());

	float expectedValue = m_config.depthExpectedValue;
	if (m_config.depthResolveMode == VK_RESOLVE_MODE_NONE_KHR)
		expectedValue = m_config.clearValue.depth;

	// depth data in buffer is tightly packed, ConstPixelBufferAccess
	// coludn't be used for depth value extraction as it cant interpret
	// formats containing just depth component

	typedef float (*DepthComponentGetterFn)(deUint8*);
	VkFormat				format				= m_config.format;
	DepthComponentGetterFn	getDepthComponent	= &get16bitDepthComponent;
	deUint32				pixelStep			= 2;
	float					epsilon				= 0.002f;

	if ((format == VK_FORMAT_X8_D24_UNORM_PACK32) ||
		(format == VK_FORMAT_D24_UNORM_S8_UINT))
	{
		getDepthComponent	= &get24bitDepthComponent;
		pixelStep			= 4;
	}
	else if ((format == VK_FORMAT_D32_SFLOAT) ||
				(format == VK_FORMAT_D32_SFLOAT_S8_UINT))
	{
		getDepthComponent	= &get32bitDepthComponent;
		pixelStep			= 4;
	}

	for (deUint32 valueIndex = 0; valueIndex < valuesCount; valueIndex++)
	{
		float depth = (*getDepthComponent)(pixelPtr);
		pixelPtr += pixelStep;

		// check if pixel data is outside of render area
		deInt32 layerIndex		= valueIndex / layerSize;
		deInt32 inLayerIndex	= valueIndex % layerSize;
		deInt32 x				= inLayerIndex % m_config.width;
		deInt32 y				= (inLayerIndex - x) / m_config.width;
		deInt32 x1				= m_config.renderArea.offset.x;
		deInt32 y1				= m_config.renderArea.offset.y;
		deInt32 x2				= x1 + m_config.renderArea.extent.width;
		deInt32 y2				= y1 + m_config.renderArea.extent.height;
		if ((x < x1) || (x >= x2) || (y < y1) || (y >= y2))
		{
			// verify that outside of render area there are clear values
			float error = deFloatAbs(depth - m_config.clearValue.depth);
			if (error > epsilon)
			{
				m_context.getTestContext().getLog()
				<< TestLog::Message << "(" << x << ", " << y
				<< ", layer: " << layerIndex << ") is outside of render area but depth value is: "
				<< depth << " (expected " << m_config.clearValue.depth << ")" << TestLog::EndMessage;
				return false;
			}

			// value is correct, go to next one
			continue;
		}

		float error = deFloatAbs(depth - expectedValue);
		if (error > epsilon)
		{
			m_context.getTestContext().getLog() << TestLog::Message
				<< "At (" << x << ", " << y << ", layer: " << layerIndex
				<< ") depth value is: " << depth << " expected: "
				<< expectedValue << TestLog::EndMessage;
			return false;
		}
	}
	m_context.getTestContext().getLog() << TestLog::Message
		<< "Depth value is " << expectedValue
		<< TestLog::EndMessage;

	return true;
}

bool DepthStencilResolveTest::verifyStencil (void)
{
	deUint32			layerSize	= m_config.width * m_config.height;
	deUint32			valuesCount	= layerSize * m_config.viewLayers;
	deUint8*			pixelPtr	= static_cast<deUint8*>(m_bufferMemory->getHostPtr());

	// when stencil is tested we are discarding invocations and
	// because of that depth and stencil need to be tested separately

	deUint8 expectedValue = m_config.stencilExpectedValue;
	if (m_config.stencilResolveMode == VK_RESOLVE_MODE_NONE_KHR)
		expectedValue = static_cast<deUint8>(m_config.clearValue.stencil);

	for (deUint32 valueIndex = 0; valueIndex < valuesCount; valueIndex++)
	{
		deUint8 stencil			= *pixelPtr++;
		deInt32 layerIndex		= valueIndex / layerSize;
		deInt32 inLayerIndex	= valueIndex % layerSize;
		deInt32 x				= inLayerIndex % m_config.width;
		deInt32 y				= (inLayerIndex - x) / m_config.width;
		deInt32 x1				= m_config.renderArea.offset.x;
		deInt32 y1				= m_config.renderArea.offset.y;
		deInt32 x2				= x1 + m_config.renderArea.extent.width;
		deInt32 y2				= y1 + m_config.renderArea.extent.height;
		if ((x < x1) || (x >= x2) || (y < y1) || (y >= y2))
		{
			if (stencil != m_config.clearValue.stencil)
			{
				m_context.getTestContext().getLog()
				<< TestLog::Message << "(" << x << ", " << y << ", layer: " << layerIndex
				<< ") is outside of render area but stencil value is: "
				<< stencil << " (expected " << m_config.clearValue.stencil << ")" << TestLog::EndMessage;
				return false;
			}

			// value is correct, go to next one
			continue;
		}

		if (stencil != expectedValue)
		{
			m_context.getTestContext().getLog() << TestLog::Message
				<< "At (" << x << ", " << y << ", layer: " << layerIndex
				<< ") stencil value is: " << static_cast<deUint32>(stencil)
				<< " expected: " << static_cast<deUint32>(expectedValue)
				<< TestLog::EndMessage;
			return false;
		}
	}
	m_context.getTestContext().getLog() << TestLog::Message
		<< "Stencil value is "
		<< static_cast<deUint32>(expectedValue)
		<< TestLog::EndMessage;

	return true;
}

tcu::TestStatus DepthStencilResolveTest::iterate (void)
{
	submit();

	bool result = false;
	if (m_config.verifyBuffer == VB_DEPTH)
		result = verifyDepth();
	else
		result = verifyStencil();

	if (result)
		return tcu::TestStatus::pass("Pass");
	return tcu::TestStatus::fail("Fail");
}

struct Programs
{
	void init (vk::SourceCollections& dst, TestConfig config) const
	{
		// geometry shader is only needed in multi-layer framebuffer resolve tests
		if (config.imageLayers > 1)
		{
			const deUint32 layerCount = 3;

			std::ostringstream src;
			src << "#version 450\n"
				<< "highp float;\n"
				<< "\n"
				<< "layout(triangles) in;\n"
				<< "layout(triangle_strip, max_vertices = " << 3 * 2 * layerCount << ") out;\n"
				<< "\n"
				<< "in gl_PerVertex {\n"
				<< "    vec4 gl_Position;\n"
				<< "} gl_in[];\n"
				<< "\n"
				<< "out gl_PerVertex {\n"
				<< "    vec4 gl_Position;\n"
				<< "};\n"
				<< "\n"
				<< "void main (void) {\n"
				<< "    for (int layerNdx = 0; layerNdx < " << layerCount << "; ++layerNdx) {\n"
				<< "        for(int vertexNdx = 0; vertexNdx < gl_in.length(); vertexNdx++) {\n"
				<< "            gl_Position = gl_in[vertexNdx].gl_Position;\n"
				<< "            gl_Layer    = layerNdx;\n"
				<< "            EmitVertex();\n"
				<< "        };\n"
				<< "        EndPrimitive();\n"
				<< "    };\n"
				<< "}\n";

			dst.glslSources.add("quad-geom") << glu::GeometrySource(src.str());
		}

		dst.glslSources.add("quad-vert") << glu::VertexSource(
			"#version 450\n"
			"out gl_PerVertex {\n"
			"\tvec4 gl_Position;\n"
			"};\n"
			"highp float;\n"
			"void main (void) {\n"
			"\tgl_Position = vec4(((gl_VertexIndex + 2) / 3) % 2 == 0 ? -1.0 : 1.0,\n"
			"\t                   ((gl_VertexIndex + 1) / 3) % 2 == 0 ? -1.0 : 1.0, 0.0, 1.0);\n"
			"}\n");

		if (config.verifyBuffer == VB_DEPTH)
		{
			dst.glslSources.add("quad-frag") << glu::FragmentSource(
				"#version 450\n"
				"precision highp float;\n"
				"precision highp int;\n"
				"void main (void)\n"
				"{\n"
				"  float sampleIndex = float(gl_SampleID);\n"				// sampleIndex is integer in range <0, 63>
				"  float valueIndex = round(mod(sampleIndex, 4.0));\n"		// limit possible depth values - count to 4
				"  float value = valueIndex + 2.0;\n"						// value is one of [2, 3, 4, 5]
				"  value = round(exp2(value));\n"							// value is one of [4, 8, 16, 32]
				"  bool condition = (int(value) == 8);\n"					// select second sample value (to make it smallest)
				"  value = round(value - float(condition) * 6.0);\n"		// value is one of [4, 2, 16, 32]
				"  gl_FragDepth = value / 100.0;\n"							// sample depth is one of [0.04, 0.02, 0.16, 0.32]
				"}\n");
		}
		else
		{
			dst.glslSources.add("quad-frag") << glu::FragmentSource(
				"#version 450\n"
				"precision highp float;\n"
				"precision highp int;\n"
				"layout(push_constant) uniform PushConstant {\n"
				"  highp int sampleID;\n"
				"} pushConstants;\n"
				"void main (void)\n"
				"{\n"
				"  if(gl_SampleID != pushConstants.sampleID)\n"
				"    discard;\n"
				"  gl_FragDepth = 0.5;\n"
				"}\n");
		}
	}
};

void initTests (tcu::TestCaseGroup* group)
{
	typedef InstanceFactory1<DepthStencilResolveTest, TestConfig, Programs> DSResolveTestInstance;

	struct FormatData
	{
		VkFormat		format;
		const char*		name;
		bool			hasDepth;
		bool			hasStencil;
	};
	FormatData formats[] =
	{
		{ VK_FORMAT_D16_UNORM,				"d16_unorm",			true,	false },
		{ VK_FORMAT_X8_D24_UNORM_PACK32,	"x8_d24_unorm_pack32",	true,	false },
		{ VK_FORMAT_D32_SFLOAT,				"d32_sfloat",			true,	false },
		{ VK_FORMAT_S8_UINT,				"s8_uint",				false,	true },
		{ VK_FORMAT_D16_UNORM_S8_UINT,		"d16_unorm_s8_uint",	true,	true },
		{ VK_FORMAT_D24_UNORM_S8_UINT,		"d24_unorm_s8_uint",	true,	true },
		{ VK_FORMAT_D32_SFLOAT_S8_UINT,		"d32_sfloat_s8_uint",	true,	true },
	};

	struct ResolveModeData
	{
		VkResolveModeFlagBitsKHR	flag;
		std::string					name;
	};
	ResolveModeData resolveModes[] =
	{
		{ VK_RESOLVE_MODE_NONE_KHR,				"none" },
		{ VK_RESOLVE_MODE_SAMPLE_ZERO_BIT_KHR,	"zero" },
		{ VK_RESOLVE_MODE_AVERAGE_BIT_KHR,		"average" },
		{ VK_RESOLVE_MODE_MIN_BIT_KHR,			"min" },
		{ VK_RESOLVE_MODE_MAX_BIT_KHR,			"max" },
	};

	struct ImageTestData
	{
		const char*					groupName;
		deUint32					width;
		deUint32					height;
		deUint32					imageLayers;
		VkRect2D					renderArea;
		VkClearDepthStencilValue	clearValue;
	};

	// NOTE: tests cant be executed for 1D and 3D images:
	// 1D images are not tested because acording to specyfication sampleCounts
	// will be set to VK_SAMPLE_COUNT_1_BIT when type is not VK_IMAGE_TYPE_2D
	// 3D images are not tested because VkFramebufferCreateInfo specification
	// states that: each element of pAttachments that is a 2D or 2D array image
	// view taken from a 3D image must not be a depth/stencil format
	ImageTestData imagesTestData[] =
	{
		{ "image_2d_32_32",	32, 32, 1, {{ 0,  0}, {32, 32}}, {0.000f, 0x00} },
		{ "image_2d_8_32",	 8, 32, 1, {{ 1,  1}, { 6, 30}}, {0.123f, 0x01} },
		{ "image_2d_49_13",	49, 13, 1, {{10,  5}, {20,  8}}, {1.000f, 0x05} },
		{ "image_2d_5_1",	 5,  1, 1, {{ 0,  0}, { 5,  1}}, {0.500f, 0x00} },
		{ "image_2d_17_1",	17,  1, 1, {{ 1,  0}, {15,  1}}, {0.789f, 0xfa} },
	};
	const deUint32 sampleCounts[] =
	{
		2u, 4u, 8u, 16u, 32u, 64u
	};
	const float depthExpectedValue[][6] =
	{
		// 2 samples	4			8			16			32			64
		{ 0.0f,			0.0f,		0.0f,		0.0f,		0.0f,		0.0f },		// RESOLVE_MODE_NONE - expect clear value
		{ 0.04f,		0.04f,		0.04f,		0.04f,		0.04f,		0.04f },	// RESOLVE_MODE_SAMPLE_ZERO_BIT
		{ 0.03f,		0.135f,		0.135f,		0.135f,		0.135f,		0.135f },	// RESOLVE_MODE_AVERAGE_BIT
		{ 0.02f,		0.02f,		0.02f,		0.02f,		0.02f,		0.02f },	// RESOLVE_MODE_MIN_BIT
		{ 0.04f,		0.32f,		0.32f,		0.32f,		0.32f,		0.32f },	// RESOLVE_MODE_MAX_BIT
	};
	const deUint8 stencilExpectedValue[][6] =
	{
		// 2 samples	4		8		16		32		64
		{ 0u,			0u,		0u,		0u,		0u,		0u },	// RESOLVE_MODE_NONE - expect clear value
		{ 1u,			1u,		1u,		1u,		1u,		1u },	// RESOLVE_MODE_SAMPLE_ZERO_BIT
		{ 0u,			0u,		0u,		0u,		0u,		0u },	// RESOLVE_MODE_AVERAGE_BIT - not supported
		{ 1u,			1u,		1u,		1u,		1u,		1u },	// RESOLVE_MODE_MIN_BIT
		{ 255u,			255u,	255u,	255u,	255u,	255u },	// RESOLVE_MODE_MAX_BIT
	};

	tcu::TestContext& testCtx(group->getTestContext());

	// iterate over image data
	for	 (deUint32 imageDataNdx = 0; imageDataNdx < DE_LENGTH_OF_ARRAY(imagesTestData); imageDataNdx++)
	{
		ImageTestData imageData = imagesTestData[imageDataNdx];

		// create test group for image data
		de::MovePtr<tcu::TestCaseGroup> imageGroup(new tcu::TestCaseGroup(testCtx, imageData.groupName, imageData.groupName));

		// iterate over sampleCounts
		for (size_t sampleCountNdx = 0; sampleCountNdx < DE_LENGTH_OF_ARRAY(sampleCounts); sampleCountNdx++)
		{
			const deUint32		sampleCount	(sampleCounts[sampleCountNdx]);
			const std::string	sampleName	("samples_" + de::toString(sampleCount));

			// create test group for sample count
			de::MovePtr<tcu::TestCaseGroup> sampleGroup(new tcu::TestCaseGroup(testCtx, sampleName.c_str(), sampleName.c_str()));

			// iterate over depth/stencil formats
			for (size_t formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(formats); formatNdx++)
			{
				const FormatData&			formatData	= formats[formatNdx];
				VkFormat					format		= formatData.format;
				const char*					formatName	= formatData.name;
				const bool					hasDepth	= formatData.hasDepth;
				const bool					hasStencil	= formatData.hasStencil;
				VkImageAspectFlags			aspectFlags	= (hasDepth * VK_IMAGE_ASPECT_DEPTH_BIT) |
														  (hasStencil * VK_IMAGE_ASPECT_STENCIL_BIT);

				// create test group for format
				de::MovePtr<tcu::TestCaseGroup> formatGroup(new tcu::TestCaseGroup(testCtx, formatName, formatName));

				// iterate over depth resolve modes
				for (size_t depthResolveModeNdx = 0; depthResolveModeNdx < DE_LENGTH_OF_ARRAY(resolveModes); depthResolveModeNdx++)
				{
					// iterate over stencil resolve modes
					for (size_t stencilResolveModeNdx = 0; stencilResolveModeNdx < DE_LENGTH_OF_ARRAY(resolveModes); stencilResolveModeNdx++)
					{
						// there is no average resolve mode for stencil - go to next iteration
						ResolveModeData& sResolve = resolveModes[stencilResolveModeNdx];
						if (sResolve.flag == VK_RESOLVE_MODE_AVERAGE_BIT_KHR)
							continue;

						// if pDepthStencilResolveAttachment is not NULL and does not have the value VK_ATTACHMENT_UNUSED,
						// depthResolveMode and stencilResolveMode must not both be VK_RESOLVE_MODE_NONE_KHR
						ResolveModeData& dResolve = resolveModes[depthResolveModeNdx];
						if ((dResolve.flag == VK_RESOLVE_MODE_NONE_KHR) && (sResolve.flag == VK_RESOLVE_MODE_NONE_KHR))
							continue;

						// If there is no depth, the depth resolve mode should be NONE, or
						// match the stencil resolve mode.
						if (!hasDepth && (dResolve.flag != VK_RESOLVE_MODE_NONE_KHR) &&
							(dResolve.flag != sResolve.flag))
							continue;

						// If there is no stencil, the stencil resmove mode should be NONE, or
						// match the depth resolve mode.
						if (!hasStencil && (sResolve.flag != VK_RESOLVE_MODE_NONE_KHR) &&
							(dResolve.flag != sResolve.flag))
							continue;

						std::string baseName = "depth_" + dResolve.name + "_stencil_" + sResolve.name;

						if (hasDepth)
						{
							std::string	name			= baseName + "_testing_depth";
							const char*	testName		= name.c_str();
							float		expectedValue	= depthExpectedValue[depthResolveModeNdx][sampleCountNdx];

							const TestConfig testConfig =
							{
								format,
								imageData.width,
								imageData.height,
								1u,
								1u,
								0u,
								imageData.renderArea,
								aspectFlags,
								sampleCount,
								dResolve.flag,
								sResolve.flag,
								VB_DEPTH,
								imageData.clearValue,
								expectedValue,
								0u
							};
							formatGroup->addChild(new DSResolveTestInstance(testCtx, tcu::NODETYPE_SELF_VALIDATE, testName, testName, testConfig));
						}
						if (hasStencil)
						{
							std::string	name			= baseName + "_testing_stencil";
							const char*	testName		= name.c_str();
							deUint8		expectedValue	= stencilExpectedValue[stencilResolveModeNdx][sampleCountNdx];

							const TestConfig testConfig =
							{
								format,
								imageData.width,
								imageData.height,
								1u,
								1u,
								0u,
								imageData.renderArea,
								aspectFlags,
								sampleCount,
								dResolve.flag,
								sResolve.flag,
								VB_STENCIL,
								imageData.clearValue,
								0.0f,
								expectedValue
							};
							formatGroup->addChild(new DSResolveTestInstance(testCtx, tcu::NODETYPE_SELF_VALIDATE, testName, testName, testConfig));
						}
					}
				}

				sampleGroup->addChild(formatGroup.release());
			}

			imageGroup->addChild(sampleGroup.release());
		}

		group->addChild(imageGroup.release());
	}

	{
		// layered texture tests are done for all stencil modes and depth modes - not all combinations
		// Test checks if all layer are resolved in multi-layered framebuffer and if we can have a framebuffer
		// which starts at a layer other than zero. Both parts are tested together by rendering to layers
		// 4-6 and resolving to layers 1-3.
		ImageTestData layeredTextureTestData =
		{
			"image_2d_16_64_6", 16, 64, 6, {{ 10,  10}, {6, 54}}, {1.0f, 0x0}
		};

		de::MovePtr<tcu::TestCaseGroup> imageGroup(new tcu::TestCaseGroup(testCtx, layeredTextureTestData.groupName, layeredTextureTestData.groupName));

		for (size_t sampleCountNdx = 0; sampleCountNdx < DE_LENGTH_OF_ARRAY(sampleCounts); sampleCountNdx++)
		{
			const deUint32		sampleCount	(sampleCounts[sampleCountNdx]);
			const std::string	sampleName	("samples_" + de::toString(sampleCount));

			// create test group for sample count
			de::MovePtr<tcu::TestCaseGroup> sampleGroup(new tcu::TestCaseGroup(testCtx, sampleName.c_str(), sampleName.c_str()));

			// iterate over depth/stencil formats
			for (size_t formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(formats); formatNdx++)
			{
				const FormatData&			formatData	= formats[formatNdx];
				VkFormat					format		= formatData.format;
				const char*					formatName	= formatData.name;
				const bool					hasDepth	= formatData.hasDepth;
				const bool					hasStencil	= formatData.hasStencil;
				VkImageAspectFlags			aspectFlags	= (hasDepth * VK_IMAGE_ASPECT_DEPTH_BIT) |
														  (hasStencil * VK_IMAGE_ASPECT_STENCIL_BIT);

				// create test group for format
				de::MovePtr<tcu::TestCaseGroup> formatGroup(new tcu::TestCaseGroup(testCtx, formatName, formatName));

				for (size_t resolveModeNdx = 0; resolveModeNdx < DE_LENGTH_OF_ARRAY(resolveModes); resolveModeNdx++)
				{
					ResolveModeData& mode = resolveModes[resolveModeNdx];

					if (hasDepth)
					{
						std::string	name			= "depth_" + mode.name;
						const char*	testName		= name.c_str();
						float		expectedValue	= depthExpectedValue[resolveModeNdx][sampleCountNdx];
						const TestConfig testConfig =
						{
							format,
							layeredTextureTestData.width,
							layeredTextureTestData.height,
							layeredTextureTestData.imageLayers,
							3u,
							0u,
							layeredTextureTestData.renderArea,
							aspectFlags,
							sampleCount,
							mode.flag,
							VK_RESOLVE_MODE_SAMPLE_ZERO_BIT_KHR,
							VB_DEPTH,
							layeredTextureTestData.clearValue,
							expectedValue,
							0u
						};
						formatGroup->addChild(new DSResolveTestInstance(testCtx, tcu::NODETYPE_SELF_VALIDATE, testName, testName, testConfig));
					}

					// there is no average resolve mode for stencil - go to next iteration
					if (mode.flag == VK_RESOLVE_MODE_AVERAGE_BIT_KHR)
						continue;

					if (hasStencil)
					{
						std::string	name			= "stencil_" + mode.name;
						const char*	testName		= name.c_str();
						deUint8		expectedValue	= stencilExpectedValue[resolveModeNdx][sampleCountNdx];
						const TestConfig testConfig =
						{
							format,
							layeredTextureTestData.width,
							layeredTextureTestData.height,
							layeredTextureTestData.imageLayers,
							3u,
							0u,
							layeredTextureTestData.renderArea,
							aspectFlags,
							sampleCount,
							VK_RESOLVE_MODE_SAMPLE_ZERO_BIT_KHR,
							mode.flag,
							VB_STENCIL,
							layeredTextureTestData.clearValue,
							0.0f,
							expectedValue
						};
						formatGroup->addChild(new DSResolveTestInstance(testCtx, tcu::NODETYPE_SELF_VALIDATE, testName, testName, testConfig));
					}
				}
				sampleGroup->addChild(formatGroup.release());
			}
			imageGroup->addChild(sampleGroup.release());
		}

		group->addChild(imageGroup.release());
	}
}

} // anonymous

tcu::TestCaseGroup* createRenderPass2DepthStencilResolveTests (tcu::TestContext& testCtx)
{
	return createTestGroup(testCtx, "depth_stencil_resolve", "Depth/stencil resolve tests", initTests);
}

} // vkt
