1/*-------------------------------------------------------------------------
2* Vulkan Conformance Tests
3* ------------------------
4*
5* Copyright (c) 2018 Advanced Micro Devices, Inc.
6* Copyright (c) 2018 The Khronos Group Inc.
7*
8* Licensed under the Apache License, Version 2.0 (the "License");
9* you may not use this file except in compliance with the License.
10* You may obtain a copy of the License at
11*
12*      http://www.apache.org/licenses/LICENSE-2.0
13*
14* Unless required by applicable law or agreed to in writing, software
15* distributed under the License is distributed on an "AS IS" BASIS,
16* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17* See the License for the specific language governing permissions and
18* limitations under the License.
19*
20*//*!
21* \file
22* \brief VK_KHR_driver_properties tests
23*//*--------------------------------------------------------------------*/
24
25#include "vktApiDriverPropertiesTests.hpp"
26#include "vktTestGroupUtil.hpp"
27#include "vktTestCaseUtil.hpp"
28#include "vkQueryUtil.hpp"
29#include "vkTypeUtil.hpp"
30#include "vkKnownDriverIds.inl"
31
32using namespace vk;
33
34namespace vkt
35{
36namespace api
37{
38namespace
39{
40
41enum TestType
42{
43	TEST_TYPE_DRIVER_ID_MATCH			= 0,
44	TEST_TYPE_NAME_IS_NOT_EMPTY,
45	TEST_TYPE_NAME_ZERO_TERMINATED,
46	TEST_TYPE_INFO_ZERO_TERMINATED,
47	TEST_TYPE_VERSION,
48};
49
50DE_INLINE bool isNullTerminated(const char* str, const deUint32 maxSize)
51{
52	return deStrnlen(str, maxSize) < maxSize;
53}
54
55DE_INLINE bool operator==(const VkConformanceVersion& a, const VkConformanceVersion& b)
56{
57	return ((a.major == b.major)		&&
58			(a.minor == b.minor)		&&
59			(a.subminor == b.subminor)	&&
60			(a.patch == b.patch));
61}
62
63void checkSupport (Context& context, const TestType config)
64{
65	DE_UNREF(config);
66	context.requireDeviceFunctionality("VK_KHR_driver_properties");
67}
68
69void testDriverMatch (const VkPhysicalDeviceDriverProperties& deviceDriverProperties)
70{
71	for (deUint32 driverNdx = 0; driverNdx < DE_LENGTH_OF_ARRAY(driverIds); driverNdx++)
72	{
73		if (deviceDriverProperties.driverID == driverIds[driverNdx].id)
74			return;
75	}
76
77	TCU_FAIL("Driver ID did not match any known driver");
78}
79
80void testNameIsNotEmpty (const VkPhysicalDeviceDriverProperties& deviceDriverProperties)
81{
82	if (deviceDriverProperties.driverName[0] == 0)
83		TCU_FAIL("Driver name is empty");
84}
85
86void testNameZeroTerminated (const VkPhysicalDeviceDriverProperties& deviceDriverProperties)
87{
88	if (!isNullTerminated(deviceDriverProperties.driverName, VK_MAX_DRIVER_NAME_SIZE))
89		TCU_FAIL("Driver name is not a null-terminated string");
90}
91
92void testInfoZeroTerminated (const VkPhysicalDeviceDriverProperties& deviceDriverProperties)
93{
94	if (!isNullTerminated(deviceDriverProperties.driverInfo, VK_MAX_DRIVER_INFO_SIZE))
95		TCU_FAIL("Driver info is not a null-terminated string");
96}
97
98void testVersion (const VkPhysicalDeviceDriverProperties& deviceDriverProperties, deUint32 usedApiVersion)
99{
100
101#include "vkKnownConformanceVersions.inl"
102
103	const deUint32 apiMajorVersion = VK_API_VERSION_MAJOR(usedApiVersion);
104	const deUint32 apiMinorVersion = VK_API_VERSION_MINOR(usedApiVersion);
105
106	if (deviceDriverProperties.conformanceVersion.major < apiMajorVersion ||
107		(deviceDriverProperties.conformanceVersion.major == apiMajorVersion &&
108		 deviceDriverProperties.conformanceVersion.minor < apiMinorVersion))
109	{
110		TCU_FAIL("Wrong driver conformance version (older than used API version)");
111	}
112
113	for (const VkConformanceVersion*	pConformanceVersion  = knownConformanceVersions;
114										pConformanceVersion != DE_ARRAY_END(knownConformanceVersions);
115									  ++pConformanceVersion)
116	{
117		if (deviceDriverProperties.conformanceVersion == *pConformanceVersion)
118			return;
119	}
120
121	TCU_FAIL("Wrong driver conformance version (not known)");
122}
123
124tcu::TestStatus testQueryProperties (Context& context, const TestType testType)
125{
126	// Query the driver properties
127	const VkPhysicalDevice				physDevice			= context.getPhysicalDevice();
128	const int							memsetPattern		= 0xaa;
129	VkPhysicalDeviceProperties2			deviceProperties2;
130	VkPhysicalDeviceDriverProperties	deviceDriverProperties;
131
132	deMemset(&deviceDriverProperties, memsetPattern, sizeof(deviceDriverProperties));
133	deviceDriverProperties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES;
134	deviceDriverProperties.pNext = DE_NULL;
135
136	deMemset(&deviceProperties2, memsetPattern, sizeof(deviceProperties2));
137	deviceProperties2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
138	deviceProperties2.pNext = &deviceDriverProperties;
139
140	context.getInstanceInterface().getPhysicalDeviceProperties2(physDevice, &deviceProperties2);
141
142	// Verify the returned values
143	switch (testType)
144	{
145		case TEST_TYPE_DRIVER_ID_MATCH:			testDriverMatch			(deviceDriverProperties);								break;
146		case TEST_TYPE_NAME_IS_NOT_EMPTY:		testNameIsNotEmpty		(deviceDriverProperties);								break;
147		case TEST_TYPE_NAME_ZERO_TERMINATED:	testNameZeroTerminated	(deviceDriverProperties);								break;
148		case TEST_TYPE_INFO_ZERO_TERMINATED:	testInfoZeroTerminated	(deviceDriverProperties);								break;
149		case TEST_TYPE_VERSION:					testVersion				(deviceDriverProperties, context.getUsedApiVersion());	break;
150		default:								TCU_THROW(InternalError, "Unknown test type specified");
151	}
152
153	return tcu::TestStatus::pass("Pass");
154}
155
156void createTestCases (tcu::TestCaseGroup* group)
157{
158	addFunctionCase(group, "driver_id_match",			checkSupport,	testQueryProperties,	TEST_TYPE_DRIVER_ID_MATCH);
159	addFunctionCase(group, "name_is_not_empty",		checkSupport,	testQueryProperties,	TEST_TYPE_NAME_IS_NOT_EMPTY);
160	addFunctionCase(group, "name_zero_terminated",	checkSupport,	testQueryProperties,	TEST_TYPE_NAME_ZERO_TERMINATED);
161	addFunctionCase(group, "info_zero_terminated",	checkSupport,	testQueryProperties,	TEST_TYPE_INFO_ZERO_TERMINATED);
162	addFunctionCase(group, "conformance_version",		checkSupport,	testQueryProperties,	TEST_TYPE_VERSION);
163}
164
165} // anonymous
166
167tcu::TestCaseGroup*	createDriverPropertiesTests(tcu::TestContext& testCtx)
168{
169	return createTestGroup(testCtx, "driver_properties", createTestCases);
170}
171
172} // api
173} // vkt
174