2b3cecef8d3c8a8a8e5bff0f5191606129aa0e89
[platform/upstream/VK-GL-CTS.git] / external / vulkancts / modules / vulkan / api / vktApiVersionCheck.cpp
1 /*-------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
4 *
5 *
6 * Copyright (c) 2019 Google Inc.
7 * Copyright (c) 2019 Khronos Group
8 *
9 * Licensed under the Apache License, Version 2.0 (the "License");
10 * you may not use this file except in compliance with the License.
11 * You may obtain a copy of the License at
12 *
13 *      http://www.apache.org/licenses/LICENSE-2.0
14 *
15 * Unless required by applicable law or agreed to in writing, software
16 * distributed under the License is distributed on an "AS IS" BASIS,
17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 * See the License for the specific language governing permissions and
19 * limitations under the License.
20 *
21 *//*!
22 * \file
23 * \brief API Version Check test - prints out version info
24 *//*--------------------------------------------------------------------*/
25
26 #include <iostream>
27 #include <typeinfo>
28
29 #include "tcuDefs.hpp"
30 #include "tcuTestCase.hpp"
31 #include "tcuTestLog.hpp"
32 #include "tcuFunctionLibrary.hpp"
33 #include "tcuPlatform.hpp"
34 #include "tcuCommandLine.hpp"
35
36 #include "vkApiVersion.hpp"
37 #include "vkDefs.hpp"
38 #include "vkPlatform.hpp"
39
40 #include "vktApiVersionCheck.hpp"
41 #include "vktTestCase.hpp"
42 #include "vktCustomInstancesDevices.hpp"
43
44 #include "vkDeviceUtil.hpp"
45 #include "vkQueryUtil.hpp"
46 #include "vkRefUtil.hpp"
47
48 #include "deString.h"
49 #include "deStringUtil.hpp"
50
51 #include <map>
52 #include <vector>
53
54 using namespace vk;
55 using namespace std;
56
57 namespace vkt
58 {
59
60 namespace api
61 {
62
63 namespace
64 {
65
66 #include "vkExtensionFunctions.inl"
67 #include "vkCoreFunctionalities.inl"
68
69 class APIVersionTestInstance : public TestInstance
70 {
71 public:
72                                                                 APIVersionTestInstance  (Context&                               ctx)
73                                                                         : TestInstance  (ctx)
74         {}
75         virtual tcu::TestStatus         iterate                                 (void)
76         {
77                 tcu::TestLog&                   log                                             = m_context.getTestContext().getLog();
78                 const vk::ApiVersion    maxVulkanVersion                = vk::unpackVersion(m_context.getMaximumFrameworkVulkanVersion());
79                 const vk::ApiVersion    instanceVersion                 = vk::unpackVersion(m_context.getAvailableInstanceVersion());
80                 const ::std::string             instanceVersionString   = de::toString(instanceVersion.majorNum) + ::std::string(".") + de::toString(instanceVersion.minorNum) + ::std::string(".") + de::toString(instanceVersion.patchNum);
81                 const vk::ApiVersion    deviceVersion                   = vk::unpackVersion(m_context.getDeviceVersion());
82                 const ::std::string             deviceVersionString             = de::toString(deviceVersion.majorNum) + ::std::string(".") + de::toString(deviceVersion.minorNum) + ::std::string(".") + de::toString(deviceVersion.patchNum);
83                 const vk::ApiVersion    usedApiVersion                  = vk::unpackVersion(m_context.getUsedApiVersion());
84                 const ::std::string             usedApiVersionString    = de::toString(usedApiVersion.majorNum) + ::std::string(".") + de::toString(usedApiVersion.minorNum) + ::std::string(".") + de::toString(usedApiVersion.patchNum);
85
86                 log << tcu::TestLog::Message << "availableInstanceVersion: " << instanceVersion << tcu::TestLog::EndMessage;
87                 log << tcu::TestLog::Message << "deviceVersion: " << deviceVersion << tcu::TestLog::EndMessage;
88                 log << tcu::TestLog::Message << "usedApiVersion: " << usedApiVersion << tcu::TestLog::EndMessage;
89
90                 if (instanceVersion.majorNum > maxVulkanVersion.majorNum || instanceVersion.minorNum > maxVulkanVersion.minorNum)
91                         return tcu::TestStatus::fail(de::toString("This version of CTS does not support a Vulkan instance with version ") + instanceVersionString);
92                 else if (deviceVersion.majorNum > maxVulkanVersion.majorNum || deviceVersion.minorNum > maxVulkanVersion.minorNum)
93                         return tcu::TestStatus::fail(de::toString("This version of CTS does not support Vulkan device version ") + deviceVersionString);
94                 else
95                         return tcu::TestStatus::pass(usedApiVersionString);
96         }
97 };
98
99 class APIVersionTestCase : public TestCase
100 {
101 public:
102                                                         APIVersionTestCase      (tcu::TestContext&              testCtx)
103                                                                 : TestCase      (testCtx, "version", "Prints out API info.")
104         {}
105
106         virtual                                 ~APIVersionTestCase     (void)
107         {}
108         virtual TestInstance*   createInstance          (Context&                               ctx) const
109         {
110                 return new APIVersionTestInstance(ctx);
111         }
112
113 private:
114 };
115
116 class APIEntryPointsTestInstance : public TestInstance
117 {
118 public:
119         struct APIContext
120         {
121                 VkInstance                              instance;
122                 VkDevice                                device;
123                 GetInstanceProcAddrFunc getInstanceProcAddr;
124                 GetDeviceProcAddrFunc   getDeviceProcAddr;
125         };
126
127                                                                 APIEntryPointsTestInstance      (Context&                               ctx)
128                                                                         : TestInstance  (ctx)
129         {
130         }
131
132         virtual tcu::TestStatus         iterate                                         (void)
133         {
134                 tcu::TestLog&                                           log                             = m_context.getTestContext().getLog();
135                 const deUint32                                          apiVersion              = m_context.getUsedApiVersion();
136                 const vk::Platform&                                     platform                = m_context.getTestContext().getPlatform().getVulkanPlatform();
137                 de::MovePtr<vk::Library>                        vkLibrary               = de::MovePtr<vk::Library>(platform.createLibrary());
138                 const tcu::FunctionLibrary&                     funcLibrary             = vkLibrary->getFunctionLibrary();
139
140                 deUint32                                                        failsQuantity   = 0u;
141
142                 // Tests with default instance and device without extensions
143                 {
144                         CustomInstance                  instance                        = createCustomInstanceFromContext(m_context, DE_NULL, false);
145                         Move<VkDevice>                  device                          = createTestDevice(m_context, instance, vector<string>(), false);
146                         GetInstanceProcAddrFunc getInstanceProcAddr     = reinterpret_cast<GetInstanceProcAddrFunc>(funcLibrary.getFunction("vkGetInstanceProcAddr"));
147                         GetDeviceProcAddrFunc   getDeviceProcAddr       = reinterpret_cast<GetDeviceProcAddrFunc>(getInstanceProcAddr(instance, "vkGetDeviceProcAddr"));
148                         APIContext                              ctx                                     = { instance, *device, getInstanceProcAddr, getDeviceProcAddr };
149
150                         // Check entry points of core functions
151                         {
152                                 ApisMap                                                 functions                       = ApisMap();
153                                 initApisMap(functions);
154                                 ApisMap::const_iterator                 lastGoodVersion         = functions.begin();
155                                 const ApisMap::const_iterator   versionsEnd                     = functions.end();
156                                 for (ApisMap::const_iterator it = lastGoodVersion; it != versionsEnd; ++it)
157                                 {
158                                         if (it->first <= m_context.getUsedApiVersion())
159                                                 lastGoodVersion = it;
160                                 }
161
162                                 log << tcu::TestLog::Message << "Regular check - tries to get core functions from proper vkGet*ProcAddr." << tcu::TestLog::EndMessage;
163                                 const char* const                               regularResult           = regularCheck(ctx, log, failsQuantity, lastGoodVersion->second) ? "Passed" : "Failed";
164                                 log << tcu::TestLog::Message << regularResult << tcu::TestLog::EndMessage;
165
166                                 log << tcu::TestLog::Message << "Cross check - tries to get core functions from improper vkGet*ProcAddr." << tcu::TestLog::EndMessage;
167                                 const char* const                               mixupResult                     = mixupAddressProcCheck(ctx, log, failsQuantity, lastGoodVersion->second) ? "Passed" : "Failed";
168                                 log << tcu::TestLog::Message << mixupResult << tcu::TestLog::EndMessage;
169                         }
170
171                         // Check function entry points of disabled extesions
172                         {
173                                 FunctionInfosList                               extFunctions            = FunctionInfosList();
174                                 extFunctions.push_back(FunctionInfo("vkTrimCommandPoolKHR", FUNCTIONORIGIN_DEVICE));
175                                 extFunctions.push_back(FunctionInfo("vkCmdPushDescriptorSetKHR", FUNCTIONORIGIN_DEVICE));
176                                 extFunctions.push_back(FunctionInfo("vkCreateSamplerYcbcrConversionKHR", FUNCTIONORIGIN_DEVICE));
177                                 extFunctions.push_back(FunctionInfo("vkGetSwapchainStatusKHR", FUNCTIONORIGIN_DEVICE));
178                                 extFunctions.push_back(FunctionInfo("vkCreateSwapchainKHR", FUNCTIONORIGIN_DEVICE));
179                                 extFunctions.push_back(FunctionInfo("vkGetImageSparseMemoryRequirements2KHR", FUNCTIONORIGIN_DEVICE));
180                                 extFunctions.push_back(FunctionInfo("vkBindBufferMemory2KHR", FUNCTIONORIGIN_DEVICE));
181                                 extFunctions.push_back(FunctionInfo("vkImportFenceWin32HandleKHR", FUNCTIONORIGIN_DEVICE));
182                                 extFunctions.push_back(FunctionInfo("vkGetBufferMemoryRequirements2KHR", FUNCTIONORIGIN_DEVICE));
183                                 extFunctions.push_back(FunctionInfo("vkGetImageMemoryRequirements2KHR", FUNCTIONORIGIN_DEVICE));
184
185                                 log << tcu::TestLog::Message << "Disabled extensions check - tries to get functions of disabled extensions from proper vkGet*ProcAddr." << tcu::TestLog::EndMessage;
186                                 const char * const                              result                          = specialCasesCheck(ctx, log, failsQuantity, extFunctions) ? "Passed" : "Failed";
187                                 log << tcu::TestLog::Message << result << tcu::TestLog::EndMessage;
188                         }
189
190                         // Check special cases
191                         {
192                                 FunctionInfosList                               dummyFunctions          = FunctionInfosList();
193                                 for (deUint32 i = 0; i <= FUNCTIONORIGIN_DEVICE; ++i)
194                                 {
195                                         const FunctionOrigin origin = static_cast<FunctionOrigin>(i);
196                                         dummyFunctions.push_back(FunctionInfo("vkSomeName", origin));
197                                         dummyFunctions.push_back(FunctionInfo("vkNonexistingKHR", origin));
198                                         dummyFunctions.push_back(FunctionInfo("", origin));
199                                 }
200
201                                 log << tcu::TestLog::Message << "Special check - tries to get some dummy functions from various vkGet*ProcAddr." << tcu::TestLog::EndMessage;
202                                 const char * const                              result                          = specialCasesCheck(ctx, log, failsQuantity, dummyFunctions) ? "Passed" : "Failed";
203                                 log << tcu::TestLog::Message << result << tcu::TestLog::EndMessage;
204                         }
205                 }
206
207                 // Tests with instance and device with extensions
208                 {
209                         CustomInstance                  instance                        = createCustomInstanceWithExtensions(m_context, getSupportedInstanceExtensions(apiVersion), DE_NULL, false);
210                         Move<VkDevice>                  device                          = createTestDevice(m_context, instance, getSupportedDeviceExtensions(apiVersion), false);
211                         GetInstanceProcAddrFunc getInstanceProcAddr     = reinterpret_cast<GetInstanceProcAddrFunc>(funcLibrary.getFunction("vkGetInstanceProcAddr"));
212                         GetDeviceProcAddrFunc   getDeviceProcAddr       = reinterpret_cast<GetDeviceProcAddrFunc>(getInstanceProcAddr(instance, "vkGetDeviceProcAddr"));
213                         APIContext                              ctx                                     = { instance, *device, getInstanceProcAddr, getDeviceProcAddr };
214
215                         // Check function entry points of enabled extensions
216                         {
217                                 vector<FunctionInfo>    extFunctions;
218
219                                 // Add supported instance extension functions
220                                 for (size_t instanceExtNdx = 0; instanceExtNdx < DE_LENGTH_OF_ARRAY(instanceExtensionNames); instanceExtNdx++)
221                                 {
222                                         vector<const char*> instanceExtFunctions;
223                                         vector<const char*> deviceExtFunctions;
224
225                                         if (isSupportedInstanceExt(instanceExtensionNames[instanceExtNdx], apiVersion))
226                                         {
227                                                 getInstanceExtensionFunctions(apiVersion, instanceExtensionNames[instanceExtNdx], instanceExtFunctions);
228                                                 getDeviceExtensionFunctions(apiVersion, instanceExtensionNames[instanceExtNdx], deviceExtFunctions);
229                                         }
230
231                                         for (size_t instanceFuncNdx = 0; instanceFuncNdx < instanceExtFunctions.size(); instanceFuncNdx++)
232                                                 extFunctions.push_back(FunctionInfo(instanceExtFunctions[instanceFuncNdx], FUNCTIONORIGIN_INSTANCE));
233
234                                         for (size_t deviceFuncNdx = 0; deviceFuncNdx < deviceExtFunctions.size(); deviceFuncNdx++)
235                                                 extFunctions.push_back(FunctionInfo(deviceExtFunctions[deviceFuncNdx], FUNCTIONORIGIN_DEVICE));
236                                 }
237
238                                 // Add supported device extension functions
239                                 for (size_t deviceExtNdx = 0; deviceExtNdx < DE_LENGTH_OF_ARRAY(deviceExtensionNames); deviceExtNdx++)
240                                 {
241                                         vector<const char*> deviceExtFunctions;
242
243                                         if (isSupportedDeviceExt(deviceExtensionNames[deviceExtNdx], apiVersion))
244                                                 getDeviceExtensionFunctions(apiVersion, deviceExtensionNames[deviceExtNdx], deviceExtFunctions);
245
246                                         for (size_t deviceFuncNdx = 0; deviceFuncNdx < deviceExtFunctions.size(); deviceFuncNdx++)
247                                                 extFunctions.push_back(FunctionInfo(deviceExtFunctions[deviceFuncNdx], FUNCTIONORIGIN_DEVICE));
248                                 }
249
250                                 log << tcu::TestLog::Message << "Enabled extensions check - tries to get functions of supported extensions from proper vkGet*ProcAddr." << tcu::TestLog::EndMessage;
251                                 const char * const              result = regularCheck(ctx, log, failsQuantity, extFunctions) ? "Passed" : "Failed";
252                                 log << tcu::TestLog::Message << result << tcu::TestLog::EndMessage;
253                         }
254                 }
255
256                 if (failsQuantity > 0u)
257                         return tcu::TestStatus::fail("Fail");
258                 else
259                         return tcu::TestStatus::pass("Pass");
260         }
261
262 private:
263
264         deUint32 findQueueFamilyIndex(const InstanceInterface& vkInstance, VkPhysicalDevice physicalDevice, VkQueueFlags requiredCaps)
265         {
266                 deUint32                                                                numQueues = 0;
267                 vkInstance.getPhysicalDeviceQueueFamilyProperties(physicalDevice, &numQueues, DE_NULL);
268                 if (numQueues > 0)
269                 {
270                         vector<VkQueueFamilyProperties>         properties(numQueues);
271                         vkInstance.getPhysicalDeviceQueueFamilyProperties(physicalDevice, &numQueues, &properties[0]);
272                         if (numQueues != static_cast<deUint32>(properties.size()))
273                                 TCU_FAIL("Returned queue family count changes between queries.");
274                         for (deUint32 queueNdx = 0u; queueNdx < numQueues; queueNdx++)
275                                 if ((properties[queueNdx].queueFlags & requiredCaps) == requiredCaps)
276                                         return queueNdx;
277                 }
278                 TCU_FAIL("Returned queue family count was 0.");
279                 return 0u;
280         }
281
282         vector<string> filterMultiAuthorExtensions (vector<VkExtensionProperties> extProperties)
283         {
284                 vector<string>  multiAuthorExtensions;
285                 const char*             extensionGroups[] =
286                 {
287                         "VK_KHR_",
288                         "VK_EXT_"
289                 };
290
291                 for (size_t extNdx = 0; extNdx < extProperties.size(); extNdx++)
292                 {
293                         for (int extGroupNdx = 0; extGroupNdx < DE_LENGTH_OF_ARRAY(extensionGroups); extGroupNdx++)
294                         {
295                                 if (deStringBeginsWith(extProperties[extNdx].extensionName, extensionGroups[extGroupNdx]))
296                                         multiAuthorExtensions.push_back(extProperties[extNdx].extensionName);
297                         }
298                 }
299
300                 return multiAuthorExtensions;
301         }
302
303         vector<string> getSupportedInstanceExtensions (const deUint32 apiVersion)
304         {
305                 vector<VkExtensionProperties>   enumeratedExtensions (enumerateInstanceExtensionProperties(m_context.getPlatformInterface(), DE_NULL));
306                 vector<VkExtensionProperties>   supportedExtensions;
307
308                 for (size_t extNdx = 0; extNdx < enumeratedExtensions.size(); extNdx++)
309                 {
310                         if (!isCoreInstanceExtension(apiVersion, enumeratedExtensions[extNdx].extensionName))
311                                 supportedExtensions.push_back(enumeratedExtensions[extNdx]);
312                 }
313
314                 return filterMultiAuthorExtensions(supportedExtensions);
315         }
316
317         vector<string> getSupportedDeviceExtensions (const deUint32 apiVersion)
318         {
319                 vector<VkExtensionProperties>   enumeratedExtensions (enumerateDeviceExtensionProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice(), DE_NULL));
320                 vector<VkExtensionProperties>   supportedExtensions;
321
322                 for (size_t extNdx = 0; extNdx < enumeratedExtensions.size(); extNdx++)
323                 {
324                         if (!isCoreDeviceExtension(apiVersion, enumeratedExtensions[extNdx].extensionName))
325                                 supportedExtensions.push_back(enumeratedExtensions[extNdx]);
326                 }
327
328                 return filterMultiAuthorExtensions(supportedExtensions);
329         }
330
331         Move<VkDevice> createTestDevice (const Context& context, VkInstance instance, vector<string> extensions = vector<string>(), bool allowLayers = true)
332         {
333                 auto&                                           cmdLine                 = context.getTestContext().getCommandLine();
334                 const PlatformInterface&        vkp                             = context.getPlatformInterface();
335                 const InstanceInterface&        vki                             = context.getInstanceInterface();
336                 VkPhysicalDevice                        physicalDevice  = chooseDevice(context.getInstanceInterface(), instance, cmdLine);
337                 vector<const char*>                     extensionPtrs;
338                 const float                                     queuePriority   = 1.0f;
339                 const deUint32                          queueIndex              = findQueueFamilyIndex(vki, physicalDevice, VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT);
340
341                 for (size_t i = 0; i < extensions.size(); i++)
342                         extensionPtrs.push_back(extensions[i].c_str());
343
344                 VkDeviceQueueCreateInfo         queueInfo               = {
345                         VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
346                         DE_NULL,
347                         static_cast<VkDeviceQueueCreateFlags>(0u),
348                         queueIndex,
349                         1u,
350                         &queuePriority
351                 };
352
353                 const VkDeviceCreateInfo        deviceInfo              = {
354                         VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
355                         DE_NULL,
356                         static_cast<VkDeviceCreateFlags>(0u),
357                         1u,
358                         &queueInfo,
359                         0u,
360                         DE_NULL,
361                         (deUint32)extensions.size(),
362                         extensions.size() ? &extensionPtrs[0] : DE_NULL,
363                         DE_NULL,
364                 };
365
366                 const bool                                      validationEnabled = (cmdLine.isValidationEnabled() && allowLayers);
367                 return createCustomDevice(validationEnabled, vkp, instance, vki, physicalDevice, &deviceInfo);
368         }
369
370         void reportFail (tcu::TestLog& log, const char* const functionName, const char* const firstParamName, const char* const secondParamName, deBool shouldBeNonNull, deUint32& failsQuantity)
371         {
372                 log << tcu::TestLog::Message
373                         << "[" << failsQuantity << "] " << functionName << '(' << firstParamName << ", \"" << secondParamName << "\") "
374                         << "returned " << (shouldBeNonNull ? "nullptr" : "non-null") << ". Should return " << (shouldBeNonNull ? "valid function address." : "nullptr.")
375                         << tcu::TestLog::EndMessage;
376                 ++failsQuantity;
377         }
378
379         void checkPlatformFunction (const APIContext& ctx, tcu::TestLog& log, const char* const name, deBool shouldBeNonNull, deUint32& failsQuantity)
380         {
381                 if ((ctx.getInstanceProcAddr(DE_NULL, name) == DE_NULL) == shouldBeNonNull)
382                         reportFail(log, "vkGetInstanceProcAddr", "DE_NULL", name, shouldBeNonNull, failsQuantity);
383         }
384
385         void checkInstanceFunction (const APIContext& ctx, tcu::TestLog& log, const char* const name, deBool shouldBeNonNull, deUint32& failsQuantity)
386         {
387                 if ((ctx.getInstanceProcAddr(ctx.instance, name) == DE_NULL) == shouldBeNonNull)
388                         reportFail(log, "vkGetInstanceProcAddr", "instance", name, shouldBeNonNull, failsQuantity);
389         }
390
391         void checkDeviceFunction (const APIContext& ctx, tcu::TestLog& log, const char* const name, deBool shouldBeNonNull, deUint32& failsQuantity)
392         {
393                 if ((ctx.getDeviceProcAddr(ctx.device, name) == DE_NULL) == shouldBeNonNull)
394                         reportFail(log, "vkGetDeviceProcAddr", "device", name, shouldBeNonNull, failsQuantity);
395         }
396
397         deBool isSupportedInstanceExt (const string extName, const deUint32 apiVersion)
398         {
399                 const vector<string> supportedInstanceExtensions (getSupportedInstanceExtensions(apiVersion));
400
401                 return de::contains(supportedInstanceExtensions.begin(), supportedInstanceExtensions.end(), extName);
402         }
403
404         deBool isSupportedDeviceExt (const string extName, const deUint32 apiVersion)
405         {
406                 const vector<string> supportedDeviceExtensions (getSupportedDeviceExtensions(apiVersion));
407
408                 return de::contains(supportedDeviceExtensions.begin(), supportedDeviceExtensions.end(), extName);
409         }
410
411         deBool mixupAddressProcCheck (const APIContext& ctx, tcu::TestLog& log, deUint32& failsQuantity, const vector<pair<const char*, FunctionOrigin> >& testsArr)
412         {
413                 const deUint32 startingQuantity = failsQuantity;
414                 for (deUint32 ndx = 0u; ndx < testsArr.size(); ++ndx)
415                 {
416                         if (deStringEqual(testsArr[ndx].first, "vkGetInstanceProcAddr") || deStringEqual(testsArr[ndx].first, "vkEnumerateInstanceVersion"))
417                                 continue;
418
419                         const char*        functionName = testsArr[ndx].first;
420                         const deUint32 functionType = testsArr[ndx].second;
421                         if (functionType == FUNCTIONORIGIN_INSTANCE)
422                         {
423                                 checkPlatformFunction(ctx, log, functionName, DE_FALSE, failsQuantity);
424                                 checkDeviceFunction(ctx, log, functionName, DE_FALSE, failsQuantity);
425                         }
426                         else if (functionType == FUNCTIONORIGIN_DEVICE)
427                                 checkPlatformFunction(ctx, log, functionName, DE_FALSE, failsQuantity);
428                 }
429                 return startingQuantity == failsQuantity;
430         }
431
432         deBool specialCasesCheck (const APIContext& ctx, tcu::TestLog& log, deUint32& failsQuantity, const vector<pair<const char*, FunctionOrigin> >& testsArr)
433         {
434                 const deUint32 startingQuantity = failsQuantity;
435                 for (deUint32 ndx = 0u; ndx < testsArr.size(); ++ndx)
436                 {
437                         const deUint32 functionType = testsArr[ndx].second;
438                         if (functionType == FUNCTIONORIGIN_PLATFORM)
439                                 checkPlatformFunction(ctx, log, testsArr[ndx].first, DE_FALSE, failsQuantity);
440                         else if (functionType == FUNCTIONORIGIN_INSTANCE)
441                                 checkInstanceFunction(ctx, log, testsArr[ndx].first, DE_FALSE, failsQuantity);
442                         else if (functionType == FUNCTIONORIGIN_DEVICE)
443                                 checkDeviceFunction(ctx, log, testsArr[ndx].first, DE_FALSE, failsQuantity);
444                 }
445                 return startingQuantity == failsQuantity;
446         }
447
448         deBool regularCheck (const APIContext& ctx, tcu::TestLog& log, deUint32& failsQuantity, const vector<pair<const char*, FunctionOrigin> >& testsArr)
449         {
450                 const deUint32 startingQuantity = failsQuantity;
451                 for (deUint32 ndx = 0u; ndx < testsArr.size(); ++ndx)
452                 {
453                         if (deStringEqual(testsArr[ndx].first, "vkGetInstanceProcAddr") && m_context.getUsedApiVersion() < VK_API_VERSION_1_2)
454                                 continue;
455
456                         const deUint32 functionType     = testsArr[ndx].second;
457                         if (functionType == FUNCTIONORIGIN_PLATFORM)
458                                 checkPlatformFunction(ctx, log, testsArr[ndx].first, DE_TRUE, failsQuantity);
459                         else if (functionType == FUNCTIONORIGIN_INSTANCE)
460                         {
461                                 checkInstanceFunction(ctx, log, testsArr[ndx].first, DE_TRUE, failsQuantity);
462                                 checkDeviceFunction(ctx, log, testsArr[ndx].first, DE_FALSE, failsQuantity);
463                         }
464                         else if (functionType == FUNCTIONORIGIN_DEVICE)
465                         {
466                                 checkInstanceFunction(ctx, log, testsArr[ndx].first, DE_TRUE, failsQuantity);
467                                 checkDeviceFunction(ctx, log, testsArr[ndx].first, DE_TRUE, failsQuantity);
468                         }
469                 }
470                 return startingQuantity == failsQuantity;
471         }
472 };
473
474 class APIEntryPointsTestCase : public TestCase
475 {
476 public:
477                                                         APIEntryPointsTestCase                  (tcu::TestContext&              testCtx)
478                                                                 : TestCase      (testCtx, "entry_points", "Prints out API info.")
479         {}
480
481         virtual                                 ~APIEntryPointsTestCase                 (void)
482         {}
483         virtual TestInstance*   createInstance                                  (Context&                               ctx) const
484         {
485                 return new APIEntryPointsTestInstance(ctx);
486         }
487
488 private:
489 };
490
491 } // anonymous
492
493 tcu::TestCaseGroup*                     createVersionSanityCheckTests   (tcu::TestContext & testCtx)
494 {
495         de::MovePtr<tcu::TestCaseGroup> versionTests    (new tcu::TestCaseGroup(testCtx, "version_check", "API Version Tests"));
496         versionTests->addChild(new APIVersionTestCase(testCtx));
497         versionTests->addChild(new APIEntryPointsTestCase(testCtx));
498         return versionTests.release();
499 }
500
501 } // api
502
503 } // vkt