/*------------------------------------------------------------------------
 * 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.getPipelineCreationCacheControlFeatures();
	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_FALSE,													// 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
