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