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

#include <amber/amber.h>

#include "tcuDefs.hpp"

#include "vkDefs.hpp"
#include "vkDeviceUtil.hpp"
#include "vktTestGroupUtil.hpp"
#include "vktAmberTestCase.hpp"
#include "vktSubgroupUniformControlFlowTests.hpp"
#include "vktTestGroupUtil.hpp"

namespace vkt
{
namespace subgroups
{
namespace
{

struct Case
{
	Case(const char*	b, const char* d,	bool sw,	bool use_ssc,	vk::VkShaderStageFlagBits s, vk::VkSubgroupFeatureFlagBits o) :
		basename(b),
		description(d),
		small_workgroups(sw),
		use_subgroup_size_control(use_ssc),
		stage(s)
	{
		operation = (vk::VkSubgroupFeatureFlagBits)(o | vk::VK_SUBGROUP_FEATURE_BASIC_BIT);
	}
	const char* basename;
	const char* description;
	bool small_workgroups;
	bool use_subgroup_size_control;
	vk::VkShaderStageFlagBits stage;
	vk::VkSubgroupFeatureFlagBits operation;
};

struct CaseGroup
{
	CaseGroup(const char*	the_data_dir, const char*	the_subdir) : data_dir(the_data_dir),	subdir(the_subdir) { }
	void add(const char*	basename,	const char*	description,	bool small_workgroups,	bool use_subgroup_size_control, vk::VkShaderStageFlagBits stage, vk::VkSubgroupFeatureFlagBits operation = vk::VK_SUBGROUP_FEATURE_BASIC_BIT)
	{
		cases.push_back(Case(basename, description, small_workgroups, use_subgroup_size_control, stage, operation));
	}

	const char*	data_dir;
	const char*	subdir;
	std::vector<Case>	cases;
};

class SubgroupUniformControlFlowTestCase : public cts_amber::AmberTestCase
{
public:
	SubgroupUniformControlFlowTestCase(tcu::TestContext&	testCtx,
									   const char*	name,
									   const char*	description,
									   const std::string&	readFilename,
									   bool	small_workgroups,
									   bool	use_subgroup_size_control,
									   vk::VkShaderStageFlagBits stage,
									   vk::VkSubgroupFeatureFlagBits operation) :
		cts_amber::AmberTestCase(testCtx, name, description, readFilename),
		m_small_workgroups(small_workgroups),
		m_use_subgroup_size_control(use_subgroup_size_control),
		m_stage(stage),
		m_operation(operation)
	{ }

	virtual void checkSupport(Context&	ctx) const;	// override
private:
	bool	m_small_workgroups;
	bool	m_use_subgroup_size_control;
	vk::VkShaderStageFlagBits	m_stage;
	vk::VkSubgroupFeatureFlagBits	m_operation;
};

void SubgroupUniformControlFlowTestCase::checkSupport(Context& ctx) const
{
	// Check required extensions.
	ctx.requireDeviceFunctionality("VK_KHR_shader_subgroup_uniform_control_flow");
	if (m_use_subgroup_size_control)
	{
		ctx.requireDeviceFunctionality("VK_EXT_subgroup_size_control");
	}

	vk::VkPhysicalDeviceSubgroupProperties subgroupProperties;
	subgroupProperties.sType = vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_PROPERTIES;
	subgroupProperties.pNext = DE_NULL;

	vk::VkPhysicalDeviceProperties2 properties2;
	properties2.sType = vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
	properties2.pNext = &subgroupProperties;

	ctx.getInstanceInterface().getPhysicalDeviceProperties2(ctx.getPhysicalDevice(), &properties2);

	vk::VkPhysicalDeviceSubgroupSizeControlFeaturesEXT subgroupSizeControlFeatures;
	subgroupSizeControlFeatures.sType = vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_FEATURES_EXT;
	subgroupSizeControlFeatures.pNext = DE_NULL;

	vk::VkPhysicalDeviceFeatures2 features2;
	features2.sType = vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
	features2.pNext = &subgroupSizeControlFeatures;

	ctx.getInstanceInterface().getPhysicalDeviceFeatures2(ctx.getPhysicalDevice(), &features2);

	// Check that the stage supports the required subgroup operations.
	if ((m_stage & subgroupProperties.supportedStages) == 0)
	{
		TCU_THROW(NotSupportedError, "Device does not support subgroup operations in this stage");
	}
	if ((m_operation & subgroupProperties.supportedOperations) != m_operation)
	{
		TCU_THROW(NotSupportedError, "Device does not support required operations");
	}

	// For the compute shader tests, there are variants for implementations
	// that support the subgroup size control extension and variants for those
	// that do not. It is expected that computeFullSubgroups must be set for
	// these tests if the extension is supported so tests are only supported
	// for the extension appropriate version.
	if (m_stage == vk::VK_SHADER_STAGE_COMPUTE_BIT)
	{
		if (m_use_subgroup_size_control)
		{
			if (subgroupSizeControlFeatures.computeFullSubgroups != VK_TRUE)
			{
				TCU_THROW(NotSupportedError, "Implementation does not support subgroup size control");
			}
		}
		else
		{
			if (subgroupSizeControlFeatures.computeFullSubgroups == VK_TRUE)
			{
				TCU_THROW(NotSupportedError, "These tests are not enabled for subgroup size control implementations");
			}
		}
	}

	// The are large and small variants of the tests. The large variants
	// require 256 invocations in a workgroup.
	if (!m_small_workgroups)
	{
		vk::VkPhysicalDeviceProperties properties;
		ctx.getInstanceInterface().getPhysicalDeviceProperties(ctx.getPhysicalDevice(), &properties);
		if (properties.limits.maxComputeWorkGroupInvocations < 256)
		{
			TCU_THROW(NotSupportedError, "Device supported fewer than 256 invocations per workgroup");
		}
	}
}

void addTestsForAmberFiles(tcu::TestCaseGroup* tests, CaseGroup group)
{
	tcu::TestContext&	testCtx = tests->getTestContext();
	const std::string	data_dir(group.data_dir);
	const std::string	subdir(group.subdir);
	const std::string	category = data_dir + "/" + subdir;
	std::vector<Case> cases(group.cases);

	for (unsigned i = 0; i < cases.size(); ++i)
	{
		const std::string file = std::string(cases[i].basename) + ".amber";
		std::string readFilename("vulkan/amber/");
		readFilename.append(category);
		readFilename.append("/");
		readFilename.append(file);
		SubgroupUniformControlFlowTestCase*	testCase =
			new SubgroupUniformControlFlowTestCase(testCtx,
													cases[i].basename,
													cases[i].description,
													readFilename,
													cases[i].small_workgroups,
													cases[i].use_subgroup_size_control,
													cases[i].stage,
													cases[i].operation);
		DE_ASSERT(testCase != DE_NULL);
		tests->addChild(testCase);
	}
}

} // anonymous

tcu::TestCaseGroup* createSubgroupUniformControlFlowTests(tcu::TestContext&	testCtx)
{
	// There are four main groups of tests. Each group runs the same set of base
	// shaders with minor variations. The groups are with or without compute full
	// subgroups and a larger or smaller number of invocations. For each group of
	// tests, shaders test either odd or even subgroups reconverge after
	// diverging, without reconverging the whole workgroup. For the _partial
	// tests, the workgroup is launched without a full final subgroup (not enough
	// invocations).
	//
	// It is assumed that if an implementation does not support the compute full
	// subgroups feature, that it will always launch full subgroups. Therefore,
	// any given implementation only runs half of the tests. Implementations that
	// do not support compute full subgroups cannot support the tests that enable
	// it, while implementations that do support the feature will (likely) not
	// pass the tests that do not enable the feature.

	de::MovePtr<tcu::TestCaseGroup>	uniformControlFlowTests(new	tcu::TestCaseGroup(testCtx,	"subgroup_uniform_control_flow", "VK_KHR_shader_subgroup_uniform_control_flow tests"));

	// Location of the Amber script files under data/vulkan/amber source tree.
	const char* data_dir = "subgroup_uniform_control_flow";
	const char*	large_dir = "large";
	const char*	small_dir = "small";
	const char*	large_control_dir = "large_control";
	const char* small_control_dir = "small_control";

	std::vector<bool> controls = {false, true};
	for (unsigned c = 0; c < controls.size(); ++c)
	{
		// Full subgroups.
		bool small = false;
		bool control = controls[c];
		vk::VkShaderStageFlagBits stage = vk::VK_SHADER_STAGE_COMPUTE_BIT;
		const char*	subdir = (control ? large_control_dir : large_dir);
		CaseGroup group(data_dir, subdir);
		group.add("subgroup_reconverge00", "if/else diverge", small, control, stage);
		group.add("subgroup_reconverge01", "do while diverge", small, control, stage);
		group.add("subgroup_reconverge02", "while true with break", small, control, stage);
		group.add("subgroup_reconverge03", "if/else diverge, volatile", small, control, stage);
		group.add("subgroup_reconverge04", "early return and if/else diverge", small, control, stage);
		group.add("subgroup_reconverge05", "early return and if/else volatile", small, control, stage);
		group.add("subgroup_reconverge06", "while true with volatile conditional break and early return", small, control, stage);
		group.add("subgroup_reconverge07", "while true return and break", small, control, stage);
		group.add("subgroup_reconverge08", "for loop atomics with conditional break", small, control, stage);
		group.add("subgroup_reconverge09", "diverge in for loop", small, control, stage);
		group.add("subgroup_reconverge10", "diverge in for loop and break", small, control, stage);
		group.add("subgroup_reconverge11", "diverge in for loop and continue", small, control, stage);
		group.add("subgroup_reconverge12", "early return, divergent switch", small, control, stage);
		group.add("subgroup_reconverge13", "early return, divergent switch more cases", small, control, stage);
		group.add("subgroup_reconverge14", "divergent switch, some subgroups terminate", small, control, stage);
		group.add("subgroup_reconverge15", "switch in switch", small, control, stage);
		group.add("subgroup_reconverge16", "for loop unequal iterations", small, control, stage);
		group.add("subgroup_reconverge17", "if/else with nested returns", small, control, stage);
		group.add("subgroup_reconverge18", "if/else subgroup all equal", small, control, stage, vk::VK_SUBGROUP_FEATURE_VOTE_BIT);
		group.add("subgroup_reconverge19", "if/else subgroup any nested return", small, control, stage, vk::VK_SUBGROUP_FEATURE_VOTE_BIT);
		group.add("subgroup_reconverge20", "deeply nested", small, control, stage);
		const char*	group_name = (control ? "large_full_control" : "large_full");
		uniformControlFlowTests->addChild(createTestGroup(testCtx, group_name,
														  "Large Full subgroups",
														  addTestsForAmberFiles, group));

		// Partial subgroup.
		group = CaseGroup(data_dir, subdir);
		group.add("subgroup_reconverge_partial00", "if/else diverge", small, control, stage);
		group.add("subgroup_reconverge_partial01", "do while diverge", small, control, stage);
		group.add("subgroup_reconverge_partial02", "while true with break", small, control, stage);
		group.add("subgroup_reconverge_partial03", "if/else diverge, volatile", small, control, stage);
		group.add("subgroup_reconverge_partial04", "early return and if/else diverge", small, control, stage);
		group.add("subgroup_reconverge_partial05", "early return and if/else volatile", small, control, stage);
		group.add("subgroup_reconverge_partial06", "while true with volatile conditional break and early return", small, control, stage);
		group.add("subgroup_reconverge_partial07", "while true return and break", small, control, stage);
		group.add("subgroup_reconverge_partial08", "for loop atomics with conditional break", small, control, stage);
		group.add("subgroup_reconverge_partial09", "diverge in for loop", small, control, stage);
		group.add("subgroup_reconverge_partial10", "diverge in for loop and break", small, control, stage);
		group.add("subgroup_reconverge_partial11", "diverge in for loop and continue", small, control, stage);
		group.add("subgroup_reconverge_partial12", "early return, divergent switch", small, control, stage);
		group.add("subgroup_reconverge_partial13", "early return, divergent switch more cases", small, control, stage);
		group.add("subgroup_reconverge_partial14", "divergent switch, some subgroups terminate", small, control, stage);
		group.add("subgroup_reconverge_partial15", "switch in switch", small, control, stage);
		group.add("subgroup_reconverge_partial16", "for loop unequal iterations", small, control, stage);
		group.add("subgroup_reconverge_partial17", "if/else with nested returns", small, control, stage);
		group.add("subgroup_reconverge_partial18", "if/else subgroup all equal", small, control, stage, vk::VK_SUBGROUP_FEATURE_VOTE_BIT);
		group.add("subgroup_reconverge_partial19", "if/else subgroup any nested return", small, control, stage, vk::VK_SUBGROUP_FEATURE_VOTE_BIT);
		group.add("subgroup_reconverge_partial20", "deeply nested", small, control, stage);
		group_name = (control ? "large_partial_control" : "large_partial");
		uniformControlFlowTests->addChild(createTestGroup(testCtx, group_name,
														  "Large Partial subgroups",
														  addTestsForAmberFiles, group));
	}

	for (unsigned c = 0; c < controls.size(); ++c)
	{
		// Full subgroups.
		bool small = true;
		bool control = controls[c];
		vk::VkShaderStageFlagBits stage = vk::VK_SHADER_STAGE_COMPUTE_BIT;
		const char*	subdir = (control ? small_control_dir : small_dir);
		CaseGroup group(data_dir, subdir);
		group.add("small_subgroup_reconverge00", "if/else diverge", small, control, stage);
		group.add("small_subgroup_reconverge01", "do while diverge", small, control, stage);
		group.add("small_subgroup_reconverge02", "while true with break", small, control, stage);
		group.add("small_subgroup_reconverge03", "if/else diverge, volatile", small, control, stage);
		group.add("small_subgroup_reconverge04", "early return and if/else diverge", small, control, stage);
		group.add("small_subgroup_reconverge05", "early return and if/else volatile", small, control, stage);
		group.add("small_subgroup_reconverge06", "while true with volatile conditional break and early return", small, control, stage);
		group.add("small_subgroup_reconverge07", "while true return and break", small, control, stage);
		group.add("small_subgroup_reconverge08", "for loop atomics with conditional break", small, control, stage);
		group.add("small_subgroup_reconverge09", "diverge in for loop", small, control, stage);
		group.add("small_subgroup_reconverge10", "diverge in for loop and break", small, control, stage);
		group.add("small_subgroup_reconverge11", "diverge in for loop and continue", small, control, stage);
		group.add("small_subgroup_reconverge12", "early return, divergent switch", small, control, stage);
		group.add("small_subgroup_reconverge13", "early return, divergent switch more cases", small, control, stage);
		group.add("small_subgroup_reconverge14", "divergent switch, some subgroups terminate", small, control, stage);
		group.add("small_subgroup_reconverge15", "switch in switch", small, control, stage);
		group.add("small_subgroup_reconverge16", "for loop unequal iterations", small, control, stage);
		group.add("small_subgroup_reconverge17", "if/else with nested returns", small, control, stage);
		group.add("small_subgroup_reconverge18", "if/else subgroup all equal", small, control, stage, vk::VK_SUBGROUP_FEATURE_VOTE_BIT);
		group.add("small_subgroup_reconverge19", "if/else subgroup any nested return", small, control, stage, vk::VK_SUBGROUP_FEATURE_VOTE_BIT);
		group.add("small_subgroup_reconverge20", "deeply nested", small, control, stage);
		const char*	group_name = (control ? "small_full_control" : "small_full");
		uniformControlFlowTests->addChild(createTestGroup(testCtx, group_name,
														  "Small Full subgroups",
														  addTestsForAmberFiles, group));

		// Partial subgroup.
		group = CaseGroup(data_dir, subdir);
		group.add("small_subgroup_reconverge_partial00", "if/else diverge", small, control, stage);
		group.add("small_subgroup_reconverge_partial01", "do while diverge", small, control, stage);
		group.add("small_subgroup_reconverge_partial02", "while true with break", small, control, stage);
		group.add("small_subgroup_reconverge_partial03", "if/else diverge, volatile", small, control, stage);
		group.add("small_subgroup_reconverge_partial04", "early return and if/else diverge", small, control, stage);
		group.add("small_subgroup_reconverge_partial05", "early return and if/else volatile", small, control, stage);
		group.add("small_subgroup_reconverge_partial06", "while true with volatile conditional break and early return", small, control, stage);
		group.add("small_subgroup_reconverge_partial07", "while true return and break", small, control, stage);
		group.add("small_subgroup_reconverge_partial08", "for loop atomics with conditional break", small, control, stage);
		group.add("small_subgroup_reconverge_partial09", "diverge in for loop", small, control, stage);
		group.add("small_subgroup_reconverge_partial10", "diverge in for loop and break", small, control, stage);
		group.add("small_subgroup_reconverge_partial11", "diverge in for loop and continue", small, control, stage);
		group.add("small_subgroup_reconverge_partial12", "early return, divergent switch", small, control, stage);
		group.add("small_subgroup_reconverge_partial13", "early return, divergent switch more cases", small, control, stage);
		group.add("small_subgroup_reconverge_partial14", "divergent switch, some subgroups terminate", small, control, stage);
		group.add("small_subgroup_reconverge_partial15", "switch in switch", small, control, stage);
		group.add("small_subgroup_reconverge_partial16", "for loop unequal iterations", small, control, stage);
		group.add("small_subgroup_reconverge_partial17", "if/else with nested returns", small, control, stage);
		group.add("small_subgroup_reconverge_partial18", "if/else subgroup all equal", small, control, stage, vk::VK_SUBGROUP_FEATURE_VOTE_BIT);
		group.add("small_subgroup_reconverge_partial19", "if/else subgroup any nested return", small, control, stage, vk::VK_SUBGROUP_FEATURE_VOTE_BIT);
		group.add("small_subgroup_reconverge_partial20", "deeply nested", small, control, stage);
		group_name = (control ? "small_partial_control" : "small_partial");
		uniformControlFlowTests->addChild(createTestGroup(testCtx, group_name,
														  "Small Partial subgroups",
														  addTestsForAmberFiles, group));
	}

	// Discard test
	CaseGroup group(data_dir, "discard");
	group.add("subgroup_reconverge_discard00", "discard test", true, false, vk::VK_SHADER_STAGE_FRAGMENT_BIT);
	uniformControlFlowTests->addChild(createTestGroup(testCtx, "discard",
														"Discard tests",
														addTestsForAmberFiles, group));

	return uniformControlFlowTests.release();
}

} // subgroups
} // vkt
