/*------------------------------------------------------------------------
 * Vulkan Conformance Tests
 * ------------------------
 *
 * Copyright (c) 2015 The Khronos Group Inc.
 * Copyright (c) 2018 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 Test cases for VK_KHR_shader_clock. Ensure that values are
          being read from the OpReadClockKHR OpCode.
 *//*--------------------------------------------------------------------*/

#include "vktShaderClockTests.hpp"
#include "vktTestCaseUtil.hpp"
#include "vktTestGroupUtil.hpp"
#include "vktShaderExecutor.hpp"

#include "vkQueryUtil.hpp"

#include "tcuStringTemplate.hpp"

#include "vktAtomicOperationTests.hpp"
#include "vktShaderExecutor.hpp"

#include "vkRefUtil.hpp"
#include "vkMemUtil.hpp"
#include "vkQueryUtil.hpp"
#include "vktTestGroupUtil.hpp"

#include "tcuTestLog.hpp"
#include "tcuStringTemplate.hpp"
#include "tcuResultCollector.hpp"

#include "deStringUtil.hpp"
#include "deSharedPtr.hpp"
#include "deRandom.hpp"
#include "deArrayUtil.hpp"

#include <cassert>
#include <string>

namespace vkt
{
namespace shaderexecutor
{

namespace
{

enum
{
	NUM_ELEMENTS = 32
};

enum clockType
{
	SUBGROUP = 0,
	DEVICE
};

enum bitType
{
	BIT_32 = 0,
	BIT_64
};

struct testType
{
	clockType   testClockType;
	bitType     testBitType;
	const char* testName;
};

static inline void* getPtrOfVar(deUint64& var)
{
	return &var;
}

using namespace vk;

class ShaderClockTestInstance : public TestInstance
{
public:
	ShaderClockTestInstance(Context& context, bool realtimeTest, const ShaderSpec& shaderSpec, glu::ShaderType shaderType)
		: TestInstance(context)
		, m_realtime_test(realtimeTest)
		, m_executor(createExecutor(m_context, shaderType, shaderSpec))
	{
		checkSupported();
	}

	virtual tcu::TestStatus iterate(void)
	{
		const deUint64 initValue = 0xcdcdcdcd;

		std::vector<deUint64>	outputs		(NUM_ELEMENTS, initValue);
		std::vector<void*>		outputPtr	(NUM_ELEMENTS, nullptr);

		std::transform(std::begin(outputs), std::end(outputs), std::begin(outputPtr), getPtrOfVar);

		m_executor->execute(NUM_ELEMENTS, nullptr, outputPtr.data());

		if (validateOutput(outputs))
			return tcu::TestStatus::pass("Pass");
		else
			return tcu::TestStatus::fail("Result comparison failed");
	}

private:
	void checkSupported(void)
	{
		m_context.requireDeviceExtension("VK_KHR_shader_clock");

		VkPhysicalDeviceShaderClockFeaturesKHR shaderClockFeatures;
		shaderClockFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_CLOCK_FEATURES_KHR;
		shaderClockFeatures.pNext = DE_NULL;

		VkPhysicalDeviceFeatures2 features;
		features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
		features.pNext = &shaderClockFeatures;

		m_context.getInstanceInterface().getPhysicalDeviceFeatures2(m_context.getPhysicalDevice(), &features);

		if (m_realtime_test && !shaderClockFeatures.shaderDeviceClock)
			TCU_THROW(NotSupportedError, "Shader device clock is not supported");

		if (!m_realtime_test && !shaderClockFeatures.shaderSubgroupClock)
			TCU_THROW(NotSupportedError, "Shader subgroup clock is not supported");
	}

	bool validateOutput(std::vector<deUint64>& outputs)
	{
		// The shader will write a 1 in the output if the clock did not increase
		return (outputs.size() == deUint64(std::count(std::begin(outputs), std::end(outputs), 0)));
	}

	const bool							m_realtime_test;
	de::UniquePtr<ShaderExecutor>		m_executor;
};

class ShaderClockCase : public TestCase
{
public:
	ShaderClockCase(tcu::TestContext& testCtx, testType operation, glu::ShaderType shaderType)
		: TestCase(testCtx, operation.testName, operation.testName)
		, m_operation(operation)
		, m_shaderSpec()
		, m_shaderType(shaderType)
	{
		initShaderSpec();
	}

	TestInstance* createInstance(Context& ctx) const
	{
		return new ShaderClockTestInstance(ctx, (m_operation.testClockType == DEVICE), m_shaderSpec, m_shaderType);
	}

	void initPrograms(vk::SourceCollections& programCollection) const
	{
		generateSources(m_shaderType, m_shaderSpec, programCollection);
	}

private:
	void initShaderSpec()
	{
		std::stringstream extensions;
		std::stringstream source;

		if (m_operation.testBitType == BIT_64)
		{
			extensions	<< "#extension GL_ARB_gpu_shader_int64 : require        \n";

			source << "uint64_t time1 = " << m_operation.testName << "();   \n";
			source << "uint64_t time2 = " << m_operation.testName << "();   \n";
			source << "out0  = uvec2(0, 0);                                 \n";
			source << "if (time1 > time2) {                                 \n";
			source << "    out0.x = 1;                                      \n";
			source << "}                                                    \n";
		}
		else
		{
			source << "uvec2 time1 = " << m_operation.testName << "();                      \n";
			source << "uvec2 time2 = " << m_operation.testName << "();                      \n";
			source << "out0  = uvec2(0, 0);                                                 \n";
			source << "if (time1.y > time2.y || (time1.y == time2.y && time1.x > time2.x)){ \n";
			source << "    out0.x = 1;                                                      \n";
			source << "}                                                                    \n";
		}

		if (m_operation.testClockType == DEVICE)
		{
			extensions << "#extension GL_EXT_shader_realtime_clock : require	\n";
		}
		else
		{
			extensions << "#extension GL_ARB_shader_clock : enable				\n";
		}

		std::map<std::string, std::string> specializations = {
			{	"EXTENSIONS",	extensions.str()    },
			{	"SOURCE",		source.str()        }
		};

		m_shaderSpec.globalDeclarations = tcu::StringTemplate("${EXTENSIONS}").specialize(specializations);
		m_shaderSpec.source             = tcu::StringTemplate("${SOURCE}	").specialize(specializations);

		m_shaderSpec.outputs.push_back(Symbol("out0", glu::VarType(glu::TYPE_UINT_VEC2, glu::PRECISION_HIGHP)));
	}

private:
	ShaderClockCase				(const ShaderClockCase&);
	ShaderClockCase& operator=	(const ShaderClockCase&);

	testType							m_operation;
	ShaderSpec							m_shaderSpec;
	glu::ShaderType						m_shaderType;
};

void addShaderClockTests (tcu::TestCaseGroup* testGroup)
{
	static glu::ShaderType stages[] =
	{
		glu::SHADERTYPE_VERTEX,
		glu::SHADERTYPE_FRAGMENT,
		glu::SHADERTYPE_COMPUTE
	};

	static testType operations[] =
    {
		{SUBGROUP, BIT_64, "clockARB"},
		{SUBGROUP, BIT_32, "clock2x32ARB" },
		{DEVICE,   BIT_64, "clockRealtimeEXT"},
		{DEVICE,   BIT_32, "clockRealtime2x32EXT"}
	};

	tcu::TestContext& testCtx = testGroup->getTestContext();

	for (size_t i = 0; i != DE_LENGTH_OF_ARRAY(stages); ++i)
	{
		const char* stageName = (stages[i] == glu::SHADERTYPE_VERTEX) ? ("vertex")
								: (stages[i] == glu::SHADERTYPE_FRAGMENT) ? ("fragment")
								: (stages[i] == glu::SHADERTYPE_COMPUTE) ? ("compute")
								: (DE_NULL);

		const std::string setName = std::string() + stageName;
		de::MovePtr<tcu::TestCaseGroup> stageGroupTest(new tcu::TestCaseGroup(testCtx, setName.c_str(), "Shader Clock Tests"));

		for (size_t j = 0; j != DE_LENGTH_OF_ARRAY(operations); ++j)
		{
			stageGroupTest->addChild(new ShaderClockCase(testCtx, operations[j], stages[i]));
		}

		testGroup->addChild(stageGroupTest.release());
	}
}

} // anonymous

tcu::TestCaseGroup* createShaderClockTests(tcu::TestContext& testCtx)
{
	return createTestGroup(testCtx, "shader_clock", "Shader Clock Tests", addShaderClockTests);
}

} // shaderexecutor
} // vkt
