/*------------------------------------------------------------------------
 * 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;

// Disable formatting on this next block for readability
// clang-format off
/*--------------------------------------------------------------------*//*!
 * \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::NO_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
};
// clang-format on

/*--------------------------------------------------------------------*//*!
 * \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
