xref: /aosp_15_r20/external/deqp/external/vulkancts/modules/vulkan/sc/vktFaultHandlingTests.cpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
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     uint32_t maxQueryFaultCount = context.getDeviceVulkanSC10Properties().maxQueryFaultCount;
65 
66     VkBool32 unrecordedFaults = VK_TRUE;
67     uint32_t faultCount       = maxQueryFaultCount;
68     std::vector<VkFaultData> faults;
69     for (uint32_t i = 0; i < maxQueryFaultCount; ++i)
70     {
71         faults.push_back({
72             VK_STRUCTURE_TYPE_FAULT_DATA, // VkStructureType sType;
73             DE_NULL,                      // void* pNext;
74             VK_FAULT_LEVEL_UNASSIGNED,    // VkFaultLevel faultLevel;
75             VK_FAULT_TYPE_UNASSIGNED,     // VkFaultType faultType;
76         });
77     }
78     bool isOK           = true;
79     bool faultsModified = false;
80     VkResult result;
81 
82     switch (testParams.faultValue)
83     {
84     case FHF_NULL:
85         result = vk.getFaultData(device, testParams.queryBehaviour, &unrecordedFaults, &faultCount, DE_NULL);
86 
87         if (result != VK_SUCCESS)
88         {
89             context.getTestContext().getLog()
90                 << tcu::TestLog::Message << "Result is not VK_SUCCESS" << tcu::TestLog::EndMessage;
91             isOK = false;
92         }
93         if (unrecordedFaults != VK_FALSE)
94         {
95             context.getTestContext().getLog()
96                 << tcu::TestLog::Message << "unrecordedFaults is not VK_FALSE" << tcu::TestLog::EndMessage;
97             isOK = false;
98         }
99         if (faultCount != 0u)
100         {
101             context.getTestContext().getLog()
102                 << 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()
112                 << tcu::TestLog::Message << "Result is not VK_SUCCESS" << tcu::TestLog::EndMessage;
113             isOK = false;
114         }
115         if (unrecordedFaults != VK_FALSE)
116         {
117             context.getTestContext().getLog()
118                 << tcu::TestLog::Message << "unrecordedFaults is not VK_FALSE" << tcu::TestLog::EndMessage;
119             isOK = false;
120         }
121         if (faultCount != 0u)
122         {
123             context.getTestContext().getLog()
124                 << tcu::TestLog::Message << "faultCount is not 0" << tcu::TestLog::EndMessage;
125             isOK = false;
126         }
127         for (uint32_t i = 0; i < maxQueryFaultCount; ++i)
128             if (faults[i].faultLevel != VK_FAULT_LEVEL_UNASSIGNED || faults[i].faultType != VK_FAULT_TYPE_UNASSIGNED)
129                 faultsModified = true;
130         if (faultsModified)
131         {
132             context.getTestContext().getLog()
133                 << tcu::TestLog::Message << "pFaults have been modified" << tcu::TestLog::EndMessage;
134             isOK = false;
135         }
136         break;
137     default:
138         TCU_THROW(InternalError, "Unrecognized fault type");
139     }
140 
141     return isOK ? tcu::TestStatus::pass("Pass") : tcu::TestStatus::fail("Fail");
142 }
143 
testFaultCallback(VkBool32 incompleteFaultData,uint32_t faultCount,const VkFaultData * pFaultData)144 VKAPI_ATTR void VKAPI_CALL testFaultCallback(VkBool32 incompleteFaultData, uint32_t faultCount,
145                                              const VkFaultData *pFaultData)
146 {
147     DE_UNREF(incompleteFaultData);
148     DE_UNREF(faultCount);
149     DE_UNREF(pFaultData);
150 }
151 
152 struct FaultCallbackInfoTestParams
153 {
154     bool allocateFaultData;
155 };
156 
testCreateDeviceWithFaultCallbackInfo(Context & context,FaultCallbackInfoTestParams testParams)157 tcu::TestStatus testCreateDeviceWithFaultCallbackInfo(Context &context, FaultCallbackInfoTestParams testParams)
158 {
159     const CustomInstance instance(createCustomInstanceFromContext(context));
160     const InstanceDriver &instanceDriver(instance.getDriver());
161     const VkPhysicalDevice physicalDevice =
162         chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
163 
164     void *pNext = DE_NULL;
165 
166     VkDeviceObjectReservationCreateInfo memReservationInfo = context.getTestContext().getCommandLine().isSubProcess() ?
167                                                                  context.getResourceInterface()->getStatMax() :
168                                                                  resetDeviceObjectReservationCreateInfo();
169     memReservationInfo.pNext                               = pNext;
170     pNext                                                  = &memReservationInfo;
171 
172     VkPhysicalDeviceVulkanSC10Features sc10Features = createDefaultSC10Features();
173     sc10Features.pNext                              = pNext;
174     pNext                                           = &sc10Features;
175 
176     // create VkFaultCallbackInfo
177     uint32_t maxQueryFaultCount = context.getDeviceVulkanSC10Properties().maxQueryFaultCount;
178     std::vector<VkFaultData> faults;
179 
180     if (testParams.allocateFaultData)
181     {
182         for (uint32_t i = 0; i < maxQueryFaultCount; ++i)
183         {
184             faults.push_back({
185                 VK_STRUCTURE_TYPE_FAULT_DATA, // VkStructureType sType;
186                 DE_NULL,                      // void* pNext;
187                 VK_FAULT_LEVEL_UNASSIGNED,    // VkFaultLevel faultLevel;
188                 VK_FAULT_TYPE_UNASSIGNED,     // VkFaultType faultType;
189             });
190         }
191     }
192 
193     VkFaultCallbackInfo faultCallBackInfo = {
194         VK_STRUCTURE_TYPE_FAULT_CALLBACK_INFO,                  // VkStructureType sType;
195         DE_NULL,                                                // void* pNext;
196         uint32_t(faults.size()),                                // uint32_t faultCount;
197         testParams.allocateFaultData ? faults.data() : nullptr, // VkFaultData* pFaults;
198         testFaultCallback                                       // PFN_vkFaultCallbackFunction pfnFaultCallback;
199     };
200     faultCallBackInfo.pNext = pNext;
201     pNext                   = &faultCallBackInfo;
202 
203     // create VkDeviceCreateInfo
204 
205     const float queuePriority = 1.0f;
206 
207     const VkDeviceQueueCreateInfo deviceQueueCI = {
208         VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, // sType
209         DE_NULL,                                    // pNext
210         (VkDeviceQueueCreateFlags)0u,               // flags
211         0,                                          //queueFamilyIndex;
212         1,                                          //queueCount;
213         &queuePriority,                             //pQueuePriorities;
214     };
215 
216     VkDeviceCreateInfo deviceCreateInfo = {
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 =
230         createCustomDevice(context.getTestContext().getCommandLine().isValidationEnabled(),
231                            context.getPlatformInterface(), instance, instanceDriver, physicalDevice, &deviceCreateInfo);
232 
233     return tcu::TestStatus::pass("Pass");
234 }
235 
236 } // namespace
237 
createFaultHandlingTests(tcu::TestContext & testCtx)238 tcu::TestCaseGroup *createFaultHandlingTests(tcu::TestContext &testCtx)
239 {
240     // Tests verifying Vulkan SC fault handling
241     de::MovePtr<tcu::TestCaseGroup> group(new tcu::TestCaseGroup(testCtx, "fault_handling"));
242 
243     // add tests for vkGetFaultData function
244     {
245         // Testing vkGetFaultData results
246         de::MovePtr<tcu::TestCaseGroup> getFaultDataGroup(new tcu::TestCaseGroup(testCtx, "get_fault_data"));
247 
248         const struct
249         {
250             VkFaultQueryBehavior queryBehaviour;
251             const char *name;
252         } behaviours[] = {
253             {VK_FAULT_QUERY_BEHAVIOR_GET_AND_CLEAR_ALL_FAULTS, "get_and_clear_all_faults"},
254         };
255 
256         const struct
257         {
258             FHFaultValue faultValue;
259             const char *name;
260         } faults[] = {
261             {FHF_NULL, "null"},
262             {FHF_ARRAY, "array"},
263         };
264 
265         for (int behaviourIdx = 0; behaviourIdx < DE_LENGTH_OF_ARRAY(behaviours); ++behaviourIdx)
266         {
267             de::MovePtr<tcu::TestCaseGroup> behaviourGroup(
268                 new tcu::TestCaseGroup(testCtx, behaviours[behaviourIdx].name));
269 
270             for (int faultIdx = 0; faultIdx < DE_LENGTH_OF_ARRAY(faults); ++faultIdx)
271             {
272                 TestParams testParams{behaviours[behaviourIdx].queryBehaviour, faults[faultIdx].faultValue};
273 
274                 addFunctionCase(behaviourGroup.get(), faults[faultIdx].name, testGetFaultData, testParams);
275             }
276             getFaultDataGroup->addChild(behaviourGroup.release());
277         }
278         group->addChild(getFaultDataGroup.release());
279     }
280 
281     // add tests for VkFaultCallbackInfo
282     {
283         de::MovePtr<tcu::TestCaseGroup> faultCallbackInfoGroup(new tcu::TestCaseGroup(testCtx, "fault_callback_info"));
284 
285         {
286             FaultCallbackInfoTestParams testParams{true};
287             addFunctionCase(faultCallbackInfoGroup.get(), "create_device_with_callback_with_fault_data",
288                             testCreateDeviceWithFaultCallbackInfo, testParams);
289         }
290         {
291             FaultCallbackInfoTestParams testParams{false};
292             addFunctionCase(faultCallbackInfoGroup.get(), "create_device_with_callback_without_fault_data",
293                             testCreateDeviceWithFaultCallbackInfo, testParams);
294         }
295         group->addChild(faultCallbackInfoGroup.release());
296     }
297 
298     return group.release();
299 }
300 
301 } // namespace sc
302 
303 } // namespace vkt
304