• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2022 NVIDIA CORPORATION, Inc.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *	  http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  *//*!
20  * \file
21  * \brief  Vulkan SC VK_EXT_application_parameters Tests
22 *//*--------------------------------------------------------------------*/
23 
24 #include "vktApplicationParametersTests.hpp"
25 
26 #include "vktTestCaseUtil.hpp"
27 #include "vktCustomInstancesDevices.hpp"
28 #include "vkSafetyCriticalUtil.hpp"
29 #include "vkDeviceUtil.hpp"
30 #include "vkQueryUtil.hpp"
31 #include "tcuTestLog.hpp"
32 
33 namespace vkt
34 {
35 namespace sc
36 {
37 
38 using namespace vk;
39 
40 enum ApplicationParametersCreateType
41 {
42 	INSTANCE = 0,
43 	DEVICE
44 };
45 
46 enum ApplicationParametersTestType
47 {
48 	INVALID_VENDOR_ID = 0,
49 	INVALID_DEVICE_ID,
50 	INVALID_PARAM_KEY,
51 	INVALID_PARAM_VALUE,
52 	VALID
53 };
54 
55 struct TestParams
56 {
57 	ApplicationParametersCreateType	createType;
58 	ApplicationParametersTestType	testType;
59 };
60 
61 struct TestData
62 {
63 	TestParams	testParams;
64 	uint32_t	vendorId;
65 	uint32_t	deviceId;
66 	uint32_t	paramKey;
67 	uint64_t	paramValue;
68 	VkResult	expectedResult;
69 };
70 
readIDsFromDevice(Context & context,uint32_t & vendorId,uint32_t & deviceId)71 void readIDsFromDevice (Context& context, uint32_t& vendorId, uint32_t& deviceId)
72 {
73 	const InstanceInterface&	instanceInterface	= context.getInstanceInterface();
74 	VkPhysicalDevice			physicalDevice		= context.getPhysicalDevice();
75 	VkPhysicalDeviceProperties	properties;
76 
77 	instanceInterface.getPhysicalDeviceProperties(physicalDevice, &properties);
78 
79 	vendorId = properties.vendorID;
80 	deviceId = properties.deviceID;
81 }
82 
getDefaultTestData(Context & context,TestParams testParams)83 TestData getDefaultTestData (Context& context, TestParams testParams)
84 {
85 	TestData testData{};
86 	testData.testParams = testParams;
87 
88 	readIDsFromDevice(context, testData.vendorId, testData.deviceId);
89 
90 	switch(testParams.testType)
91 	{
92 		case INVALID_VENDOR_ID:
93 			testData.vendorId = 0x01234567;
94 			testData.expectedResult = VK_ERROR_INCOMPATIBLE_DRIVER;
95 			break;
96 
97 		case INVALID_DEVICE_ID:
98 			testData.deviceId = 0x01234567;
99 			testData.expectedResult = VK_ERROR_INCOMPATIBLE_DRIVER;
100 			break;
101 
102 		case INVALID_PARAM_KEY:
103 			testData.paramKey = 0x7fffffff;
104 			testData.expectedResult = VK_ERROR_INITIALIZATION_FAILED;
105 			break;
106 
107 		case INVALID_PARAM_VALUE:
108 		case VALID:
109 			// There is no default test case for the invalid param value and valid tests.
110 			// Vendors should provide their own test data for these tests in getTestDataList.
111 			break;
112 	}
113 
114 	if (testParams.createType == DEVICE && testParams.testType != VALID)
115 		testData.expectedResult = VK_ERROR_INITIALIZATION_FAILED;
116 
117 	return testData;
118 }
119 
getTestDataList(Context & context,TestParams testParams)120 std::vector<TestData> getTestDataList(Context& context, TestParams testParams)
121 {
122 	std::vector<TestData>		testDataList;
123 	uint32_t					vendorId;
124 	uint32_t					deviceId;
125 
126 	readIDsFromDevice(context, vendorId, deviceId);
127 
128 //#define VENDOR_PARAMS_ADDED 1
129 #if defined(VENDOR_PARAMS_ADDED)
130 	uint32_t validVendorID = vendorId;
131 	uint32_t validDeviceID = deviceId;
132 	uint32_t validInstanceParamKey = 0;		// TODO: provide valid instance parameter key
133 	uint64_t invalidInstanceParamValue = 0;	// TODO: provide invalid parameter value for <validInstanceParamKey>
134 	uint64_t validInstanceParamValue = 0;	// TODO: provide valid parameter value for <validInstanceParamKey>
135 	uint32_t validDeviceParamKey = 0;		// TODO: provide valid device parameter key
136 	uint64_t invalidDeviceParamValue = 0;	// TODO: provide invalid parameter value for <validDeviceParamKey>
137 	uint64_t validDeviceParamValue = 0;		// TODO: provide valid parameter value for <validDeviceParamKey>
138 #endif
139 
140 	const std::vector<TestData> vendorTestDataList =
141 	{
142 		//	The invalid param value and valid tests need to use vendor-specific application
143 		//	parameter keys and values. In order to have full test coverage, vendors should
144 		//	provide their own test data for the invalid param value and valid tests here.
145 		//
146 #if defined(VENDOR_PARAMS_ADDED)
147 		{
148 			{ INSTANCE, INVALID_PARAM_VALUE },
149 			validVendorID,
150 			validDeviceID,
151 			validInstanceParamKey,
152 			invalidInstanceParamValue,
153 			VK_ERROR_INITIALIZATION_FAILED
154 		},
155 		{
156 			{ INSTANCE, VALID },
157 			validVendorID,
158 			validDeviceID,
159 			validInstanceParamKey,
160 			validInstanceParamValue,
161 			VK_SUCCESS
162 		},
163 		{
164 			{ DEVICE, INVALID_PARAM_VALUE },
165 			validVendorID,
166 			validDeviceID,
167 			validDeviceParamKey,
168 			invalidDeviceParamValue,
169 			VK_ERROR_INITIALIZATION_FAILED
170 		},
171 		{
172 			{ DEVICE, VALID },
173 			validVendorID,
174 			validDeviceID,
175 			validDeviceParamKey,
176 			validDeviceParamValue,
177 			VK_SUCCESS
178 		}
179 #endif // defined(VENDOR_PARAMS_ADDED)
180 	};
181 
182 	if (testParams.testType != INVALID_PARAM_VALUE && testParams.testType != VALID)
183 		testDataList.push_back(getDefaultTestData(context, testParams));
184 
185 	for (TestData vendorTestData : vendorTestDataList)
186 	{
187 		if (vendorTestData.testParams.createType == testParams.createType &&
188 			vendorTestData.testParams.testType == testParams.testType &&
189 			vendorTestData.vendorId == vendorId &&
190 			(vendorTestData.deviceId == 0 || vendorTestData.deviceId == deviceId))
191 		{
192 			testDataList.push_back(vendorTestData);
193 		}
194 	}
195 
196 	return testDataList;
197 }
198 
checkSupport(Context & context,TestParams testParams)199 void checkSupport (Context& context, TestParams testParams)
200 {
201 	const std::vector<VkExtensionProperties> supportedExtensions = enumerateInstanceExtensionProperties(context.getPlatformInterface(), DE_NULL);
202 
203 	if (!isExtensionStructSupported(supportedExtensions, RequiredExtension("VK_EXT_application_parameters")))
204 		TCU_THROW(NotSupportedError, "VK_EXT_application_parameters is not supported");
205 
206 	const std::vector<TestData> testDataList = getTestDataList(context, testParams);
207 
208 	if (testDataList.empty())
209 		TCU_THROW(TestError, "No test data available - please update vendorTestDataList");
210 }
211 
createDeviceTest(Context & context,TestParams testParams)212 tcu::TestStatus createDeviceTest (Context& context, TestParams testParams)
213 {
214 	tcu::TestLog&								log						= context.getTestContext().getLog();
215 	const PlatformInterface&					platformInterface		= context.getPlatformInterface();
216 	const CustomInstance						instance				(createCustomInstanceFromContext(context));
217 	const InstanceDriver&						instanceDriver			(instance.getDriver());
218 	const VkPhysicalDevice						physicalDevice			= chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
219 	const std::vector<TestData>					testDataList			= getTestDataList(context, testParams);
220 	const float									queuePriority			= 1.0f;
221 	VkDeviceObjectReservationCreateInfo			devObjectResCreateInfo	= resetDeviceObjectReservationCreateInfo();
222 	bool										testPassed				= true;
223 	const VkPhysicalDeviceVulkanSC10Features	sc10Features			=
224 	{
225 		VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_SC_1_0_FEATURES,	// sType;
226 		&devObjectResCreateInfo,									// pNext;
227 		VK_FALSE													// shaderAtomicInstructions;
228 	};
229 
230 	for (TestData testData : testDataList)
231 	{
232 		const VkApplicationParametersEXT appParams =
233 		{
234 			VK_STRUCTURE_TYPE_APPLICATION_PARAMETERS_EXT,
235 			&sc10Features,
236 			testData.vendorId,
237 			testData.deviceId,
238 			testData.paramKey,
239 			testData.paramValue
240 		};
241 
242 		const VkDeviceQueueCreateInfo deviceQueueCreateInfo =
243 		{
244 			VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,										// sType
245 			DE_NULL,																		// pNext
246 			(VkDeviceQueueCreateFlags)0u,													// flags
247 			0,																				// queueFamilyIndex;
248 			1,																				// queueCount;
249 			&queuePriority,																	// pQueuePriorities;
250 		};
251 
252 		VkDeviceCreateInfo deviceCreateInfo =
253 		{
254 			VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,											// sType;
255 			&appParams,																		// pNext;
256 			(VkDeviceCreateFlags)0u,														// flags
257 			1,																				// queueRecordCount;
258 			&deviceQueueCreateInfo,															// pRequestedQueues;
259 			0,																				// layerCount;
260 			DE_NULL,																		// ppEnabledLayerNames;
261 			0,																				// extensionCount;
262 			DE_NULL,																		// ppEnabledExtensionNames;
263 			DE_NULL,																		// pEnabledFeatures;
264 		};
265 
266 		log << tcu::TestLog::Message << "Creating device with application parameters: " << appParams << tcu::TestLog::EndMessage;
267 
268 		VkDevice		device		= (VkDevice)0;
269 		const VkResult	result		= instanceDriver.createDevice(physicalDevice, &deviceCreateInfo, DE_NULL, &device);
270 
271 		if (device)
272 		{
273 			const DeviceDriver deviceIface(platformInterface, instance, device);
274 			deviceIface.destroyDevice(device, DE_NULL/*pAllocator*/);
275 		}
276 
277 		log << tcu::TestLog::Message << "Device creation returned with " + de::toString(getResultName(result)) +
278 			" (expecting " + de::toString(getResultName(testData.expectedResult)) + ")" << tcu::TestLog::EndMessage;
279 
280 		if (result != testData.expectedResult)
281 			testPassed = false;
282 	}
283 
284 	if (testPassed)
285 		return tcu::TestStatus::pass("Pass");
286 	else
287 		return tcu::TestStatus::fail("Fail");
288 }
289 
createInstanceTest(Context & context,TestParams testParams)290 tcu::TestStatus createInstanceTest (Context& context, TestParams testParams)
291 {
292 	tcu::TestLog&				log					= context.getTestContext().getLog();
293 	const PlatformInterface&	platformInterface	= context.getPlatformInterface();
294 	const std::vector<TestData>	testDataList		= getTestDataList(context, testParams);
295 	bool						testPassed			= true;
296 
297 	for (TestData testData : testDataList)
298 	{
299 		const VkApplicationParametersEXT appParams
300 		{
301 			VK_STRUCTURE_TYPE_APPLICATION_PARAMETERS_EXT,
302 			DE_NULL,
303 			testData.vendorId,
304 			testData.deviceId,
305 			testData.paramKey,
306 			testData.paramValue
307 		};
308 
309 		const VkApplicationInfo appInfo =
310 		{
311 			VK_STRUCTURE_TYPE_APPLICATION_INFO,		// VkStructureType				sType;
312 			&appParams,								// const void*					pNext;
313 			"appName",								// const char*					pAppName;
314 			0u,										// deUint32						appVersion;
315 			"engineName",							// const char*					pEngineName;
316 			0u,										// deUint32						engineVersion;
317 			context.getUsedApiVersion(),			// deUint32						apiVersion;
318 		};
319 
320 		const VkInstanceCreateInfo instanceCreateInfo =
321 		{
322 			VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,	// VkStructureType				sType;
323 			DE_NULL,								// const void*					pNext;
324 			(VkInstanceCreateFlags)0u,				// VkInstanceCreateFlags		flags;
325 			&appInfo,								// const VkApplicationInfo*		pAppInfo;
326 			0u,										// deUint32						layerCount;
327 			DE_NULL,								// const char*const*			ppEnabledLayernames;
328 			0u,										// deUint32						extensionCount;
329 			DE_NULL,								// const char*const*			ppEnabledExtensionNames;
330 		};
331 
332 		log << tcu::TestLog::Message << "Creating instance with application parameters: " << appParams << tcu::TestLog::EndMessage;
333 
334 		VkInstance				  instance			= (VkInstance)0;
335 		const VkResult			  result			= platformInterface.createInstance(&instanceCreateInfo, DE_NULL/*pAllocator*/, &instance);
336 
337 		if (instance)
338 		{
339 			const InstanceDriver instanceIface(platformInterface, instance);
340 			instanceIface.destroyInstance(instance, DE_NULL/*pAllocator*/);
341 		}
342 
343 		log << tcu::TestLog::Message << "Instance creation returned with " + de::toString(getResultName(result)) +
344 			" (expecting " + de::toString(getResultName(testData.expectedResult)) + ")" << tcu::TestLog::EndMessage;
345 
346 		if (result != testData.expectedResult)
347 			testPassed = false;
348 	}
349 
350 	if (testPassed)
351 		return tcu::TestStatus::pass("Pass");
352 	else
353 		return tcu::TestStatus::fail("Fail");
354 }
355 
createApplicationParametersTests(tcu::TestContext & testCtx)356 tcu::TestCaseGroup*	createApplicationParametersTests (tcu::TestContext& testCtx)
357 {
358 	de::MovePtr<tcu::TestCaseGroup> group(new tcu::TestCaseGroup(testCtx, "application_parameters", "Tests VK_EXT_application_parameters"));
359 
360 	const struct
361 	{
362 		ApplicationParametersCreateType	createType;
363 		const char*						name;
364 	} groups[2] =
365 	{
366 		{ INSTANCE,							"create_instance"	},
367 		{ DEVICE,							"create_device"		}
368 	};
369 
370 	const struct
371 	{
372 		ApplicationParametersTestType		testType;
373 		const char*							name;
374 	} tests[5] =
375 	{
376 		{ INVALID_VENDOR_ID,				"invalid_vendor_id"			},
377 		{ INVALID_DEVICE_ID,				"invalid_device_id"			},
378 		{ INVALID_PARAM_KEY,				"invalid_parameter_key"		},
379 		{ INVALID_PARAM_VALUE,				"invalid_parameter_value"	},
380 		{ VALID,							"valid"						}
381 	};
382 
383 	for (int groupIdx = 0; groupIdx < DE_LENGTH_OF_ARRAY(groups); ++groupIdx)
384 	{
385 		de::MovePtr<tcu::TestCaseGroup> createGroup(new tcu::TestCaseGroup(testCtx, groups[groupIdx].name, ""));
386 
387 		for (int testIdx = 0; testIdx < DE_LENGTH_OF_ARRAY(tests); ++testIdx)
388 		{
389 			TestParams testParams = { groups[groupIdx].createType, tests[testIdx].testType };
390 
391 			if (testParams.createType == INSTANCE)
392 				addFunctionCase(createGroup.get(), tests[testIdx].name, "", checkSupport, createInstanceTest, testParams);
393 			else
394 				addFunctionCase(createGroup.get(), tests[testIdx].name, "", checkSupport, createDeviceTest, testParams);
395 		}
396 
397 		group->addChild(createGroup.release());
398 	}
399 
400 	return group.release();
401 }
402 
403 } // sc
404 
405 } // vkt
406