• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2021 The Khronos Group 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 fault handling tests
22 *//*--------------------------------------------------------------------*/
23 
24 #include "vktFaultHandlingTests.hpp"
25 
26 #include <set>
27 #include <vector>
28 #include <string>
29 
30 #include "vktTestCaseUtil.hpp"
31 #include "vkDeviceUtil.hpp"
32 #include "vkSafetyCriticalUtil.hpp"
33 #include "vktCustomInstancesDevices.hpp"
34 #include "tcuTestLog.hpp"
35 
36 namespace vkt
37 {
38 namespace sc
39 {
40 
41 using namespace vk;
42 
43 namespace
44 {
45 
46 enum FHFaultValue
47 {
48 	FHF_UNUSED = 0,
49 	FHF_NULL,
50 	FHF_ARRAY
51 };
52 
53 struct TestParams
54 {
55 	VkFaultQueryBehavior	queryBehaviour;
56 	FHFaultValue			faultValue;
57 };
58 
testGetFaultData(Context & context,TestParams testParams)59 tcu::TestStatus testGetFaultData (Context& context, TestParams testParams)
60 {
61 	const DeviceInterface&		vk							= context.getDeviceInterface();
62 	const VkDevice				device						= context.getDevice();
63 
64 	deUint32					maxQueryFaultCount			= context.getDeviceVulkanSC10Properties().maxQueryFaultCount;
65 
66 	VkBool32					unrecordedFaults			= VK_TRUE;
67 	deUint32					faultCount					= maxQueryFaultCount;
68 	std::vector<VkFaultData>	faults;
69 	for (deUint32 i = 0; i < maxQueryFaultCount; ++i)
70 	{
71 		faults.push_back
72 		(
73 			{
74 				VK_STRUCTURE_TYPE_FAULT_DATA,	// VkStructureType	sType;
75 				DE_NULL,						// void*			pNext;
76 				VK_FAULT_LEVEL_UNASSIGNED,		// VkFaultLevel		faultLevel;
77 				VK_FAULT_TYPE_UNASSIGNED,		// VkFaultType		faultType;
78 			}
79 		);
80 	}
81 	bool						isOK						= true;
82 	bool						faultsModified				= false;
83 	VkResult					result;
84 
85 	switch (testParams.faultValue)
86 	{
87 	case FHF_NULL:
88 		result = vk.getFaultData(device, testParams.queryBehaviour, &unrecordedFaults, &faultCount, DE_NULL);
89 
90 		if (result != VK_SUCCESS)
91 		{
92 			context.getTestContext().getLog() << tcu::TestLog::Message << "Result is not VK_SUCCESS" << tcu::TestLog::EndMessage;
93 			isOK = false;
94 		}
95 		if (unrecordedFaults != VK_FALSE)
96 		{
97 			context.getTestContext().getLog() << tcu::TestLog::Message << "unrecordedFaults is not VK_FALSE" << tcu::TestLog::EndMessage;
98 			isOK = false;
99 		}
100 		if (faultCount != 0u)
101 		{
102 			context.getTestContext().getLog() << tcu::TestLog::Message << "faultCount is not 0" << tcu::TestLog::EndMessage;
103 			isOK = false;
104 		}
105 		break;
106 	case FHF_ARRAY:
107 		result = vk.getFaultData(device, testParams.queryBehaviour, &unrecordedFaults, &faultCount, faults.data());
108 
109 		if (result != VK_SUCCESS)
110 		{
111 			context.getTestContext().getLog() << tcu::TestLog::Message << "Result is not VK_SUCCESS" << tcu::TestLog::EndMessage;
112 			isOK = false;
113 		}
114 		if (unrecordedFaults != VK_FALSE)
115 		{
116 			context.getTestContext().getLog() << tcu::TestLog::Message << "unrecordedFaults is not VK_FALSE" << tcu::TestLog::EndMessage;
117 			isOK = false;
118 		}
119 		if (faultCount != 0u)
120 		{
121 			context.getTestContext().getLog() << tcu::TestLog::Message << "faultCount is not 0" << tcu::TestLog::EndMessage;
122 			isOK = false;
123 		}
124 		for (deUint32 i = 0; i < maxQueryFaultCount; ++i)
125 			if (faults[i].faultLevel != VK_FAULT_LEVEL_UNASSIGNED || faults[i].faultType != VK_FAULT_TYPE_UNASSIGNED)
126 				faultsModified = true;
127 		if (faultsModified)
128 		{
129 			context.getTestContext().getLog() << tcu::TestLog::Message << "pFaults have been modified" << tcu::TestLog::EndMessage;
130 			isOK = false;
131 		}
132 		break;
133 	default:
134 		TCU_THROW(InternalError, "Unrecognized fault type");
135 	}
136 
137 	return isOK ? tcu::TestStatus::pass("Pass") : tcu::TestStatus::fail("Fail");
138 }
139 
testFaultCallback(VkBool32 incompleteFaultData,deUint32 faultCount,VkFaultData * pFaultData)140 void		testFaultCallback (VkBool32			incompleteFaultData,
141 							   deUint32			faultCount,
142 							   VkFaultData*		pFaultData)
143 {
144 	DE_UNREF(incompleteFaultData);
145 	DE_UNREF(faultCount);
146 	DE_UNREF(pFaultData);
147 }
148 
149 struct FaultCallbackInfoTestParams
150 {
151 	bool allocateFaultData;
152 };
153 
testCreateDeviceWithFaultCallbackInfo(Context & context,FaultCallbackInfoTestParams testParams)154 tcu::TestStatus testCreateDeviceWithFaultCallbackInfo (Context& context, FaultCallbackInfoTestParams testParams)
155 {
156 	const CustomInstance				instance				(createCustomInstanceFromContext(context));
157 	const InstanceDriver&				instanceDriver			(instance.getDriver());
158 	const VkPhysicalDevice				physicalDevice			= chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
159 
160 	void*								pNext					= DE_NULL;
161 
162 	VkDeviceObjectReservationCreateInfo	memReservationInfo		= context.getTestContext().getCommandLine().isSubProcess() ? context.getResourceInterface()->getStatMax() : resetDeviceObjectReservationCreateInfo();
163 	memReservationInfo.pNext									= pNext;
164 	pNext														= &memReservationInfo;
165 
166 	VkPhysicalDeviceVulkanSC10Features	sc10Features			= createDefaultSC10Features();
167 	sc10Features.pNext											= pNext;
168 	pNext														= &sc10Features;
169 
170 	// create VkFaultCallbackInfo
171 	deUint32							maxQueryFaultCount		= context.getDeviceVulkanSC10Properties().maxQueryFaultCount;
172 	std::vector<VkFaultData>			faults;
173 
174 	if (testParams.allocateFaultData)
175 	{
176 		for (deUint32 i = 0; i < maxQueryFaultCount; ++i)
177 		{
178 			faults.push_back
179 			(
180 				{
181 					VK_STRUCTURE_TYPE_FAULT_DATA,	// VkStructureType	sType;
182 					DE_NULL,						// void*			pNext;
183 					VK_FAULT_LEVEL_UNASSIGNED,		// VkFaultLevel		faultLevel;
184 					VK_FAULT_TYPE_UNASSIGNED,		// VkFaultType		faultType;
185 				}
186 			);
187 		}
188 	}
189 
190 	VkFaultCallbackInfo					faultCallBackInfo		=
191 	{
192 		VK_STRUCTURE_TYPE_FAULT_CALLBACK_INFO,					//	VkStructureType				sType;
193 		DE_NULL,												//	void*						pNext;
194 		deUint32(faults.size()),								//	uint32_t					faultCount;
195 		testParams.allocateFaultData ? faults.data() : nullptr,	//	VkFaultData*				pFaults;
196 		(PFN_vkFaultCallbackFunction) testFaultCallback			//	PFN_vkFaultCallbackFunction	pfnFaultCallback;
197 	};
198 	faultCallBackInfo.pNext										= pNext;
199 	pNext														= &faultCallBackInfo;
200 
201 	// create VkDeviceCreateInfo
202 
203 	const float							queuePriority			= 1.0f;
204 
205 	const VkDeviceQueueCreateInfo		deviceQueueCI			=
206 	{
207 		VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,				// sType
208 		DE_NULL,												// pNext
209 		(VkDeviceQueueCreateFlags)0u,							// flags
210 		0,														//queueFamilyIndex;
211 		1,														//queueCount;
212 		&queuePriority,											//pQueuePriorities;
213 	};
214 
215 	VkDeviceCreateInfo					deviceCreateInfo		=
216 	{
217 		VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,					// sType;
218 		pNext,													// pNext;
219 		(VkDeviceCreateFlags)0u,								// flags
220 		1,														// queueRecordCount;
221 		&deviceQueueCI,											// pRequestedQueues;
222 		0,														// layerCount;
223 		DE_NULL,												// ppEnabledLayerNames;
224 		0,														// extensionCount;
225 		DE_NULL,												// ppEnabledExtensionNames;
226 		DE_NULL,												// pEnabledFeatures;
227 	};
228 
229 	Move<VkDevice> resultingDevice = createCustomDevice(context.getTestContext().getCommandLine().isValidationEnabled(), context.getPlatformInterface(), instance, instanceDriver, physicalDevice, &deviceCreateInfo);
230 
231 	return tcu::TestStatus::pass("Pass");
232 }
233 
234 } // anonymous
235 
createFaultHandlingTests(tcu::TestContext & testCtx)236 tcu::TestCaseGroup*	createFaultHandlingTests (tcu::TestContext& testCtx)
237 {
238 	de::MovePtr<tcu::TestCaseGroup> group(new tcu::TestCaseGroup(testCtx, "fault_handling", "Tests verifying Vulkan SC fault handling"));
239 
240 	// add tests for vkGetFaultData function
241 	{
242 		de::MovePtr<tcu::TestCaseGroup>	getFaultDataGroup(new tcu::TestCaseGroup(testCtx, "get_fault_data", "Testing vkGetFaultData results"));
243 
244 		const struct
245 		{
246 			VkFaultQueryBehavior						queryBehaviour;
247 			const char*									name;
248 		} behaviours[] =
249 		{
250 			{ VK_FAULT_QUERY_BEHAVIOR_GET_AND_CLEAR_ALL_FAULTS,	"get_and_clear_all_faults"	},
251 		};
252 
253 		const struct
254 		{
255 			FHFaultValue								faultValue;
256 			const char*									name;
257 		} faults[] =
258 		{
259 			{ FHF_NULL,									"null"	},
260 			{ FHF_ARRAY,								"array"	},
261 		};
262 
263 		for (int behaviourIdx = 0; behaviourIdx < DE_LENGTH_OF_ARRAY(behaviours); ++behaviourIdx)
264 		{
265 			de::MovePtr<tcu::TestCaseGroup> behaviourGroup(new tcu::TestCaseGroup(testCtx, behaviours[behaviourIdx].name, ""));
266 
267 			for (int faultIdx = 0; faultIdx < DE_LENGTH_OF_ARRAY(faults); ++faultIdx)
268 			{
269 				TestParams testParams{ behaviours[behaviourIdx].queryBehaviour, faults[faultIdx].faultValue };
270 
271 				addFunctionCase(behaviourGroup.get(), faults[faultIdx].name, "", testGetFaultData, testParams);
272 			}
273 			getFaultDataGroup->addChild(behaviourGroup.release());
274 		}
275 		group->addChild(getFaultDataGroup.release());
276 	}
277 
278 	// add tests for VkFaultCallbackInfo
279 	{
280 		de::MovePtr<tcu::TestCaseGroup>	faultCallbackInfoGroup(new tcu::TestCaseGroup(testCtx, "fault_callback_info", "Testing vkGetFaultData results"));
281 
282 		{
283 			FaultCallbackInfoTestParams testParams { true };
284 			addFunctionCase(faultCallbackInfoGroup.get(), "create_device_with_callback_with_fault_data", "", testCreateDeviceWithFaultCallbackInfo, testParams);
285 		}
286 		{
287 			FaultCallbackInfoTestParams testParams { false };
288 			addFunctionCase(faultCallbackInfoGroup.get(), "create_device_with_callback_without_fault_data", "", testCreateDeviceWithFaultCallbackInfo, testParams);
289 		}
290 		group->addChild(faultCallbackInfoGroup.release());
291 	}
292 
293 	return group.release();
294 }
295 
296 }	// sc
297 
298 }	// vkt
299