/*------------------------------------------------------------------------
 * Vulkan Conformance Tests
 * ------------------------
 *
 * Copyright (c) 2020 The Khronos Group Inc.
 * Copyright (c) 2020 Advanced Micro Devices, 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 Pipeline Cache Tests
 */
/*--------------------------------------------------------------------*/

#include "vktPipelineCreationCacheControlTests.hpp"

#include "deRandom.hpp"
#include "deUniquePtr.hpp"
#include "tcuStringTemplate.hpp"
#include "vkDeviceUtil.hpp"
#include "vkRefUtil.hpp"
#include "vktConstexprVectorUtil.hpp"
#include "vktTestCase.hpp"
#include "vktTestCaseUtil.hpp"

#include <chrono>
#include <random>
#include <string>
#include <vector>

namespace vkt
{
namespace pipeline
{
namespace
{
using namespace vk;

using tcu::StringTemplate;
using tcu::TestCaseGroup;
using tcu::TestContext;
using tcu::TestStatus;

using ::std::array;
using ::std::string;
using ::std::vector;

/*--------------------------------------------------------------------*//*!
 * Elements common to all test types
 *//*--------------------------------------------------------------------*/
namespace test_common
{
static constexpr auto VK_NULL_HANDLE = DE_NULL;

using ::std::chrono::high_resolution_clock;
using ::std::chrono::microseconds;

using duration			 = high_resolution_clock::duration;
using UniquePipeline	 = Move<VkPipeline>;
using UniqueShaderModule = Move<VkShaderModule>;

/*--------------------------------------------------------------------*//*!
 * \brief Paired Vulkan API result with elapsed duration
 *//*--------------------------------------------------------------------*/
struct TimedResult
{
	VkResult result;
	duration elapsed;
};

/*--------------------------------------------------------------------*//*!
 * \brief Validation function type output from vkCreate*Pipelines()
 *
 * \param result - VkResult returned from API call
 * \param pipeliens - vector of pipelines created
 * \param elapsed - high_resolution_clock::duration of time elapsed in API
 * \param reason - output string to give the reason for failure
 *
 * \return QP_TEST_RESULT_PASS on success QP_TEST_RESULT_FAIL otherwise
 *//*--------------------------------------------------------------------*/
using Validator = qpTestResult (*)(VkResult, const vector<UniquePipeline>&, duration, string&);

static constexpr size_t VALIDATOR_ARRAY_MAX = 4;
using ValidatorArray						= ConstexprVector<Validator, VALIDATOR_ARRAY_MAX>;

/*--------------------------------------------------------------------*//*!
 * \brief Run a loop of validation tests and return the result
 *//*--------------------------------------------------------------------*/
template <typename pipelines_t, qpTestResult FAIL_RESULT = QP_TEST_RESULT_FAIL>
TestStatus validateResults(VkResult				 result,
						   const pipelines_t&	 pipelines,
						   duration				 elapsed,
						   const ValidatorArray& validators)
{
	using de::contains;
	static constexpr VkResult ALLOWED_RESULTS[] = {VK_SUCCESS, VK_ERROR_PIPELINE_COMPILE_REQUIRED_EXT};

	string reason;

	if (contains(DE_ARRAY_BEGIN(ALLOWED_RESULTS), DE_ARRAY_END(ALLOWED_RESULTS), result) == DE_FALSE)
	{
		static const StringTemplate ERROR_MSG = {"Pipeline creation returned an error result: ${0}"};
		TCU_THROW(InternalError, ERROR_MSG.format(result).c_str());
	}

	for (const auto& validator : validators)
	{
		const auto qpResult = validator(result, pipelines, elapsed, reason);
		if (qpResult != QP_TEST_RESULT_PASS)
		{
			return {qpResult, reason};
		}
	}

	return TestStatus::pass("Test passed.");
}

/*--------------------------------------------------------------------*//*!
 * \brief Generate an error if result does not match VK_RESULT
 *//*--------------------------------------------------------------------*/
template <VkResult VK_RESULT, qpTestResult FAIL_RESULT = QP_TEST_RESULT_FAIL>
qpTestResult checkResult(VkResult result, const vector<UniquePipeline>&, duration, string& reason)
{
	if (VK_RESULT != result)
	{
		static const StringTemplate ERROR_MSG = {"Got ${0}, Expected ${1}"};
		reason								  = ERROR_MSG.format(result, VK_RESULT);
		return FAIL_RESULT;
	}

	return QP_TEST_RESULT_PASS;
}

/*--------------------------------------------------------------------*//*!
 * \brief Generate an error if pipeline[INDEX] is not valid
 *//*--------------------------------------------------------------------*/
template <size_t INDEX, qpTestResult FAIL_RESULT = QP_TEST_RESULT_FAIL>
qpTestResult checkPipelineMustBeValid(VkResult, const vector<UniquePipeline>& pipelines, duration, string& reason)
{
	if (pipelines.size() <= INDEX)
	{
		static const StringTemplate ERROR_MSG = {"Index ${0} is not in created pipelines (pipelines.size(): ${1})"};
		TCU_THROW(TestError, ERROR_MSG.format(INDEX, pipelines.size()));
	}

	if (*pipelines[INDEX] == VK_NULL_HANDLE)
	{
		static const StringTemplate ERROR_MSG = {"pipelines[${0}] is not a valid VkPipeline object"};
		reason								  = ERROR_MSG.format(INDEX);
		return FAIL_RESULT;
	}

	return QP_TEST_RESULT_PASS;
}

/*--------------------------------------------------------------------*//*!
 * \brief Generate an error if pipeline[INDEX] is not VK_NULL_HANDLE
 *//*--------------------------------------------------------------------*/
template <size_t INDEX, qpTestResult FAIL_RESULT = QP_TEST_RESULT_FAIL>
qpTestResult checkPipelineMustBeNull(VkResult, const vector<UniquePipeline>& pipelines, duration, string& reason)
{
	if (pipelines.size() <= INDEX)
	{
		static const StringTemplate ERROR_MSG = {"Index ${0} is not in created pipelines (pipelines.size(): ${1})"};
		TCU_THROW(TestError, ERROR_MSG.format(INDEX, pipelines.size()));
	}

	if (*pipelines[INDEX] != VK_NULL_HANDLE)
	{
		static const StringTemplate ERROR_MSG = {"pipelines[${0}] is not VK_NULL_HANDLE"};
		reason								  = ERROR_MSG.format(INDEX);
		return FAIL_RESULT;
	}

	return QP_TEST_RESULT_PASS;
}

/*--------------------------------------------------------------------*//*!
 * \brief Generate an error if any pipeline is valid after an early-return failure
 *//*--------------------------------------------------------------------*/
template <size_t INDEX, qpTestResult FAIL_RESULT = QP_TEST_RESULT_FAIL>
qpTestResult checkPipelineNullAfterIndex(VkResult, const vector<UniquePipeline>& pipelines, duration, string& reason)
{
	if (pipelines.size() <= INDEX)
	{
		static const StringTemplate ERROR_MSG = {"Index ${0} is not in created pipelines (pipelines.size(): ${1})"};
		TCU_THROW(TestError, ERROR_MSG.format(INDEX, pipelines.size()));
	}

	if (pipelines.size() - 1 == INDEX)
	{
		static const StringTemplate ERROR_MSG = {"Index ${0} is the last pipeline, likely a malformed test case"};
		TCU_THROW(TestError, ERROR_MSG.format(INDEX));
	}

	// Only have to iterate through if the requested index is null
	if (*pipelines[INDEX] == VK_NULL_HANDLE)
	{
		for (size_t i = INDEX + 1; i < pipelines.size(); ++i)
		{
			if (*pipelines[i] != VK_NULL_HANDLE)
			{
				static const StringTemplate ERROR_MSG = {
					"pipelines[${0}] is not VK_NULL_HANDLE after a explicit early return index"};
				reason = ERROR_MSG.format(i);
				return FAIL_RESULT;
			}
		}
	}

	return QP_TEST_RESULT_PASS;
}

/*--------------------------------------------------------------------*//*!
 * Time limit constants
 *//*--------------------------------------------------------------------*/
enum ElapsedTime
{
	ELAPSED_TIME_INFINITE  = microseconds{-1}.count(),
	ELAPSED_TIME_IMMEDIATE = microseconds{500}.count(),
	ELAPSED_TIME_FAST	   = microseconds{1000}.count()
};

/*--------------------------------------------------------------------*//*!
 * \brief Generate an error if elapsed time exceeds MAX_TIME
 *//*--------------------------------------------------------------------*/
template <ElapsedTime MAX_TIME, qpTestResult FAIL_RESULT = QP_TEST_RESULT_FAIL>
qpTestResult checkElapsedTime(VkResult, const vector<UniquePipeline>&, duration elapsed, string& reason)
{
#if defined(DE_DEBUG)
	DE_UNREF(elapsed);
	DE_UNREF(reason);

	// In debug mode timing is not likely to be accurate
	return QP_TEST_RESULT_PASS;
#else

	using ::std::chrono::duration_cast;

	static constexpr microseconds ALLOWED_TIME = microseconds{MAX_TIME};

	if (elapsed > ALLOWED_TIME)
	{
		static const StringTemplate ERROR_MSG = {"pipeline creation took longer than ${0}us (actual time: ${1}us)"};
		reason = ERROR_MSG.format(ALLOWED_TIME.count(), duration_cast<microseconds>(elapsed).count());
		return FAIL_RESULT;
	}

	return QP_TEST_RESULT_PASS;
#endif
}

/*--------------------------------------------------------------------*//*!
 * \brief Test case parameters
 *//*--------------------------------------------------------------------*/
struct TestParams
{
	enum CacheType
	{
		NO_CACHE = 0,
		EXPLICIT_CACHE,
		DERIVATIVE_HANDLE,
		DERIVATIVE_INDEX
	};

	struct Iteration
	{
		static constexpr size_t MAX_VARIANTS = 4;
		using Variant						 = VkPipelineCreateFlags;
		using VariantArray					 = ConstexprVector<Variant, MAX_VARIANTS>;

		static constexpr Variant NORMAL		  = 0;
		static constexpr Variant NO_COMPILE	  = VK_PIPELINE_CREATE_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT_EXT;
		static constexpr Variant EARLY_RETURN = NO_COMPILE | VK_PIPELINE_CREATE_EARLY_RETURN_ON_FAILURE_BIT_EXT;

		static constexpr VariantArray SINGLE_NORMAL						= VariantArray{NORMAL};
		static constexpr VariantArray SINGLE_NOCOMPILE					= VariantArray{NO_COMPILE};
		static constexpr VariantArray BATCH_NOCOMPILE_COMPILE_NOCOMPILE = VariantArray{NO_COMPILE, NORMAL, NO_COMPILE};
		static constexpr VariantArray BATCH_RETURN_COMPILE_NOCOMPILE = VariantArray{EARLY_RETURN, NORMAL, NO_COMPILE};

		inline constexpr Iteration() : variants{}, validators{} {};
		inline constexpr Iteration(const VariantArray& v, const ValidatorArray& f) : variants{v}, validators{f} {};

		VariantArray   variants;
		ValidatorArray validators;
	};

	static constexpr size_t MAX_ITERATIONS = 4;
	using IterationArray				   = ConstexprVector<Iteration, MAX_ITERATIONS>;

	const char*	   name;
	const char*	   description;
	CacheType	   cacheType;
	IterationArray iterations;
};

/*--------------------------------------------------------------------*//*!
 * \brief Verify extension and feature support
 *//*--------------------------------------------------------------------*/
void checkSupport(Context& context, const TestParams&)
{
	static constexpr char EXT_NAME[] = "VK_EXT_pipeline_creation_cache_control";
	if (!context.requireDeviceFunctionality(EXT_NAME))
	{
		TCU_THROW(NotSupportedError, "Extension 'VK_EXT_pipeline_creation_cache_control' is not supported");
	}

	const auto features = context.getPipelineCreationCacheControlFeaturesEXT();
	if (features.pipelineCreationCacheControl == DE_FALSE)
	{
		TCU_THROW(NotSupportedError, "Feature 'pipelineCreationCacheControl' is not enabled");
	}
}

/*--------------------------------------------------------------------*//*!
 * \brief Generate a random floating point number as a string
 *//*--------------------------------------------------------------------*/
float randomFloat()
{
#if !defined(DE_DEBUG)
	static de::Random state = {::std::random_device{}()};
#else
	static de::Random state = {0xDEADBEEF};
#endif

	return state.getFloat();
}

/*--------------------------------------------------------------------*//*!
 * \brief Get a string of VkResults from a vector
 *//*--------------------------------------------------------------------*/
string getResultsString(const vector<VkResult>& results)
{
	using ::std::ostringstream;

	ostringstream output;

	output << "results[" << results.size() << "]={ ";

	if (!results.empty())
	{
		output << results[0];
	}

	for (size_t i = 1; i < results.size(); ++i)
	{
		output << ", " << results[i];
	}

	output << " }";

	return output.str();
}

/*--------------------------------------------------------------------*//*!
 * \brief Cast a pointer to an the expected SPIRV type
 *//*--------------------------------------------------------------------*/
template <typename _t>
inline const deUint32* shader_cast(const _t* ptr)
{
	return reinterpret_cast<const deUint32*>(ptr);
}

/*--------------------------------------------------------------------*//*!
 * \brief Capture a container of Vulkan handles into Move<> types
 *//*--------------------------------------------------------------------*/
template <typename input_container_t,
		  typename handle_t	 = typename input_container_t::value_type,
		  typename move_t	 = Move<handle_t>,
		  typename deleter_t = Deleter<handle_t>,
		  typename output_t	 = vector<move_t>>
output_t wrapHandles(const DeviceInterface&		  vk,
					 VkDevice					  device,
					 const input_container_t&	  input,
					 const VkAllocationCallbacks* allocator = DE_NULL)
{
	using ::std::begin;
	using ::std::end;
	using ::std::transform;

	auto output = output_t{};
	output.resize(input.size());

	struct Predicate
	{
		deleter_t deleter;
		move_t	  operator()(handle_t v)
		{
			return (v != VK_NULL_HANDLE) ? move_t{check(v), deleter} : move_t{};
		}
	};

	const auto wrapHandle = Predicate{deleter_t{vk, device, allocator}};

	transform(begin(input), end(input), begin(output), wrapHandle);

	return output;
}

/*--------------------------------------------------------------------*//*!
 * \brief create vkPipelineCache for test params
 *//*--------------------------------------------------------------------*/
Move<VkPipelineCache> createPipelineCache(const DeviceInterface& vk, VkDevice device, const TestParams& params)
{
	if (params.cacheType != TestParams::EXPLICIT_CACHE)
	{
		return {};
	}

	static constexpr auto cacheInfo = VkPipelineCacheCreateInfo{
		VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO, //sType
		DE_NULL,									  //pNext
		VkPipelineCacheCreateFlags{},				  //flags
		deUintptr{0},								  //initialDataSize
		DE_NULL										  //pInitialData
	};

	return createPipelineCache(vk, device, &cacheInfo);
}

/*--------------------------------------------------------------------*//*!
 * \brief create VkPipelineLayout with descriptor sets from test parameters
 *//*--------------------------------------------------------------------*/
Move<VkPipelineLayout> createPipelineLayout(const DeviceInterface&				 vk,
											VkDevice							 device,
											const vector<VkDescriptorSetLayout>& setLayouts,
											const TestParams&)
{
	const auto layoutCreateInfo = VkPipelineLayoutCreateInfo{
		VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // sType
		DE_NULL,									   // pNext
		VkPipelineLayoutCreateFlags{},				   // flags
		static_cast<deUint32>(setLayouts.size()),	   // setLayoutCount
		setLayouts.data(),							   // pSetLayouts
		deUint32{0u},								   // pushConstantRangeCount
		DE_NULL,									   // pPushConstantRanges
	};

	return createPipelineLayout(vk, device, &layoutCreateInfo);
}

/*--------------------------------------------------------------------*//*!
 * \brief create basic VkPipelineLayout from test parameters
 *//*--------------------------------------------------------------------*/
Move<VkPipelineLayout> createPipelineLayout(const DeviceInterface& vk, VkDevice device, const TestParams&)
{
	static constexpr auto layoutCreateInfo = VkPipelineLayoutCreateInfo{
		VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // sType
		DE_NULL,									   // pNext
		VkPipelineLayoutCreateFlags{},				   // flags
		deUint32{0u},								   // setLayoutCount
		DE_NULL,									   // pSetLayouts
		deUint32{0u},								   // pushConstantRangeCount
		DE_NULL,									   // pPushConstantRanges
	};

	return createPipelineLayout(vk, device, &layoutCreateInfo);
}

/*--------------------------------------------------------------------*//*!
 * \brief Create array of shader modules
 *//*--------------------------------------------------------------------*/
vector<UniqueShaderModule> createShaderModules(const DeviceInterface&	  vk,
											   VkDevice					  device,
											   const BinaryCollection&	  collection,
											   const vector<const char*>& names)
{
	auto output = vector<UniqueShaderModule>{};
	output.reserve(names.size());

	for (const auto& name : names)
	{
		const auto& binary	   = collection.get(name);
		const auto	createInfo = VkShaderModuleCreateInfo{
			 VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO, // sType
			 DE_NULL,									  // pNext
			 VkShaderModuleCreateFlags{},				  // flags
			 binary.getSize(),							  // codeSize
			 shader_cast(binary.getBinary())			  // pCode
		 };

		output.push_back(createShaderModule(vk, device, &createInfo));
	}

	return output;
}

/*--------------------------------------------------------------------*//*!
 * \brief Create array of shader binding stages
 *//*--------------------------------------------------------------------*/
vector<VkPipelineShaderStageCreateInfo> createShaderStages(const vector<Move<VkShaderModule>>&	modules,
														   const vector<VkShaderStageFlagBits>& stages)
{
	DE_ASSERT(modules.size() == stages.size());

	auto output = vector<VkPipelineShaderStageCreateInfo>{};
	output.reserve(modules.size());

	int i = 0;

	for (const auto& module : modules)
	{
		const auto stageInfo = VkPipelineShaderStageCreateInfo{
			VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // sType
			DE_NULL,											 // pNext
			VkPipelineShaderStageCreateFlags{},					 // flags
			stages[i++],										 // stage
			*module,											 // module
			"main",												 // pName
			DE_NULL												 // pSpecializationInfo
		};

		output.push_back(stageInfo);
	}

	return output;
}

} // namespace test_common

/*--------------------------------------------------------------------*//*!
 * \brief Graphics pipeline specific testing
 *//*--------------------------------------------------------------------*/
namespace graphics_tests
{
using namespace test_common;

/*--------------------------------------------------------------------*//*!
 * \brief Common graphics pipeline create info initialization
 *//*--------------------------------------------------------------------*/
VkGraphicsPipelineCreateInfo getPipelineCreateInfoCommon()
{
	static constexpr auto VERTEX_BINDING = VkVertexInputBindingDescription{
		deUint32{0u},				// binding
		sizeof(float[4]),			// stride
		VK_VERTEX_INPUT_RATE_VERTEX // inputRate
	};

	static constexpr auto VERTEX_ATTRIBUTE = VkVertexInputAttributeDescription{
		deUint32{0u},				   // location
		deUint32{0u},				   // binding
		VK_FORMAT_R32G32B32A32_SFLOAT, // format
		deUint32{0u}				   // offset
	};

	static constexpr auto VERTEX_INPUT_STATE = VkPipelineVertexInputStateCreateInfo{
		VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // sType
		DE_NULL,												   // pNext
		VkPipelineVertexInputStateCreateFlags{},				   // flags
		deUint32{1u},											   // vertexBindingDescriptionCount
		&VERTEX_BINDING,										   // pVertexBindingDescriptions
		deUint32{1u},											   // vertexAttributeDescriptionCount
		&VERTEX_ATTRIBUTE										   // pVertexAttributeDescriptions
	};

	static constexpr auto IA_STATE = VkPipelineInputAssemblyStateCreateInfo{
		VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, // sType
		DE_NULL,													 // pNext
		VkPipelineInputAssemblyStateCreateFlags{},					 // flags
		VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,						 // topology
		VK_TRUE														 // primitiveRestartEnable
	};

	static constexpr auto TESSALATION_STATE = VkPipelineTessellationStateCreateInfo{
		VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_DOMAIN_ORIGIN_STATE_CREATE_INFO, // sType
		DE_NULL,																 // pNext
		VkPipelineTessellationStateCreateFlags{},								 // flags
		deUint32{0u}															 // patchControlPoints
	};

	static constexpr auto VIEWPORT = VkViewport{
		0.f, // x
		0.f, // y
		1.f, // width
		1.f, // height
		0.f, // minDepth
		1.f	 // maxDept
	};

	static constexpr auto SCISSOR_RECT = VkRect2D{
		{0, 0},	   // offset
		{256, 256} // extent
	};

	static constexpr auto VIEWPORT_STATE = VkPipelineViewportStateCreateInfo{
		VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, // sType
		DE_NULL,											   // pNext
		VkPipelineViewportStateCreateFlags{},				   // flags
		deUint32{1u},										   // viewportCount
		&VIEWPORT,											   // pViewports
		deUint32{1u},										   // scissorCount
		&SCISSOR_RECT										   // pScissors
	};

	static constexpr auto RASTERIZATION_STATE = VkPipelineRasterizationStateCreateInfo{
		VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // sType
		DE_NULL,													// pNext
		VkPipelineRasterizationStateCreateFlags{},					// flags
		VK_TRUE,													// depthClampEnable
		VK_TRUE,													// rasterizerDiscardEnable
		VK_POLYGON_MODE_FILL,										// polygonMode
		VK_CULL_MODE_NONE,											// cullMode
		VK_FRONT_FACE_CLOCKWISE,									// frontFace
		VK_FALSE,													// depthBiasEnable
		0.f,														// depthBiasConstantFactor
		0.f,														// depthBiasClamp
		0.f,														// depthBiasSlopeFactor
		1.f															// lineWidth
	};

	static constexpr auto SAMPLE_MASK = VkSampleMask{};

	static constexpr auto MULTISAMPLE_STATE = VkPipelineMultisampleStateCreateInfo{
		VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // sType
		DE_NULL,												  // pNext
		VkPipelineMultisampleStateCreateFlags{},				  // flags
		VK_SAMPLE_COUNT_1_BIT,									  // rasterizationSamples
		VK_FALSE,												  // sampleShadingEnable
		0.f,													  // minSampleShading
		&SAMPLE_MASK,											  // pSampleMask
		VK_FALSE,												  // alphaToCoverageEnable
		VK_FALSE												  // alphaToOneEnable
	};

	static constexpr auto STENCIL_OP_STATE = VkStencilOpState{
		VK_STENCIL_OP_ZERO,	  // failOp
		VK_STENCIL_OP_ZERO,	  // passOp
		VK_STENCIL_OP_ZERO,	  // depthFailOp
		VK_COMPARE_OP_ALWAYS, // compareOp
		deUint32{0u},		  // compareMask
		deUint32{0u},		  // writeMask
		deUint32{0u}		  // reference
	};

	static constexpr auto DEPTH_STENCIL_STATE = VkPipelineDepthStencilStateCreateInfo{
		VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, // sType
		DE_NULL,													// pNext
		VkPipelineDepthStencilStateCreateFlags{},					// flags
		VK_FALSE,													// depthTestEnable
		VK_FALSE,													// depthWriteEnable
		VK_COMPARE_OP_ALWAYS,										// depthCompareOp
		VK_FALSE,													// depthBoundsTestEnable
		VK_FALSE,													// stencilTestEnable
		STENCIL_OP_STATE,											// front
		STENCIL_OP_STATE,											// back
		0.f,														// minDepthBounds
		1.f															// maxDepthBounds
	};

	static constexpr auto COLOR_FLAGS_ALL = VkColorComponentFlags{VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT |
																  VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT};

	static constexpr auto COLOR_BLEND_ATTACH_STATE = VkPipelineColorBlendAttachmentState{
		VK_FALSE,			  // blendEnable
		VK_BLEND_FACTOR_ONE,  // srcColorBlendFactor
		VK_BLEND_FACTOR_ZERO, // dstColorBlendFactor
		VK_BLEND_OP_ADD,	  // colorBlendOp
		VK_BLEND_FACTOR_ONE,  // srcAlphaBlendFactor
		VK_BLEND_FACTOR_ZERO, // dstAlphaBlendFactor
		VK_BLEND_OP_ADD,	  // alphaBlendOp
		COLOR_FLAGS_ALL		  // colorWriteMask
	};

	static constexpr auto COLOR_BLEND_STATE = VkPipelineColorBlendStateCreateInfo{
		VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // sType
		DE_NULL,												  // pNext
		VkPipelineColorBlendStateCreateFlags{},					  // flags
		VK_FALSE,												  // logicOpEnable
		VK_LOGIC_OP_SET,										  // logicOp
		deUint32{1u},											  // attachmentCount
		&COLOR_BLEND_ATTACH_STATE,								  // pAttachments
		{0.f, 0.f, 0.f, 0.f}									  // blendConstants[4]
	};

	static constexpr auto DYNAMIC_STATE = VkPipelineDynamicStateCreateInfo{
		VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO, // sType;
		DE_NULL,											  // pNext;
		VkPipelineDynamicStateCreateFlags{},				  // flags;
		deUint32{0u},										  // dynamicStateCount;
		DE_NULL												  // pDynamicStates;
	};

	return VkGraphicsPipelineCreateInfo{
		VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, // sType
		DE_NULL,										 // pNext
		VkPipelineCreateFlags{},						 // flags
		deUint32{0u},									 // stageCount
		DE_NULL,										 // pStages
		&VERTEX_INPUT_STATE,							 // pVertexInputState
		&IA_STATE,										 // pInputAssemblyState
		&TESSALATION_STATE,								 // pTessellationState
		&VIEWPORT_STATE,								 // pViewportState
		&RASTERIZATION_STATE,							 // pRasterizationState
		&MULTISAMPLE_STATE,								 // pMultisampleState
		&DEPTH_STENCIL_STATE,							 // pDepthStencilState
		&COLOR_BLEND_STATE,								 // pColorBlendState
		&DYNAMIC_STATE,									 // pDynamicState
		VK_NULL_HANDLE,									 // layout
		VK_NULL_HANDLE,									 // renderPass
		deUint32{0u},									 // subpass
		VK_NULL_HANDLE,									 // basePipelineHandle
		deInt32{-1}										 // basePipelineIndex
	};
}

/*--------------------------------------------------------------------*//*!
 * \brief create VkGraphicsPipelineCreateInfo structs from test iteration
 *//*--------------------------------------------------------------------*/
vector<VkGraphicsPipelineCreateInfo> createPipelineCreateInfos(const TestParams::Iteration&		   iteration,
															   const VkGraphicsPipelineCreateInfo& base,
															   VkPipeline						   basePipeline,
															   const TestParams&				   testParameter)
{
	auto output = vector<VkGraphicsPipelineCreateInfo>{};
	output.reserve(iteration.variants.size());

	deInt32 count			  = 0;
	deInt32 basePipelineIndex = -1;

	for (VkPipelineCreateFlags flags : iteration.variants)
	{
		const auto curIndex	  = count++;
		auto	   createInfo = base;

		if (testParameter.cacheType == TestParams::DERIVATIVE_INDEX)
		{
			if (flags & VK_PIPELINE_CREATE_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT_EXT)
			{
				if (basePipelineIndex != -1)
				{
					flags |= VK_PIPELINE_CREATE_DERIVATIVE_BIT;
				}
			}
			else
			{
				flags |= VK_PIPELINE_CREATE_ALLOW_DERIVATIVES_BIT;

				if (basePipelineIndex == -1)
				{
					basePipelineIndex = curIndex;
				}
			}
		}

		createInfo.flags			  = flags;
		createInfo.basePipelineHandle = basePipeline;
		createInfo.basePipelineIndex  = basePipelineIndex;

		output.push_back(createInfo);
	}

	return output;
}

/*--------------------------------------------------------------------*//*!
 * \brief create VkRenderPass object for Graphics test
 *//*--------------------------------------------------------------------*/
Move<VkRenderPass> createRenderPass(const DeviceInterface& vk, VkDevice device, const TestParams&)
{
	static constexpr auto COLOR_FORMAT = VK_FORMAT_R8G8B8A8_UNORM;

	static constexpr auto COLOR_ATTACHMENT_REF = VkAttachmentReference{
		deUint32{0u},							 // attachment
		VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // layout
	};

	static constexpr auto SUBPASS = VkSubpassDescription{
		VkSubpassDescriptionFlags{},	 // flags
		VK_PIPELINE_BIND_POINT_GRAPHICS, // pipelineBindPoint
		deUint32{0u},					 // inputAttachmentCount
		DE_NULL,						 // pInputAttachments
		deUint32{1u},					 // colorAttachmentCount
		&COLOR_ATTACHMENT_REF,			 // pColorAttachments
		DE_NULL,						 // pResolveAttachments
		DE_NULL,						 // pDepthStencilAttachment
		deUint32{0u},					 // preserveAttachmentCount
		DE_NULL							 // pPreserveAttachments
	};

	static constexpr auto COLOR_ATTACHMENT = VkAttachmentDescription{
		VkAttachmentDescriptionFlags{},	  // flags
		COLOR_FORMAT,					  // format
		VK_SAMPLE_COUNT_1_BIT,			  // samples
		VK_ATTACHMENT_LOAD_OP_CLEAR,	  // loadOp
		VK_ATTACHMENT_STORE_OP_STORE,	  // storeOp
		VK_ATTACHMENT_LOAD_OP_DONT_CARE,  // stencilLoadOp
		VK_ATTACHMENT_STORE_OP_DONT_CARE, // stencilStoreOp
		VK_IMAGE_LAYOUT_UNDEFINED,		  // initialLayout
		VK_IMAGE_LAYOUT_PRESENT_SRC_KHR	  // finalLayout
	};

	static constexpr auto RENDER_PASS_CREATE_INFO = VkRenderPassCreateInfo{
		VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // sType
		DE_NULL,								   // pNext
		VkRenderPassCreateFlags{},				   // flags
		deUint32{1u},							   // attachmentCount
		&COLOR_ATTACHMENT,						   // pAttachments
		deUint32{1u},							   // subpassCount
		&SUBPASS,								   // pSubpasses
		deUint32{0u},							   // dependencyCount
		DE_NULL									   // pDependencies
	};

	return createRenderPass(vk, device, &RENDER_PASS_CREATE_INFO);
}

/*--------------------------------------------------------------------*//*!
 * \brief Initialize shader programs
 *//*--------------------------------------------------------------------*/
void initPrograms(SourceCollections& dst, const TestParams&)
{
	using ::glu::FragmentSource;
	using ::glu::VertexSource;

	// Vertex Shader
	static const StringTemplate VS_TEXT = {"#version 310 es\n"
										   "layout(location = 0) in vec4 position;\n"
										   "layout(location = 0) out vec3 vertColor;\n"
										   "void main (void)\n"
										   "{\n"
										   "  gl_Position = position;\n"
										   "  vertColor = vec3(${0}, ${1}, ${2});\n"
										   "}\n"};

	// Fragment Shader
	static const StringTemplate FS_TEXT = {"#version 310 es\n"
										   "precision highp float;\n"
										   "layout(location = 0) in vec3 vertColor;\n"
										   "layout(location = 0) out vec4 outColor;\n"
										   "void main (void)\n"
										   "{\n"
										   "  const vec3 fragColor = vec3(${0}, ${1}, ${2});\n"
										   "  outColor = vec4((fragColor + vertColor) * 0.5, 1.0);\n"
										   "}\n"};

	dst.glslSources.add("vertex") << VertexSource{VS_TEXT.format(randomFloat(), randomFloat(), randomFloat())};
	dst.glslSources.add("fragment") << FragmentSource{FS_TEXT.format(randomFloat(), randomFloat(), randomFloat())};
}

/*--------------------------------------------------------------------*//*!
 * \brief return both result and elapsed time from pipeline creation
 *//*--------------------------------------------------------------------*/
template <typename create_infos_t, typename pipelines_t>
TimedResult timePipelineCreation(const DeviceInterface&		  vk,
								 const VkDevice				  device,
								 const VkPipelineCache		  cache,
								 const create_infos_t&		  createInfos,
								 pipelines_t&				  pipelines,
								 const VkAllocationCallbacks* pAllocator = DE_NULL)
{
	DE_ASSERT(createInfos.size() <= pipelines.size());

	const auto timeStart = high_resolution_clock::now();
	const auto result	 = vk.createGraphicsPipelines(
		   device, cache, static_cast<deUint32>(createInfos.size()), createInfos.data(), pAllocator, pipelines.data());
	const auto elapsed = high_resolution_clock::now() - timeStart;
	return {result, elapsed};
}

/*--------------------------------------------------------------------*//*!
 * \brief Test instance function
 *//*--------------------------------------------------------------------*/
TestStatus testInstance(Context& context, const TestParams& testParameter)
{
	const auto& vk			  = context.getDeviceInterface();
	const auto	device		  = context.getDevice();
	const auto	pipelineCache = createPipelineCache(vk, device, testParameter);
	const auto	layout		  = createPipelineLayout(vk, device, testParameter);
	const auto	renderPass	  = createRenderPass(vk, device, testParameter);
	const auto	modules		  = createShaderModules(vk, device, context.getBinaryCollection(), {"vertex", "fragment"});
	const auto	shaderStages  = createShaderStages(modules, {VK_SHADER_STAGE_VERTEX_BIT, VK_SHADER_STAGE_FRAGMENT_BIT});

	// Placeholder for base pipeline if using cacheType == DERIVATIVE_HANDLE
	auto basePipeline = UniquePipeline{};

	auto baseCreateInfo		  = getPipelineCreateInfoCommon();
	baseCreateInfo.layout	  = layout.get();
	baseCreateInfo.renderPass = renderPass.get();
	baseCreateInfo.stageCount = static_cast<deUint32>(shaderStages.size());
	baseCreateInfo.pStages	  = shaderStages.data();

	auto results = vector<VkResult>{};
	results.reserve(testParameter.iterations.size());

	for (const auto& i : testParameter.iterations)
	{
		const auto createInfos = createPipelineCreateInfos(i, baseCreateInfo, basePipeline.get(), testParameter);
		auto	   created	   = vector<VkPipeline>{};
		created.resize(createInfos.size());

		const auto timedResult = timePipelineCreation(vk, device, pipelineCache.get(), createInfos, created);
		auto	   pipelines   = wrapHandles(vk, device, created);

		const auto status = validateResults(timedResult.result, pipelines, timedResult.elapsed, i.validators);
		if (status.getCode() != QP_TEST_RESULT_PASS)
		{
			return status;
		}

		if ((testParameter.cacheType == TestParams::DERIVATIVE_HANDLE) && (*basePipeline == VK_NULL_HANDLE))
		{
			for (auto& pipeline : pipelines)
			{
				if (*pipeline != VK_NULL_HANDLE)
				{
					basePipeline = pipeline;
					break;
				}
			}
		}

		results.push_back(timedResult.result);
	}

	static const StringTemplate PASS_MSG = {"Test Passed. ${0}"};
	return TestStatus::pass(PASS_MSG.format(getResultsString(results)));
}

} // namespace graphics_tests

/*--------------------------------------------------------------------*//*!
 * \brief Compute pipeline specific testing
 *//*--------------------------------------------------------------------*/
namespace compute_tests
{
using namespace test_common;

/*--------------------------------------------------------------------*//*!
 * \brief create VkComputePipelineCreateInfo structs from test iteration
 *//*--------------------------------------------------------------------*/
vector<VkComputePipelineCreateInfo> createPipelineCreateInfos(const TestParams::Iteration&		 iteration,
															  const VkComputePipelineCreateInfo& base,
															  VkPipeline						 basePipeline,
															  const TestParams&					 testParameter)
{
	auto output = vector<VkComputePipelineCreateInfo>{};
	output.reserve(iteration.variants.size());

	deInt32 count			  = 0;
	deInt32 basePipelineIndex = -1;

	for (VkPipelineCreateFlags flags : iteration.variants)
	{
		const auto curIndex	  = count++;
		auto	   createInfo = base;

		if (testParameter.cacheType == TestParams::DERIVATIVE_INDEX)
		{
			if (flags & VK_PIPELINE_CREATE_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT_EXT)
			{
				if (basePipelineIndex != -1)
				{
					flags |= VK_PIPELINE_CREATE_DERIVATIVE_BIT;
				}
			}
			else
			{
				flags |= VK_PIPELINE_CREATE_ALLOW_DERIVATIVES_BIT;

				if (basePipelineIndex == -1)
				{
					basePipelineIndex = curIndex;
				}
			}
		}

		createInfo.flags			  = flags;
		createInfo.basePipelineHandle = basePipeline;
		createInfo.basePipelineIndex  = basePipelineIndex;

		output.push_back(createInfo);
	}

	return output;
}

/*--------------------------------------------------------------------*//*!
 * \brief create compute descriptor set layout
 *//*--------------------------------------------------------------------*/
Move<VkDescriptorSetLayout> createDescriptorSetLayout(const DeviceInterface& vk, VkDevice device, const TestParams&)
{
	static constexpr auto DESCRIPTOR_SET_LAYOUT_BINDING = VkDescriptorSetLayoutBinding{
		deUint32{0u},					   // binding
		VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, // descriptorType
		deUint32{1u},					   // descriptorCount
		VK_SHADER_STAGE_COMPUTE_BIT,	   // stageFlags
		DE_NULL							   // pImmutableSamplers
	};

	static constexpr auto DESCRIPTOR_SET_LAYOUT_CREATE_INFO = VkDescriptorSetLayoutCreateInfo{
		VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, // sType
		DE_NULL,											 // pNext
		VkDescriptorSetLayoutCreateFlags{},					 // flags
		deUint32{1u},										 // bindingCount
		&DESCRIPTOR_SET_LAYOUT_BINDING						 // pBindings
	};

	return createDescriptorSetLayout(vk, device, &DESCRIPTOR_SET_LAYOUT_CREATE_INFO);
}

/*--------------------------------------------------------------------*//*!
 * \brief Initialize shader programs
 *//*--------------------------------------------------------------------*/
void initPrograms(SourceCollections& dst, const TestParams&)
{
	using ::glu::ComputeSource;

	static const StringTemplate CS_TEXT = {"#version 450\n"
										   "precision highp float;\n"
										   "layout (local_size_x = 64, local_size_y = 1, local_size_z = 1) in;\n"
										   "layout (std140, binding = 0) buffer buf { vec3 data[]; };\n"
										   "void main (void)\n"
										   "{\n"
										   "  data[gl_GlobalInvocationID.x] = vec3(${0}, ${1}, ${2});\n"
										   "}\n"};

	dst.glslSources.add("compute")
		<< ComputeSource{CS_TEXT.format(randomFloat(), randomFloat(), randomFloat())};
}

/*--------------------------------------------------------------------*//*!
 * \brief return both result and elapsed time from pipeline creation
 *//*--------------------------------------------------------------------*/
template <typename create_infos_t, typename pipelines_t>
TimedResult timePipelineCreation(const DeviceInterface&		  vk,
								 const VkDevice				  device,
								 const VkPipelineCache		  cache,
								 const create_infos_t&		  createInfos,
								 pipelines_t&				  pipelines,
								 const VkAllocationCallbacks* pAllocator = DE_NULL)
{
	DE_ASSERT(createInfos.size() <= pipelines.size());

	const auto timeStart = high_resolution_clock::now();
	const auto result	 = vk.createComputePipelines(
		   device, cache, static_cast<deUint32>(createInfos.size()), createInfos.data(), pAllocator, pipelines.data());
	const auto elapsed = high_resolution_clock::now() - timeStart;
	return {result, elapsed};
}

/*--------------------------------------------------------------------*//*!
 * \brief Test instance function
 *//*--------------------------------------------------------------------*/
TestStatus testInstance(Context& context, const TestParams& testParameter)
{
	const auto& vk					= context.getDeviceInterface();
	const auto	device				= context.getDevice();
	const auto	pipelineCache		= createPipelineCache(vk, device, testParameter);
	const auto	descriptorSetLayout = createDescriptorSetLayout(vk, device, testParameter);
	const auto	pipelineLayout		= createPipelineLayout(vk, device, {descriptorSetLayout.get()}, testParameter);
	const auto	modules				= createShaderModules(vk, device, context.getBinaryCollection(), {"compute"});
	const auto	shaderStages		= createShaderStages(modules, {VK_SHADER_STAGE_COMPUTE_BIT});

	// Placeholder for base pipeline if using cacheType == DERIVATIVE_HANDLE
	auto basePipeline = UniquePipeline{};

	const auto baseCreateInfo = VkComputePipelineCreateInfo{
		VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO, // sType
		DE_NULL,										// pNext
		VkPipelineCreateFlags{},						// flags
		shaderStages[0],								// stage
		pipelineLayout.get(),							// layout
		VK_NULL_HANDLE,									// basePipelineHandle
		deInt32{-1}										// basePipelineIndex
	};

	auto results = vector<VkResult>{};
	results.reserve(testParameter.iterations.size());

	for (const auto& i : testParameter.iterations)
	{
		const auto createInfos = createPipelineCreateInfos(i, baseCreateInfo, basePipeline.get(), testParameter);
		auto	   created	   = vector<VkPipeline>{};
		created.resize(createInfos.size());

		const auto timedResult = timePipelineCreation(vk, device, pipelineCache.get(), createInfos, created);
		auto	   pipelines   = wrapHandles(vk, device, created);

		const auto status = validateResults(timedResult.result, pipelines, timedResult.elapsed, i.validators);
		if (status.getCode() != QP_TEST_RESULT_PASS)
		{
			return status;
		}

		if ((testParameter.cacheType == TestParams::DERIVATIVE_HANDLE) && (*basePipeline == VK_NULL_HANDLE))
		{
			for (auto& pipeline : pipelines)
			{
				if (*pipeline != VK_NULL_HANDLE)
				{
					basePipeline = pipeline;
					break;
				}
			}
		}

		results.push_back(timedResult.result);
	}

	static const StringTemplate PASS_MSG = {"Test Passed. ${0}"};
	return TestStatus::pass(PASS_MSG.format(getResultsString(results)));
}

} // namespace compute_tests

using namespace test_common;

/*--------------------------------------------------------------------*//*!
 * \brief Duplicate single pipeline recreation with explicit caching
 *//*--------------------------------------------------------------------*/
static constexpr TestParams DUPLICATE_SINGLE_RECREATE_EXPLICIT_CACHING =
{
	"duplicate_single_recreate_explicit_caching",
	"Duplicate single pipeline recreation with explicit caching",
	TestParams::EXPLICIT_CACHE,
	TestParams::IterationArray
	{
		TestParams::Iteration{
			// Iteration [0]: Force compilation of pipeline
			TestParams::Iteration::SINGLE_NORMAL,
			ValidatorArray{
				// Fail if result is not VK_SUCCESS
				checkResult<VK_SUCCESS>,
				// Fail if pipeline is not valid
				checkPipelineMustBeValid<0>
			}
		},
		TestParams::Iteration{
			// Iteration [1]: Request compilation of same pipeline without compile
			TestParams::Iteration::SINGLE_NOCOMPILE,
			ValidatorArray{
				// Warn if result is not VK_SUCCESS
				checkResult<VK_SUCCESS, QP_TEST_RESULT_COMPATIBILITY_WARNING>,
				// Warn if pipeline is not valid
				checkPipelineMustBeValid<0, QP_TEST_RESULT_COMPATIBILITY_WARNING>,
				// Warn if pipeline took too long
				checkElapsedTime<ELAPSED_TIME_FAST, QP_TEST_RESULT_QUALITY_WARNING>
			}
		}
	}
};

/*--------------------------------------------------------------------*//*!
 * \brief Duplicate single pipeline recreation with no explicit cache
 *//*--------------------------------------------------------------------*/
static constexpr TestParams DUPLICATE_SINGLE_RECREATE_NO_CACHING =
{
	"duplicate_single_recreate_no_caching",
	"Duplicate single pipeline recreation with no explicit cache",
	TestParams::NO_CACHE,
	TestParams::IterationArray{
		TestParams::Iteration{
			// Iteration [0]: Force compilation of pipeline
			TestParams::Iteration::SINGLE_NORMAL,
			ValidatorArray{
				// Fail if result is not VK_SUCCESS
				checkResult<VK_SUCCESS>,
				// Fail if pipeline is not valid
				checkPipelineMustBeValid<0>
			}
		},
		TestParams::Iteration{
			// Iteration [1]: Request compilation of same pipeline without compile
			TestParams::Iteration::SINGLE_NOCOMPILE,
			ValidatorArray{
				// Warn if pipeline took too long
				checkElapsedTime<ELAPSED_TIME_FAST, QP_TEST_RESULT_QUALITY_WARNING>
			}
		}
	}
};

/*--------------------------------------------------------------------*//*!
 * \brief Duplicate single pipeline recreation using derivative pipelines
 *//*--------------------------------------------------------------------*/
static constexpr TestParams DUPLICATE_SINGLE_RECREATE_DERIVATIVE =
{
	"duplicate_single_recreate_derivative",
	"Duplicate single pipeline recreation using derivative pipelines",
	TestParams::DERIVATIVE_HANDLE,
	TestParams::IterationArray{
		TestParams::Iteration{
			// Iteration [0]: Force compilation of pipeline
			TestParams::Iteration::SINGLE_NORMAL,
			ValidatorArray{
				// Fail if result is not VK_SUCCESS
				checkResult<VK_SUCCESS>,
				// Fail if pipeline is not valid
				checkPipelineMustBeValid<0>
				}
			},
		TestParams::Iteration{
			// Iteration [1]: Request compilation of same pipeline without compile
			TestParams::Iteration::SINGLE_NOCOMPILE,
			ValidatorArray{
				// Warn if pipeline took too long
				checkElapsedTime<ELAPSED_TIME_FAST, QP_TEST_RESULT_QUALITY_WARNING>
			}
		}
	}
};

/*--------------------------------------------------------------------*//*!
 * \brief Single creation of never before seen pipeline without compile
 *//*--------------------------------------------------------------------*/
static constexpr TestParams SINGLE_PIPELINE_NO_COMPILE =
{
	"single_pipeline_no_compile",
	"Single creation of never before seen pipeline without compile",
	TestParams::NO_CACHE,
	TestParams::IterationArray{
		TestParams::Iteration{
			TestParams::Iteration::SINGLE_NOCOMPILE,
			ValidatorArray{
				// Warn if pipeline took too long
				checkElapsedTime<ELAPSED_TIME_IMMEDIATE, QP_TEST_RESULT_QUALITY_WARNING>
			}
		}
	}
};

/*--------------------------------------------------------------------*//*!
 * \brief Batch creation of duplicate pipelines with explicit caching
 *//*--------------------------------------------------------------------*/
static constexpr TestParams DUPLICATE_BATCH_PIPELINES_EXPLICIT_CACHE =
{
	"duplicate_batch_pipelines_explicit_cache",
	"Batch creation of duplicate pipelines with explicit caching",
	TestParams::EXPLICIT_CACHE,
	TestParams::IterationArray{
		TestParams::Iteration{
			TestParams::Iteration::BATCH_NOCOMPILE_COMPILE_NOCOMPILE,
			ValidatorArray{
				// Fail if pipeline[1] is not valid
				checkPipelineMustBeValid<1>,
				// Warn if result is not VK_ERROR_PIPELINE_COMPILE_REQUIRED_EXT
				checkResult<VK_ERROR_PIPELINE_COMPILE_REQUIRED_EXT, QP_TEST_RESULT_COMPATIBILITY_WARNING>,
				// Warn if pipelines[0] is not VK_NULL_HANDLE
				checkPipelineMustBeNull<0, QP_TEST_RESULT_COMPATIBILITY_WARNING>,
				// Warn if pipelines[2] is not valid
				checkPipelineMustBeValid<2, QP_TEST_RESULT_COMPATIBILITY_WARNING>
			}
		}
	}
};

/*--------------------------------------------------------------------*//*!
 * \brief Batch creation of duplicate pipelines with no caching
 *//*--------------------------------------------------------------------*/
static constexpr TestParams DUPLICATE_BATCH_PIPELINES_NO_CACHE =
{
	"duplicate_batch_pipelines_no_cache",
	"Batch creation of duplicate pipelines with no caching",
	TestParams::EXPLICIT_CACHE,
	TestParams::IterationArray{
		TestParams::Iteration{
			TestParams::Iteration::BATCH_NOCOMPILE_COMPILE_NOCOMPILE,
			ValidatorArray{
				// Fail if pipeline[1] is not valid
				checkPipelineMustBeValid<1>,
				// Warn if result is not VK_ERROR_PIPELINE_COMPILE_REQUIRED_EXT
				checkResult<VK_ERROR_PIPELINE_COMPILE_REQUIRED_EXT, QP_TEST_RESULT_COMPATIBILITY_WARNING>,
				// Warn if pipelines[0] is not VK_NULL_HANDLE
				checkPipelineMustBeNull<0, QP_TEST_RESULT_COMPATIBILITY_WARNING>
			}
		}
	}
};

/*--------------------------------------------------------------------*//*!
 * \brief Batch creation of duplicate pipelines with derivative pipeline index
 *//*--------------------------------------------------------------------*/
static constexpr TestParams DUPLICATE_BATCH_PIPELINES_DERIVATIVE_INDEX =
{
	"duplicate_batch_pipelines_derivative_index",
	"Batch creation of duplicate pipelines with derivative pipeline index",
	TestParams::DERIVATIVE_INDEX,
	TestParams::IterationArray{
		TestParams::Iteration{
			TestParams::Iteration::BATCH_NOCOMPILE_COMPILE_NOCOMPILE,
			ValidatorArray{
				// Fail if pipeline[1] is not valid
				checkPipelineMustBeValid<1>,
				// Warn if result is not VK_ERROR_PIPELINE_COMPILE_REQUIRED_EXT
				checkResult<VK_ERROR_PIPELINE_COMPILE_REQUIRED_EXT, QP_TEST_RESULT_COMPATIBILITY_WARNING>,
				// Warn if pipelines[0] is not VK_NULL_HANDLE
				checkPipelineMustBeNull<0, QP_TEST_RESULT_COMPATIBILITY_WARNING>
			}
		}
	}
};

/*--------------------------------------------------------------------*//*!
 * \brief Batch creation of pipelines with early return
 *//*--------------------------------------------------------------------*/
static constexpr TestParams BATCH_PIPELINES_EARLY_RETURN =
{
	"batch_pipelines_early_return",
	"Batch creation of pipelines with early return",
	TestParams::NO_CACHE,
	TestParams::IterationArray{
		TestParams::Iteration{
			TestParams::Iteration::BATCH_RETURN_COMPILE_NOCOMPILE,
			ValidatorArray{
				// fail if a valid pipeline follows the early-return failure
				checkPipelineNullAfterIndex<0>,
				// Warn if return was not immediate
				checkElapsedTime<ELAPSED_TIME_IMMEDIATE, QP_TEST_RESULT_QUALITY_WARNING>,
				// Warn if pipelines[0] is not VK_NULL_HANDLE
				checkPipelineMustBeNull<0, QP_TEST_RESULT_COMPATIBILITY_WARNING>,
				// Warn if result is not VK_ERROR_PIPELINE_COMPILE_REQUIRED_EXT
				checkResult<VK_ERROR_PIPELINE_COMPILE_REQUIRED_EXT, QP_TEST_RESULT_COMPATIBILITY_WARNING>
			}
		}
	}
};

/*--------------------------------------------------------------------*//*!
 * \brief Full array of test cases
 *//*--------------------------------------------------------------------*/
static constexpr TestParams TEST_CASES[] =
{
	SINGLE_PIPELINE_NO_COMPILE,
	BATCH_PIPELINES_EARLY_RETURN,
	DUPLICATE_SINGLE_RECREATE_EXPLICIT_CACHING,
	DUPLICATE_SINGLE_RECREATE_NO_CACHING,
	DUPLICATE_SINGLE_RECREATE_DERIVATIVE,
	DUPLICATE_BATCH_PIPELINES_EXPLICIT_CACHE,
	DUPLICATE_BATCH_PIPELINES_NO_CACHE,
	DUPLICATE_BATCH_PIPELINES_DERIVATIVE_INDEX
};

/*--------------------------------------------------------------------*//*!
 * \brief Variadic version of de::newMovePtr
 *//*--------------------------------------------------------------------*/
template <typename T, typename... args_t>
inline de::MovePtr<T> newMovePtr(args_t&&... args)
{
	return de::MovePtr<T>(new T(::std::forward<args_t>(args)...));
}

/*--------------------------------------------------------------------*//*!
 * \brief Make test group consisting of graphics pipeline tests
 *//*--------------------------------------------------------------------*/
void addGraphicsPipelineTests(TestCaseGroup& group)
{
	using namespace graphics_tests;

	auto tests = newMovePtr<TestCaseGroup>(
		group.getTestContext(), "graphics_pipelines", "Test pipeline creation cache control with graphics pipelines");

	for (const auto& params : TEST_CASES)
	{
		addFunctionCaseWithPrograms<const TestParams&>(
			tests.get(), params.name, params.description, checkSupport, initPrograms, testInstance, params);
	}

	group.addChild(tests.release());
}

/*--------------------------------------------------------------------*//*!
 * \brief Make test group consisting of compute pipeline tests
 *//*--------------------------------------------------------------------*/
void addComputePipelineTests(TestCaseGroup& group)
{
	using namespace compute_tests;

	auto tests = newMovePtr<TestCaseGroup>(
		group.getTestContext(), "compute_pipelines", "Test pipeline creation cache control with compute pipelines");

	for (const auto& params : TEST_CASES)
	{
		addFunctionCaseWithPrograms<const TestParams&>(
			tests.get(), params.name, params.description, checkSupport, initPrograms, testInstance, params);
	}

	group.addChild(tests.release());
}

} // namespace

/*--------------------------------------------------------------------*//*!
 * \brief Make pipeline creation cache control test group
 *//*--------------------------------------------------------------------*/
TestCaseGroup* createCacheControlTests(TestContext& testCtx)
{
	auto tests = newMovePtr<TestCaseGroup>(testCtx, "creation_cache_control", "pipeline creation cache control tests");

	addGraphicsPipelineTests(*tests);
	addComputePipelineTests(*tests);

	return tests.release();
}

} // namespace pipeline

} // namespace vkt
