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