1/*-------------------------------------------------------------------------
2* Vulkan Conformance Tests
3* ------------------------
4*
5* Copyright (c) 2019 Advanced Micro Devices, Inc.
6* Copyright (c) 2019 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_EXT_tooling_info tests
23*//*--------------------------------------------------------------------*/
24
25#include "vktApiToolingInfoTests.hpp"
26#include "vktTestGroupUtil.hpp"
27#include "vktTestCaseUtil.hpp"
28#include "vkQueryUtil.hpp"
29#include "vkStrUtil.hpp"
30#include "vkTypeUtil.hpp"
31#include "tcuTestLog.hpp"
32#include <iostream>
33#include <string>
34#include <vector>
35
36#include <string.h>
37
38using namespace vk;
39
40namespace vkt
41{
42namespace api
43{
44namespace
45{
46
47bool validateToolPurposeFlagBits(const VkToolPurposeFlagsEXT purposes)
48{
49	const VkToolPurposeFlagsEXT validPurposes =	VK_TOOL_PURPOSE_VALIDATION_BIT_EXT			|
50												VK_TOOL_PURPOSE_PROFILING_BIT_EXT			|
51												VK_TOOL_PURPOSE_TRACING_BIT_EXT				|
52												VK_TOOL_PURPOSE_ADDITIONAL_FEATURES_BIT_EXT	|
53												VK_TOOL_PURPOSE_MODIFYING_FEATURES_BIT_EXT	|
54												VK_TOOL_PURPOSE_DEBUG_REPORTING_BIT_EXT		|
55												VK_TOOL_PURPOSE_DEBUG_MARKERS_BIT_EXT;
56	return (purposes | validPurposes) == validPurposes;
57}
58
59void checkSupport (Context& context)
60{
61	context.requireDeviceFunctionality("VK_EXT_tooling_info");
62}
63
64tcu::TestStatus validateGetter(Context& context)
65{
66	tcu::TestLog& testLog = context.getTestContext().getLog();
67
68	VkResult result		= VK_SUCCESS;
69	deUint32 toolCount	= 0;
70
71	result = context.getInstanceInterface().getPhysicalDeviceToolProperties(context.getPhysicalDevice(), &toolCount, DE_NULL);
72
73	if(result != VK_SUCCESS)
74	{
75		testLog << tcu::TestLog::Message << "getPhysicalDeviceToolPropertiesEXT wrong result code" << tcu::TestLog::EndMessage;
76		return tcu::TestStatus::fail("Fail");
77	}
78
79	if (toolCount > 0)
80	{
81		deUint32 toolCountSecondCall = toolCount;
82
83		std::vector<VkPhysicalDeviceToolPropertiesEXT>	deviceToolPropertiesEXTArray(toolCountSecondCall);
84
85		for (size_t toolNdx = 0; toolNdx < deviceToolPropertiesEXTArray.size(); ++toolNdx)
86		{
87			deviceToolPropertiesEXTArray[toolNdx].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TOOL_PROPERTIES_EXT;
88		}
89
90		result = context.getInstanceInterface().getPhysicalDeviceToolProperties(context.getPhysicalDevice(), &toolCountSecondCall, &deviceToolPropertiesEXTArray[0]);
91
92		if (result != VK_SUCCESS)
93		{
94			testLog << tcu::TestLog::Message << "getPhysicalDeviceToolPropertiesEXT wrong result code" << tcu::TestLog::EndMessage;
95			return tcu::TestStatus::fail("Fail");
96		}
97
98		if (toolCountSecondCall != toolCount)
99		{
100			testLog << tcu::TestLog::Message << "Got different tools count on the second call" << tcu::TestLog::EndMessage;
101			return tcu::TestStatus::fail("Fail");
102		}
103
104		toolCountSecondCall++;
105
106		deviceToolPropertiesEXTArray.resize(toolCountSecondCall);
107
108		for (size_t toolNdx = 0; toolNdx < deviceToolPropertiesEXTArray.size(); ++toolNdx)
109		{
110			deviceToolPropertiesEXTArray[toolNdx].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TOOL_PROPERTIES_EXT;
111		}
112
113		result = context.getInstanceInterface().getPhysicalDeviceToolProperties(context.getPhysicalDevice(), &toolCountSecondCall, &deviceToolPropertiesEXTArray[0]);
114
115		if (result != VK_SUCCESS)
116		{
117			testLog << tcu::TestLog::Message << "getPhysicalDeviceToolPropertiesEXT wrong result code" << tcu::TestLog::EndMessage;
118			return tcu::TestStatus::fail("Fail");
119		}
120
121		if (toolCountSecondCall != toolCount)
122		{
123			testLog << tcu::TestLog::Message << "Bigger array causes an error" << tcu::TestLog::EndMessage;
124			return tcu::TestStatus::fail("Fail");
125		}
126
127		toolCountSecondCall = 0;
128
129		result = context.getInstanceInterface().getPhysicalDeviceToolProperties(context.getPhysicalDevice(), &toolCountSecondCall, &deviceToolPropertiesEXTArray[0]);
130
131		if (result != VK_INCOMPLETE)
132		{
133			testLog << tcu::TestLog::Message << "getPhysicalDeviceToolPropertiesEXT wrong result code" << tcu::TestLog::EndMessage;
134			return tcu::TestStatus::fail("Fail");
135		}
136
137		if (toolCountSecondCall != 0)
138		{
139			testLog << tcu::TestLog::Message << "Zero array causes an error" << tcu::TestLog::EndMessage;
140			return tcu::TestStatus::fail("Fail");
141		}
142	}
143
144	if (toolCount > 1)
145	{
146		deUint32 toolCountSecondCall = toolCount / 2;
147
148		std::vector<VkPhysicalDeviceToolPropertiesEXT>	deviceToolPropertiesEXTArray(toolCountSecondCall);
149
150		for (size_t toolNdx = 0; toolNdx < deviceToolPropertiesEXTArray.size(); ++toolNdx)
151		{
152			deviceToolPropertiesEXTArray[toolNdx].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TOOL_PROPERTIES_EXT;
153		}
154
155		result = context.getInstanceInterface().getPhysicalDeviceToolProperties(context.getPhysicalDevice(), &toolCountSecondCall, &deviceToolPropertiesEXTArray[0]);
156
157		if (result != VK_INCOMPLETE)
158		{
159			testLog << tcu::TestLog::Message << "getPhysicalDeviceToolPropertiesEXT wrong result code" << tcu::TestLog::EndMessage;
160			return tcu::TestStatus::fail("Fail");
161		}
162
163		if (toolCountSecondCall != (toolCount / 2))
164		{
165			testLog << tcu::TestLog::Message << "Smaller array causes an error" << tcu::TestLog::EndMessage;
166			return tcu::TestStatus::fail("Fail");
167		}
168	}
169
170	return tcu::TestStatus::pass("Pass");
171}
172
173tcu::TestStatus validateToolsProperties (Context& context)
174{
175	tcu::TestLog& testLog = context.getTestContext().getLog();
176
177	bool	 result		= true;
178	deUint32 toolCount	= 0;
179
180	VK_CHECK(context.getInstanceInterface().getPhysicalDeviceToolProperties(context.getPhysicalDevice(), &toolCount, DE_NULL));
181
182	if (toolCount > 0)
183	{
184		std::vector<VkPhysicalDeviceToolPropertiesEXT>	deviceToolPropertiesEXTArray(toolCount);
185
186		for (size_t toolNdx = 0; toolNdx < deviceToolPropertiesEXTArray.size(); ++toolNdx)
187		{
188			deviceToolPropertiesEXTArray[toolNdx].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TOOL_PROPERTIES_EXT;
189		}
190
191		VK_CHECK(context.getInstanceInterface().getPhysicalDeviceToolProperties(context.getPhysicalDevice(), &toolCount, &deviceToolPropertiesEXTArray[0]));
192
193		for (deUint32 i = 0; i < toolCount; ++i)
194		{
195			size_t nameSize		= strnlen(deviceToolPropertiesEXTArray[i].name, VK_MAX_EXTENSION_NAME_SIZE);
196			size_t versionSize	= strnlen(deviceToolPropertiesEXTArray[i].version, VK_MAX_EXTENSION_NAME_SIZE);
197			size_t descSize		= strnlen(deviceToolPropertiesEXTArray[i].description, VK_MAX_DESCRIPTION_SIZE);
198			size_t layerSize	= strnlen(deviceToolPropertiesEXTArray[i].layer, VK_MAX_EXTENSION_NAME_SIZE);
199
200			result = result && (deviceToolPropertiesEXTArray[i].sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TOOL_PROPERTIES_EXT);
201			result = result && validateToolPurposeFlagBits(deviceToolPropertiesEXTArray[i].purposes);
202			result = result && ((nameSize > 0)		&& (nameSize < VK_MAX_EXTENSION_NAME_SIZE));
203			result = result && ((versionSize > 0)	&& (versionSize < VK_MAX_EXTENSION_NAME_SIZE));
204			result = result && ((descSize > 0)		&& (descSize < VK_MAX_DESCRIPTION_SIZE));
205			result = result && ((layerSize == 0)	|| (layerSize < VK_MAX_EXTENSION_NAME_SIZE));
206
207			if (result == false)
208			{
209				testLog << tcu::TestLog::Message << "Tool validation failed" << tcu::TestLog::EndMessage;
210				testLog << tcu::TestLog::Message << "Tool name: " << deviceToolPropertiesEXTArray[i].name << tcu::TestLog::EndMessage;
211				testLog << tcu::TestLog::Message << "Version: " << deviceToolPropertiesEXTArray[i].version << tcu::TestLog::EndMessage;
212				testLog << tcu::TestLog::Message << "Description: " << deviceToolPropertiesEXTArray[i].description << tcu::TestLog::EndMessage;
213				testLog << tcu::TestLog::Message << "Purposes: " << getToolPurposeFlagsStr(deviceToolPropertiesEXTArray[i].purposes) << tcu::TestLog::EndMessage;
214				if (layerSize > 0)
215				{
216					testLog << tcu::TestLog::Message << "Corresponding Layer: " << deviceToolPropertiesEXTArray[i].layer << tcu::TestLog::EndMessage;
217				}
218				break;
219			}
220		}
221	}
222
223	if (result)
224	{
225		return tcu::TestStatus::pass("Pass");
226	}
227	else
228	{
229		return tcu::TestStatus::fail("Fail");
230	}
231}
232
233void createTestCases (tcu::TestCaseGroup* group)
234{
235	addFunctionCase(group, "validate_getter", checkSupport, validateGetter);
236	addFunctionCase(group, "validate_tools_properties",	checkSupport, validateToolsProperties);
237}
238
239} // anonymous
240
241tcu::TestCaseGroup*	createToolingInfoTests(tcu::TestContext& testCtx)
242{
243	return createTestGroup(testCtx, "tooling_info", createTestCases);
244}
245
246} // api
247} // vkt
248