/*-------------------------------------------------------------------------
* Vulkan Conformance Tests
* ------------------------
*
* Copyright (c) 2018 Advanced Micro Devices, Inc.
* Copyright (c) 2018 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 VK_KHR_driver_properties tests
*//*--------------------------------------------------------------------*/

#include "vktApiDriverPropertiesTests.hpp"
#include "vktTestGroupUtil.hpp"
#include "vktTestCaseUtil.hpp"
#include "vkQueryUtil.hpp"
#include "vkTypeUtil.hpp"

using namespace vk;

namespace vkt
{
namespace api
{
namespace
{

static const deUint32 knownDriverIds[] =
{
	// Specified in the Vulkan registry (vk.xml)
	1,	// author = "Advanced Micro Devices, Inc."   comment = "AMD proprietary driver"
	2,	// author = "Advanced Micro Devices, Inc."   comment = "AMD open-source driver"
	3,	// author = "Mesa open source project"       comment = "Mesa RADV driver"
	4,	// author = "NVIDIA Corporation"             comment = "NVIDIA proprietary driver"
	5,	// author = "Intel Corporation"              comment = "Intel proprietary Windows driver"
	6,	// author = "Intel Corporation"              comment = "Intel open-source Mesa driver"
	7,	// author = "Imagination Technologies"       comment = "Imagination proprietary driver"
	8,	// author = "Qualcomm Technologies, Inc."    comment = "Qualcomm proprietary driver"
	9,	// author = "Arm Limited"                    comment = "Arm proprietary driver"
};

static const VkConformanceVersionKHR knownConformanceVersions[] =
{
	makeConformanceVersionKHR(1, 1, 3, 0),
	makeConformanceVersionKHR(1, 1, 2, 3),
	makeConformanceVersionKHR(1, 1, 2, 2),
	makeConformanceVersionKHR(1, 1, 2, 1),
	makeConformanceVersionKHR(1, 1, 2, 0),
	makeConformanceVersionKHR(1, 1, 1, 3),
	makeConformanceVersionKHR(1, 1, 1, 2),
	makeConformanceVersionKHR(1, 1, 1, 1),
	makeConformanceVersionKHR(1, 1, 1, 0),
	makeConformanceVersionKHR(1, 1, 0, 3),
	makeConformanceVersionKHR(1, 0, 2, 6),
	makeConformanceVersionKHR(1, 0, 2, 5),
	makeConformanceVersionKHR(1, 0, 2, 4),
	makeConformanceVersionKHR(1, 0, 2, 3),
	makeConformanceVersionKHR(1, 0, 2, 2),
	makeConformanceVersionKHR(1, 0, 2, 1),
	makeConformanceVersionKHR(1, 0, 2, 0),
};

DE_INLINE bool isNullTerminated(const char* str, const deUint32 maxSize)
{
	return deStrnlen(str, maxSize) < maxSize;
}

DE_INLINE bool operator==(const VkConformanceVersionKHR& a, const VkConformanceVersionKHR& b)
{
	return ((a.major == b.major)		&&
			(a.minor == b.minor)		&&
			(a.subminor == b.subminor)	&&
			(a.patch == b.patch));
}

tcu::TestStatus testQueryProperties (Context& context)
{
	// Check extension support

	if (!isDeviceExtensionSupported(context.getUsedApiVersion(), context.getDeviceExtensions(), "VK_KHR_driver_properties"))
		TCU_THROW(NotSupportedError, "Unsupported extension: VK_KHR_driver_properties");

	// Query the driver properties

	const VkPhysicalDevice				physDevice			= context.getPhysicalDevice();
	const int							memsetPattern		= 0xaa;
	VkPhysicalDeviceProperties2			deviceProperties2;
	VkPhysicalDeviceDriverPropertiesKHR	deviceDriverProperties;

	deMemset(&deviceDriverProperties, memsetPattern, sizeof(deviceDriverProperties));
	deviceDriverProperties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES_KHR;
	deviceDriverProperties.pNext = DE_NULL;

	deMemset(&deviceProperties2, memsetPattern, sizeof(deviceProperties2));
	deviceProperties2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
	deviceProperties2.pNext = &deviceDriverProperties;

	context.getInstanceInterface().getPhysicalDeviceProperties2(physDevice, &deviceProperties2);

	// Verify the returned values

	bool match = false;

	for (const deUint32* pDriverId = knownDriverIds; (pDriverId != DE_ARRAY_END(knownDriverIds)) && !match; ++pDriverId)
	{
		if (deviceDriverProperties.driverID == *pDriverId)
		{
			match = true;

			if (!isNullTerminated(deviceDriverProperties.driverName, VK_MAX_DRIVER_NAME_SIZE_KHR))
				TCU_FAIL("Driver name is not a null-terminated string");

			if (deviceDriverProperties.driverName[0] == 0)
				TCU_FAIL("Driver name is empty");

			if (!isNullTerminated(deviceDriverProperties.driverInfo, VK_MAX_DRIVER_INFO_SIZE_KHR))
				TCU_FAIL("Driver info is not a null-terminated string");

			bool conformanceVersionMatch = false;

			for (const VkConformanceVersionKHR* pConformanceVersion  = knownConformanceVersions;
												pConformanceVersion != DE_ARRAY_END(knownConformanceVersions);
											  ++pConformanceVersion)
			{
				if (deviceDriverProperties.conformanceVersion == *pConformanceVersion)
				{
					conformanceVersionMatch = true;
					break;
				}
			}

			if (!conformanceVersionMatch)
				TCU_FAIL("Wrong driver conformance version");
		}
	}

	if (!match)
		TCU_FAIL("Driver ID did not match any known driver");

	return tcu::TestStatus::pass("Pass");
}

void createTestCases (tcu::TestCaseGroup* group)
{
	addFunctionCase(group, "properties", "Query VkPhysicalDeviceDriverPropertiesKHR and check its values", testQueryProperties);
}

} // anonymous

tcu::TestCaseGroup*	createDriverPropertiesTests(tcu::TestContext& testCtx)
{
	return createTestGroup(testCtx, "driver_properties", "VK_KHR_driver_properties tests", createTestCases);
}

} // api
} // vkt
