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:
APIVersionTestInstance(Context & ctx)72 APIVersionTestInstance (Context& ctx)
73 : TestInstance (ctx)
74 {}
iterate(void)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 (deviceVersion.majorNum > maxVulkanVersion.majorNum || deviceVersion.minorNum > maxVulkanVersion.minorNum)
91 return tcu::TestStatus::fail(de::toString("This version of CTS does not support Vulkan device version ") + deviceVersionString);
92 else
93 return tcu::TestStatus::pass(usedApiVersionString);
94 }
95 };
96
97 class APIVersionTestCase : public TestCase
98 {
99 public:
APIVersionTestCase(tcu::TestContext & testCtx)100 APIVersionTestCase (tcu::TestContext& testCtx)
101 : TestCase (testCtx, "version", "Prints out API info.")
102 {}
103
~APIVersionTestCase(void)104 virtual ~APIVersionTestCase (void)
105 {}
createInstance(Context & ctx) const106 virtual TestInstance* createInstance (Context& ctx) const
107 {
108 return new APIVersionTestInstance(ctx);
109 }
110
111 private:
112 };
113
114 class APIEntryPointsTestInstance : public TestInstance
115 {
116 public:
117 struct APIContext
118 {
119 VkInstance instance;
120 VkDevice device;
121 GetInstanceProcAddrFunc getInstanceProcAddr;
122 GetDeviceProcAddrFunc getDeviceProcAddr;
123 };
124
APIEntryPointsTestInstance(Context & ctx)125 APIEntryPointsTestInstance (Context& ctx)
126 : TestInstance (ctx)
127 {
128 }
129
iterate(void)130 virtual tcu::TestStatus iterate (void)
131 {
132 tcu::TestLog& log = m_context.getTestContext().getLog();
133 const deUint32 apiVersion = m_context.getUsedApiVersion();
134 const vk::Platform& platform = m_context.getTestContext().getPlatform().getVulkanPlatform();
135 de::MovePtr<vk::Library> vkLibrary = de::MovePtr<vk::Library>(platform.createLibrary());
136 const tcu::FunctionLibrary& funcLibrary = vkLibrary->getFunctionLibrary();
137
138 deUint32 failsQuantity = 0u;
139
140 // Tests with default instance and device without extensions
141 {
142 CustomInstance instance = createCustomInstanceFromContext(m_context, DE_NULL, false);
143 Move<VkDevice> device = createTestDevice(m_context, instance, vector<string>(), false);
144 GetInstanceProcAddrFunc getInstanceProcAddr = reinterpret_cast<GetInstanceProcAddrFunc>(funcLibrary.getFunction("vkGetInstanceProcAddr"));
145 GetDeviceProcAddrFunc getDeviceProcAddr = reinterpret_cast<GetDeviceProcAddrFunc>(getInstanceProcAddr(instance, "vkGetDeviceProcAddr"));
146 APIContext ctx = { instance, *device, getInstanceProcAddr, getDeviceProcAddr };
147
148 // Check entry points of core functions
149 {
150 ApisMap functions = ApisMap();
151 initApisMap(functions);
152 ApisMap::const_iterator lastGoodVersion = functions.begin();
153 const ApisMap::const_iterator versionsEnd = functions.end();
154 for (ApisMap::const_iterator it = lastGoodVersion; it != versionsEnd; ++it)
155 {
156 if (it->first <= m_context.getUsedApiVersion())
157 lastGoodVersion = it;
158 }
159
160 log << tcu::TestLog::Message << "Regular check - tries to get core functions from proper vkGet*ProcAddr." << tcu::TestLog::EndMessage;
161 const char* const regularResult = regularCheck(ctx, log, failsQuantity, lastGoodVersion->second) ? "Passed" : "Failed";
162 log << tcu::TestLog::Message << regularResult << tcu::TestLog::EndMessage;
163
164 log << tcu::TestLog::Message << "Cross check - tries to get core functions from improper vkGet*ProcAddr." << tcu::TestLog::EndMessage;
165 const char* const mixupResult = mixupAddressProcCheck(ctx, log, failsQuantity, lastGoodVersion->second) ? "Passed" : "Failed";
166 log << tcu::TestLog::Message << mixupResult << tcu::TestLog::EndMessage;
167 }
168
169 // Check function entry points of disabled extesions
170 {
171 FunctionInfosList extFunctions = FunctionInfosList();
172 extFunctions.push_back(FunctionInfo("vkTrimCommandPoolKHR", FUNCTIONORIGIN_DEVICE));
173 extFunctions.push_back(FunctionInfo("vkCmdPushDescriptorSetKHR", FUNCTIONORIGIN_DEVICE));
174 extFunctions.push_back(FunctionInfo("vkCreateSamplerYcbcrConversionKHR", FUNCTIONORIGIN_DEVICE));
175 extFunctions.push_back(FunctionInfo("vkGetSwapchainStatusKHR", FUNCTIONORIGIN_DEVICE));
176 extFunctions.push_back(FunctionInfo("vkCreateSwapchainKHR", FUNCTIONORIGIN_DEVICE));
177 extFunctions.push_back(FunctionInfo("vkGetImageSparseMemoryRequirements2KHR", FUNCTIONORIGIN_DEVICE));
178 extFunctions.push_back(FunctionInfo("vkBindBufferMemory2KHR", FUNCTIONORIGIN_DEVICE));
179 extFunctions.push_back(FunctionInfo("vkImportFenceWin32HandleKHR", FUNCTIONORIGIN_DEVICE));
180 extFunctions.push_back(FunctionInfo("vkGetBufferMemoryRequirements2KHR", FUNCTIONORIGIN_DEVICE));
181 extFunctions.push_back(FunctionInfo("vkGetImageMemoryRequirements2KHR", FUNCTIONORIGIN_DEVICE));
182
183 log << tcu::TestLog::Message << "Disabled extensions check - tries to get functions of disabled extensions from proper vkGet*ProcAddr." << tcu::TestLog::EndMessage;
184 const char * const result = specialCasesCheck(ctx, log, failsQuantity, extFunctions) ? "Passed" : "Failed";
185 log << tcu::TestLog::Message << result << tcu::TestLog::EndMessage;
186 }
187
188 // Check special cases
189 {
190 FunctionInfosList nonexistingFunctions = FunctionInfosList();
191 for (deUint32 i = 0; i <= FUNCTIONORIGIN_DEVICE; ++i)
192 {
193 const FunctionOrigin origin = static_cast<FunctionOrigin>(i);
194 nonexistingFunctions.push_back(FunctionInfo("vkSomeName", origin));
195 nonexistingFunctions.push_back(FunctionInfo("vkNonexistingKHR", origin));
196 nonexistingFunctions.push_back(FunctionInfo("", origin));
197 }
198
199 log << tcu::TestLog::Message << "Special check - tries to get some nonexisting functions from various vkGet*ProcAddr." << tcu::TestLog::EndMessage;
200 const char * const result = specialCasesCheck(ctx, log, failsQuantity, nonexistingFunctions) ? "Passed" : "Failed";
201 log << tcu::TestLog::Message << result << tcu::TestLog::EndMessage;
202 }
203 }
204
205 // Tests with instance and device with extensions
206 {
207 CustomInstance instance = createCustomInstanceWithExtensions(m_context, getSupportedInstanceExtensions(apiVersion), DE_NULL, false);
208 Move<VkDevice> device = createTestDevice(m_context, instance, getSupportedDeviceExtensions(apiVersion), false);
209 GetInstanceProcAddrFunc getInstanceProcAddr = reinterpret_cast<GetInstanceProcAddrFunc>(funcLibrary.getFunction("vkGetInstanceProcAddr"));
210 GetDeviceProcAddrFunc getDeviceProcAddr = reinterpret_cast<GetDeviceProcAddrFunc>(getInstanceProcAddr(instance, "vkGetDeviceProcAddr"));
211 APIContext ctx = { instance, *device, getInstanceProcAddr, getDeviceProcAddr };
212
213 // Check function entry points of enabled extensions
214 {
215 vector<FunctionInfo> extFunctions;
216
217 // Add supported instance extension functions
218 for (size_t instanceExtNdx = 0; instanceExtNdx < DE_LENGTH_OF_ARRAY(instanceExtensionNames); instanceExtNdx++)
219 {
220 vector<const char*> instanceExtFunctions;
221 vector<const char*> deviceExtFunctions;
222
223 if (isSupportedInstanceExt(instanceExtensionNames[instanceExtNdx], apiVersion))
224 {
225 getInstanceExtensionFunctions(apiVersion, instanceExtensionNames[instanceExtNdx], instanceExtFunctions);
226 getDeviceExtensionFunctions(apiVersion, instanceExtensionNames[instanceExtNdx], deviceExtFunctions);
227 }
228
229 for (size_t instanceFuncNdx = 0; instanceFuncNdx < instanceExtFunctions.size(); instanceFuncNdx++)
230 extFunctions.push_back(FunctionInfo(instanceExtFunctions[instanceFuncNdx], FUNCTIONORIGIN_INSTANCE));
231
232 for (size_t deviceFuncNdx = 0; deviceFuncNdx < deviceExtFunctions.size(); deviceFuncNdx++)
233 extFunctions.push_back(FunctionInfo(deviceExtFunctions[deviceFuncNdx], FUNCTIONORIGIN_DEVICE));
234 }
235
236 // Add supported device extension functions
237 for (size_t deviceExtNdx = 0; deviceExtNdx < DE_LENGTH_OF_ARRAY(deviceExtensionNames); deviceExtNdx++)
238 {
239 vector<const char*> deviceExtFunctions;
240
241 if (isSupportedDeviceExt(deviceExtensionNames[deviceExtNdx], apiVersion))
242 getDeviceExtensionFunctions(apiVersion, deviceExtensionNames[deviceExtNdx], deviceExtFunctions);
243
244 for (size_t deviceFuncNdx = 0; deviceFuncNdx < deviceExtFunctions.size(); deviceFuncNdx++)
245 extFunctions.push_back(FunctionInfo(deviceExtFunctions[deviceFuncNdx], FUNCTIONORIGIN_DEVICE));
246 }
247
248 log << tcu::TestLog::Message << "Enabled extensions check - tries to get functions of supported extensions from proper vkGet*ProcAddr." << tcu::TestLog::EndMessage;
249 const char * const result = regularCheck(ctx, log, failsQuantity, extFunctions) ? "Passed" : "Failed";
250 log << tcu::TestLog::Message << result << tcu::TestLog::EndMessage;
251 }
252 }
253
254 if (failsQuantity > 0u)
255 return tcu::TestStatus::fail("Fail");
256 else
257 return tcu::TestStatus::pass("Pass");
258 }
259
260 private:
261
findQueueFamilyIndex(const InstanceInterface & vkInstance,VkPhysicalDevice physicalDevice,VkQueueFlags requiredCaps)262 deUint32 findQueueFamilyIndex(const InstanceInterface& vkInstance, VkPhysicalDevice physicalDevice, VkQueueFlags requiredCaps)
263 {
264 deUint32 numQueues = 0;
265 vkInstance.getPhysicalDeviceQueueFamilyProperties(physicalDevice, &numQueues, DE_NULL);
266 if (numQueues > 0)
267 {
268 vector<VkQueueFamilyProperties> properties(numQueues);
269 vkInstance.getPhysicalDeviceQueueFamilyProperties(physicalDevice, &numQueues, &properties[0]);
270 if (numQueues != static_cast<deUint32>(properties.size()))
271 TCU_FAIL("Returned queue family count changes between queries.");
272 for (deUint32 queueNdx = 0u; queueNdx < numQueues; queueNdx++)
273 if ((properties[queueNdx].queueFlags & requiredCaps) == requiredCaps)
274 return queueNdx;
275 }
276 TCU_FAIL("Returned queue family count was 0.");
277 return 0u;
278 }
279
filterMultiAuthorExtensions(vector<VkExtensionProperties> extProperties)280 vector<string> filterMultiAuthorExtensions (vector<VkExtensionProperties> extProperties)
281 {
282 vector<string> multiAuthorExtensions;
283 const char* extensionGroups[] =
284 {
285 "VK_KHR_",
286 "VK_EXT_"
287 };
288
289 for (size_t extNdx = 0; extNdx < extProperties.size(); extNdx++)
290 {
291 for (int extGroupNdx = 0; extGroupNdx < DE_LENGTH_OF_ARRAY(extensionGroups); extGroupNdx++)
292 {
293 if (deStringBeginsWith(extProperties[extNdx].extensionName, extensionGroups[extGroupNdx]))
294 multiAuthorExtensions.push_back(extProperties[extNdx].extensionName);
295 }
296 }
297
298 return multiAuthorExtensions;
299 }
300
getSupportedInstanceExtensions(const deUint32 apiVersion)301 vector<string> getSupportedInstanceExtensions (const deUint32 apiVersion)
302 {
303 vector<VkExtensionProperties> enumeratedExtensions (enumerateInstanceExtensionProperties(m_context.getPlatformInterface(), DE_NULL));
304 vector<VkExtensionProperties> supportedExtensions;
305
306 for (size_t extNdx = 0; extNdx < enumeratedExtensions.size(); extNdx++)
307 {
308 if (!isCoreInstanceExtension(apiVersion, enumeratedExtensions[extNdx].extensionName))
309 supportedExtensions.push_back(enumeratedExtensions[extNdx]);
310 }
311
312 return filterMultiAuthorExtensions(supportedExtensions);
313 }
314
getSupportedDeviceExtensions(const deUint32 apiVersion)315 vector<string> getSupportedDeviceExtensions (const deUint32 apiVersion)
316 {
317 vector<VkExtensionProperties> enumeratedExtensions (enumerateDeviceExtensionProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice(), DE_NULL));
318 vector<VkExtensionProperties> supportedExtensions;
319
320 for (size_t extNdx = 0; extNdx < enumeratedExtensions.size(); extNdx++)
321 {
322 if (!isCoreDeviceExtension(apiVersion, enumeratedExtensions[extNdx].extensionName))
323 supportedExtensions.push_back(enumeratedExtensions[extNdx]);
324 }
325
326 return filterMultiAuthorExtensions(supportedExtensions);
327 }
328
createTestDevice(const Context & context,VkInstance instance,vector<string> extensions=vector<string> (),bool allowLayers=true)329 Move<VkDevice> createTestDevice (const Context& context, VkInstance instance, vector<string> extensions = vector<string>(), bool allowLayers = true)
330 {
331 auto& cmdLine = context.getTestContext().getCommandLine();
332 const PlatformInterface& vkp = context.getPlatformInterface();
333 const InstanceInterface& vki = context.getInstanceInterface();
334 VkPhysicalDevice physicalDevice = chooseDevice(context.getInstanceInterface(), instance, cmdLine);
335 vector<const char*> extensionPtrs;
336 const float queuePriority = 1.0f;
337 const deUint32 queueIndex = findQueueFamilyIndex(vki, physicalDevice, VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT);
338
339 for (size_t i = 0; i < extensions.size(); i++)
340 extensionPtrs.push_back(extensions[i].c_str());
341
342 VkDeviceQueueCreateInfo queueInfo = {
343 VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
344 DE_NULL,
345 static_cast<VkDeviceQueueCreateFlags>(0u),
346 queueIndex,
347 1u,
348 &queuePriority
349 };
350
351 const VkDeviceCreateInfo deviceInfo = {
352 VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
353 DE_NULL,
354 static_cast<VkDeviceCreateFlags>(0u),
355 1u,
356 &queueInfo,
357 0u,
358 DE_NULL,
359 (deUint32)extensions.size(),
360 extensions.size() ? &extensionPtrs[0] : DE_NULL,
361 DE_NULL,
362 };
363
364 const bool validationEnabled = (cmdLine.isValidationEnabled() && allowLayers);
365 return createCustomDevice(validationEnabled, vkp, instance, vki, physicalDevice, &deviceInfo);
366 }
367
reportFail(tcu::TestLog & log,const char * const functionName,const char * const firstParamName,const char * const secondParamName,deBool shouldBeNonNull,deUint32 & failsQuantity)368 void reportFail (tcu::TestLog& log, const char* const functionName, const char* const firstParamName, const char* const secondParamName, deBool shouldBeNonNull, deUint32& failsQuantity)
369 {
370 log << tcu::TestLog::Message
371 << "[" << failsQuantity << "] " << functionName << '(' << firstParamName << ", \"" << secondParamName << "\") "
372 << "returned " << (shouldBeNonNull ? "nullptr" : "non-null") << ". Should return " << (shouldBeNonNull ? "valid function address." : "nullptr.")
373 << tcu::TestLog::EndMessage;
374 ++failsQuantity;
375 }
376
checkPlatformFunction(const APIContext & ctx,tcu::TestLog & log,const char * const name,deBool shouldBeNonNull,deUint32 & failsQuantity)377 void checkPlatformFunction (const APIContext& ctx, tcu::TestLog& log, const char* const name, deBool shouldBeNonNull, deUint32& failsQuantity)
378 {
379 if ((ctx.getInstanceProcAddr(DE_NULL, name) == DE_NULL) == shouldBeNonNull)
380 reportFail(log, "vkGetInstanceProcAddr", "DE_NULL", name, shouldBeNonNull, failsQuantity);
381 }
382
checkInstanceFunction(const APIContext & ctx,tcu::TestLog & log,const char * const name,deBool shouldBeNonNull,deUint32 & failsQuantity)383 void checkInstanceFunction (const APIContext& ctx, tcu::TestLog& log, const char* const name, deBool shouldBeNonNull, deUint32& failsQuantity)
384 {
385 if ((ctx.getInstanceProcAddr(ctx.instance, name) == DE_NULL) == shouldBeNonNull)
386 reportFail(log, "vkGetInstanceProcAddr", "instance", name, shouldBeNonNull, failsQuantity);
387 }
388
checkDeviceFunction(const APIContext & ctx,tcu::TestLog & log,const char * const name,deBool shouldBeNonNull,deUint32 & failsQuantity)389 void checkDeviceFunction (const APIContext& ctx, tcu::TestLog& log, const char* const name, deBool shouldBeNonNull, deUint32& failsQuantity)
390 {
391 if ((ctx.getDeviceProcAddr(ctx.device, name) == DE_NULL) == shouldBeNonNull)
392 reportFail(log, "vkGetDeviceProcAddr", "device", name, shouldBeNonNull, failsQuantity);
393 }
394
isSupportedInstanceExt(const string extName,const deUint32 apiVersion)395 deBool isSupportedInstanceExt (const string extName, const deUint32 apiVersion)
396 {
397 const vector<string> supportedInstanceExtensions (getSupportedInstanceExtensions(apiVersion));
398
399 return de::contains(supportedInstanceExtensions.begin(), supportedInstanceExtensions.end(), extName);
400 }
401
isSupportedDeviceExt(const string extName,const deUint32 apiVersion)402 deBool isSupportedDeviceExt (const string extName, const deUint32 apiVersion)
403 {
404 const vector<string> supportedDeviceExtensions (getSupportedDeviceExtensions(apiVersion));
405
406 return de::contains(supportedDeviceExtensions.begin(), supportedDeviceExtensions.end(), extName);
407 }
408
mixupAddressProcCheck(const APIContext & ctx,tcu::TestLog & log,deUint32 & failsQuantity,const vector<pair<const char *,FunctionOrigin>> & testsArr)409 deBool mixupAddressProcCheck (const APIContext& ctx, tcu::TestLog& log, deUint32& failsQuantity, const vector<pair<const char*, FunctionOrigin> >& testsArr)
410 {
411 const deUint32 startingQuantity = failsQuantity;
412 for (deUint32 ndx = 0u; ndx < testsArr.size(); ++ndx)
413 {
414 if (deStringEqual(testsArr[ndx].first, "vkGetInstanceProcAddr") || deStringEqual(testsArr[ndx].first, "vkEnumerateInstanceVersion"))
415 continue;
416
417 const char* functionName = testsArr[ndx].first;
418 const deUint32 functionType = testsArr[ndx].second;
419 if (functionType == FUNCTIONORIGIN_INSTANCE)
420 {
421 checkPlatformFunction(ctx, log, functionName, DE_FALSE, failsQuantity);
422 checkDeviceFunction(ctx, log, functionName, DE_FALSE, failsQuantity);
423 }
424 else if (functionType == FUNCTIONORIGIN_DEVICE)
425 checkPlatformFunction(ctx, log, functionName, DE_FALSE, failsQuantity);
426 }
427 return startingQuantity == failsQuantity;
428 }
429
specialCasesCheck(const APIContext & ctx,tcu::TestLog & log,deUint32 & failsQuantity,const vector<pair<const char *,FunctionOrigin>> & testsArr)430 deBool specialCasesCheck (const APIContext& ctx, tcu::TestLog& log, deUint32& failsQuantity, const vector<pair<const char*, FunctionOrigin> >& testsArr)
431 {
432 const deUint32 startingQuantity = failsQuantity;
433 for (deUint32 ndx = 0u; ndx < testsArr.size(); ++ndx)
434 {
435 const deUint32 functionType = testsArr[ndx].second;
436 if (functionType == FUNCTIONORIGIN_PLATFORM)
437 checkPlatformFunction(ctx, log, testsArr[ndx].first, DE_FALSE, failsQuantity);
438 else if (functionType == FUNCTIONORIGIN_INSTANCE)
439 checkInstanceFunction(ctx, log, testsArr[ndx].first, DE_FALSE, failsQuantity);
440 else if (functionType == FUNCTIONORIGIN_DEVICE)
441 checkDeviceFunction(ctx, log, testsArr[ndx].first, DE_FALSE, failsQuantity);
442 }
443 return startingQuantity == failsQuantity;
444 }
445
regularCheck(const APIContext & ctx,tcu::TestLog & log,deUint32 & failsQuantity,const vector<pair<const char *,FunctionOrigin>> & testsArr)446 deBool regularCheck (const APIContext& ctx, tcu::TestLog& log, deUint32& failsQuantity, const vector<pair<const char*, FunctionOrigin> >& testsArr)
447 {
448 const deUint32 startingQuantity = failsQuantity;
449
450 for (deUint32 ndx = 0u; ndx < testsArr.size(); ++ndx)
451 {
452 const auto& funcName = testsArr[ndx].first;
453 const auto& funcType = testsArr[ndx].second;
454 const auto apiVersion = m_context.getUsedApiVersion();
455
456 if (deStringEqual(funcName, "vkGetInstanceProcAddr") && apiVersion < VK_API_VERSION_1_2)
457 continue;
458
459 // VK_KHR_draw_indirect_count was promoted to core in Vulkan 1.2, but these entrypoints are not mandatory unless the
460 // device supports the extension. In that case, the drawIndirectCount feature bit will also be true. Any of the two
461 // checks is valid. We use the extension name for convenience here.
462 if ((deStringEqual(funcName, "vkCmdDrawIndirectCount") || deStringEqual(funcName, "vkCmdDrawIndexedIndirectCount"))
463 && !isSupportedDeviceExt("VK_KHR_draw_indirect_count", apiVersion))
464 continue;
465
466 if (funcType == FUNCTIONORIGIN_PLATFORM)
467 {
468 checkPlatformFunction(ctx, log, funcName, DE_TRUE, failsQuantity);
469 }
470 else if (funcType == FUNCTIONORIGIN_INSTANCE)
471 {
472 checkInstanceFunction(ctx, log, funcName, DE_TRUE, failsQuantity);
473 checkDeviceFunction(ctx, log, funcName, DE_FALSE, failsQuantity);
474 }
475 else if (funcType == FUNCTIONORIGIN_DEVICE)
476 {
477 checkInstanceFunction(ctx, log, funcName, DE_TRUE, failsQuantity);
478 checkDeviceFunction(ctx, log, funcName, DE_TRUE, failsQuantity);
479 }
480 }
481
482 return startingQuantity == failsQuantity;
483 }
484 };
485
486 class APIEntryPointsTestCase : public TestCase
487 {
488 public:
APIEntryPointsTestCase(tcu::TestContext & testCtx)489 APIEntryPointsTestCase (tcu::TestContext& testCtx)
490 : TestCase (testCtx, "entry_points", "Prints out API info.")
491 {}
492
~APIEntryPointsTestCase(void)493 virtual ~APIEntryPointsTestCase (void)
494 {}
createInstance(Context & ctx) const495 virtual TestInstance* createInstance (Context& ctx) const
496 {
497 return new APIEntryPointsTestInstance(ctx);
498 }
499
500 private:
501 };
502
503 } // anonymous
504
createVersionSanityCheckTests(tcu::TestContext & testCtx)505 tcu::TestCaseGroup* createVersionSanityCheckTests (tcu::TestContext & testCtx)
506 {
507 de::MovePtr<tcu::TestCaseGroup> versionTests (new tcu::TestCaseGroup(testCtx, "version_check", "API Version Tests"));
508 versionTests->addChild(new APIVersionTestCase(testCtx));
509 versionTests->addChild(new APIEntryPointsTestCase(testCtx));
510 return versionTests.release();
511 }
512
513 } // api
514
515 } // vkt
516