1 /*-------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
5 * Copyright (c) 2015 Google Inc.
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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.
21 * \brief Vulkan test case base classes
22 *//*--------------------------------------------------------------------*/
24 #include "vktTestCase.hpp"
27 #include "vkRefUtil.hpp"
28 #include "vkQueryUtil.hpp"
29 #include "vkDeviceUtil.hpp"
30 #include "vkMemUtil.hpp"
31 #include "vkPlatform.hpp"
32 #include "vkDebugReportUtil.hpp"
34 #include "tcuCommandLine.hpp"
36 #include "deSTLUtil.hpp"
44 // Default device utilities
54 vector<string> getValidationLayers (const vector<VkLayerProperties>& supportedLayers)
56 static const char* s_magicLayer = "VK_LAYER_LUNARG_standard_validation";
57 static const char* s_defaultLayers[] =
59 "VK_LAYER_GOOGLE_threading",
60 "VK_LAYER_LUNARG_parameter_validation",
61 "VK_LAYER_LUNARG_device_limits",
62 "VK_LAYER_LUNARG_object_tracker",
63 "VK_LAYER_LUNARG_image",
64 "VK_LAYER_LUNARG_core_validation",
65 "VK_LAYER_LUNARG_swapchain",
66 "VK_LAYER_GOOGLE_unique_objects"
69 vector<string> enabledLayers;
71 if (isLayerSupported(supportedLayers, RequiredLayer(s_magicLayer)))
72 enabledLayers.push_back(s_magicLayer);
75 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_defaultLayers); ++ndx)
77 if (isLayerSupported(supportedLayers, RequiredLayer(s_defaultLayers[ndx])))
78 enabledLayers.push_back(s_defaultLayers[ndx]);
85 vector<string> getValidationLayers (const PlatformInterface& vkp)
87 return getValidationLayers(enumerateInstanceLayerProperties(vkp));
90 vector<string> getValidationLayers (const InstanceInterface& vki, VkPhysicalDevice physicalDevice)
92 return getValidationLayers(enumerateDeviceLayerProperties(vki, physicalDevice));
95 vector<string> filterExtensions (const vector<VkExtensionProperties>& extensions)
97 vector<string> enabledExtensions;
98 const char* extensionGroups[] =
105 for (size_t extNdx = 0; extNdx < extensions.size(); extNdx++)
107 for (int extGroupNdx = 0; extGroupNdx < DE_LENGTH_OF_ARRAY(extensionGroups); extGroupNdx++)
109 if (deStringBeginsWith(extensions[extNdx].extensionName, extensionGroups[extGroupNdx]))
110 enabledExtensions.push_back(extensions[extNdx].extensionName);
114 return enabledExtensions;
117 vector<string> addExtensions (const vector<string>& a, const vector<const char*>& b)
119 vector<string> res (a);
121 for (vector<const char*>::const_iterator bIter = b.begin(); bIter != b.end(); ++bIter)
123 if (!de::contains(res.begin(), res.end(), string(*bIter)))
124 res.push_back(string(*bIter));
130 vector<string> removeExtensions (const vector<string>& a, const vector<const char*>& b)
133 set<string> removeExts (b.begin(), b.end());
135 for (vector<string>::const_iterator aIter = a.begin(); aIter != a.end(); ++aIter)
137 if (!de::contains(removeExts, *aIter))
138 res.push_back(*aIter);
144 vector<string> addCoreInstanceExtensions (const vector<string>& extensions, deUint32 instanceVersion)
146 vector<const char*> coreExtensions;
147 getCoreInstanceExtensions(instanceVersion, coreExtensions);
148 return addExtensions(extensions, coreExtensions);
151 vector<string> addCoreDeviceExtensions(const vector<string>& extensions, deUint32 instanceVersion)
153 vector<const char*> coreExtensions;
154 getCoreDeviceExtensions(instanceVersion, coreExtensions);
155 return addExtensions(extensions, coreExtensions);
158 deUint32 getTargetInstanceVersion (const PlatformInterface& vkp)
160 deUint32 version = pack(ApiVersion(1, 0, 0));
161 if (vkp.enumerateInstanceVersion(&version) != VK_SUCCESS)
162 TCU_THROW(InternalError, "Enumerate instance version error");
166 std::pair<deUint32, deUint32> determineDeviceVersions(const PlatformInterface& vkp, deUint32 apiVersion, const tcu::CommandLine& cmdLine)
168 Move<VkInstance> preinstance = createDefaultInstance(vkp, apiVersion);
169 InstanceDriver preinterface (vkp, preinstance.get());
171 const vector<VkPhysicalDevice> devices = enumeratePhysicalDevices(preinterface, preinstance.get());
172 deUint32 lowestDeviceVersion = 0xFFFFFFFFu;
173 for (deUint32 deviceNdx = 0u; deviceNdx < devices.size(); ++deviceNdx)
175 const VkPhysicalDeviceProperties props = getPhysicalDeviceProperties(preinterface, devices[deviceNdx]);
176 if (props.apiVersion < lowestDeviceVersion)
177 lowestDeviceVersion = props.apiVersion;
180 const vk::VkPhysicalDevice choosenDevice = chooseDevice(preinterface, *preinstance, cmdLine);
181 const VkPhysicalDeviceProperties props = getPhysicalDeviceProperties(preinterface, choosenDevice);
182 const deUint32 choosenDeviceVersion = props.apiVersion;
184 return std::make_pair(choosenDeviceVersion, lowestDeviceVersion);
188 Move<VkInstance> createInstance (const PlatformInterface& vkp, deUint32 apiVersion, const vector<string>& enabledExtensions, const tcu::CommandLine& cmdLine)
190 const bool isValidationEnabled = cmdLine.isValidationEnabled();
191 vector<string> enabledLayers;
193 // \note Extensions in core are not explicitly enabled even though
194 // they are in the extension list advertised to tests.
195 vector<const char*> coreExtensions;
196 getCoreInstanceExtensions(apiVersion, coreExtensions);
197 vector<string> nonCoreExtensions (removeExtensions(enabledExtensions, coreExtensions));
199 if (isValidationEnabled)
201 if (!isDebugReportSupported(vkp))
202 TCU_THROW(NotSupportedError, "VK_EXT_debug_report is not supported");
204 enabledLayers = getValidationLayers(vkp);
205 if (enabledLayers.empty())
206 TCU_THROW(NotSupportedError, "No validation layers found");
209 return createDefaultInstance(vkp, apiVersion, enabledLayers, nonCoreExtensions);
212 static deUint32 findQueueFamilyIndexWithCaps (const InstanceInterface& vkInstance, VkPhysicalDevice physicalDevice, VkQueueFlags requiredCaps)
214 const vector<VkQueueFamilyProperties> queueProps = getPhysicalDeviceQueueFamilyProperties(vkInstance, physicalDevice);
216 for (size_t queueNdx = 0; queueNdx < queueProps.size(); queueNdx++)
218 if ((queueProps[queueNdx].queueFlags & requiredCaps) == requiredCaps)
219 return (deUint32)queueNdx;
222 TCU_THROW(NotSupportedError, "No matching queue found");
225 Move<VkDevice> createDefaultDevice (const InstanceInterface& vki,
226 VkPhysicalDevice physicalDevice,
227 const deUint32 apiVersion,
229 deUint32 sparseQueueIndex,
230 const VkPhysicalDeviceFeatures2& enabledFeatures,
231 const vector<string>& enabledExtensions,
232 const tcu::CommandLine& cmdLine)
234 VkDeviceQueueCreateInfo queueInfo[2];
235 VkDeviceCreateInfo deviceInfo;
236 vector<string> enabledLayers;
237 vector<const char*> layerPtrs;
238 vector<const char*> extensionPtrs;
239 const float queuePriority = 1.0f;
240 const deUint32 numQueues = (enabledFeatures.features.sparseBinding && (queueIndex != sparseQueueIndex)) ? 2 : 1;
242 deMemset(&queueInfo, 0, sizeof(queueInfo));
243 deMemset(&deviceInfo, 0, sizeof(deviceInfo));
245 if (cmdLine.isValidationEnabled())
247 enabledLayers = getValidationLayers(vki, physicalDevice);
248 if (enabledLayers.empty())
249 TCU_THROW(NotSupportedError, "No validation layers found");
252 layerPtrs.resize(enabledLayers.size());
254 for (size_t ndx = 0; ndx < enabledLayers.size(); ++ndx)
255 layerPtrs[ndx] = enabledLayers[ndx].c_str();
257 // \note Extensions in core are not explicitly enabled even though
258 // they are in the extension list advertised to tests.
259 vector<const char*> coreExtensions;
260 getCoreDeviceExtensions(apiVersion, coreExtensions);
261 vector<string> nonCoreExtensions(removeExtensions(enabledExtensions, coreExtensions));
263 extensionPtrs.resize(nonCoreExtensions.size());
265 for (size_t ndx = 0; ndx < nonCoreExtensions.size(); ++ndx)
266 extensionPtrs[ndx] = nonCoreExtensions[ndx].c_str();
268 queueInfo[0].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
269 queueInfo[0].pNext = DE_NULL;
270 queueInfo[0].flags = (VkDeviceQueueCreateFlags)0u;
271 queueInfo[0].queueFamilyIndex = queueIndex;
272 queueInfo[0].queueCount = 1u;
273 queueInfo[0].pQueuePriorities = &queuePriority;
277 queueInfo[1].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
278 queueInfo[1].pNext = DE_NULL;
279 queueInfo[1].flags = (VkDeviceQueueCreateFlags)0u;
280 queueInfo[1].queueFamilyIndex = sparseQueueIndex;
281 queueInfo[1].queueCount = 1u;
282 queueInfo[1].pQueuePriorities = &queuePriority;
285 // VK_KHR_get_physical_device_properties2 is used if enabledFeatures.pNext != 0
286 deviceInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
287 deviceInfo.pNext = enabledFeatures.pNext ? &enabledFeatures : DE_NULL;
288 deviceInfo.queueCreateInfoCount = numQueues;
289 deviceInfo.pQueueCreateInfos = queueInfo;
290 deviceInfo.enabledExtensionCount = (deUint32)extensionPtrs.size();
291 deviceInfo.ppEnabledExtensionNames = (extensionPtrs.empty() ? DE_NULL : &extensionPtrs[0]);
292 deviceInfo.enabledLayerCount = (deUint32)layerPtrs.size();
293 deviceInfo.ppEnabledLayerNames = (layerPtrs.empty() ? DE_NULL : &layerPtrs[0]);
294 deviceInfo.pEnabledFeatures = enabledFeatures.pNext ? DE_NULL : &enabledFeatures.features;
296 return createDevice(vki, physicalDevice, &deviceInfo);
299 bool isPhysicalDeviceFeatures2Supported (const deUint32 version, const vector<string>& instanceExtensions)
301 return isInstanceExtensionSupported(version, instanceExtensions, "VK_KHR_get_physical_device_properties2");
307 VkPhysicalDeviceFeatures2 coreFeatures;
308 VkPhysicalDeviceSamplerYcbcrConversionFeatures samplerYCbCrConversionFeatures;
309 VkPhysicalDevice16BitStorageFeatures sixteenBitStorageFeatures;
310 VkPhysicalDeviceVariablePointerFeatures variablePointerFeatures;
312 DeviceFeatures (const InstanceInterface& vki,
313 const deUint32 apiVersion,
314 const VkPhysicalDevice& physicalDevice,
315 const vector<string>& instanceExtensions,
316 const vector<string>& deviceExtensions)
318 deMemset(&coreFeatures, 0, sizeof(coreFeatures));
319 deMemset(&samplerYCbCrConversionFeatures, 0, sizeof(samplerYCbCrConversionFeatures));
320 deMemset(&sixteenBitStorageFeatures, 0, sizeof(sixteenBitStorageFeatures));
321 deMemset(&variablePointerFeatures, 0, sizeof(variablePointerFeatures));
323 coreFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
324 samplerYCbCrConversionFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES;
325 sixteenBitStorageFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES_KHR;
326 variablePointerFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTER_FEATURES_KHR;
328 if (isPhysicalDeviceFeatures2Supported(apiVersion, instanceExtensions))
330 void** nextPtr = &coreFeatures.pNext;
332 if (de::contains(deviceExtensions.begin(), deviceExtensions.end(), "VK_KHR_sampler_ycbcr_conversion"))
334 *nextPtr = &samplerYCbCrConversionFeatures;
335 nextPtr = &samplerYCbCrConversionFeatures.pNext;
337 if (de::contains(deviceExtensions.begin(), deviceExtensions.end(), "VK_KHR_16bit_storage"))
339 *nextPtr = &sixteenBitStorageFeatures;
340 nextPtr = &sixteenBitStorageFeatures.pNext;
342 if (de::contains(deviceExtensions.begin(), deviceExtensions.end(), "VK_KHR_variable_pointers"))
344 *nextPtr = &variablePointerFeatures;
345 nextPtr = &variablePointerFeatures.pNext;
348 vki.getPhysicalDeviceFeatures2(physicalDevice, &coreFeatures);
351 coreFeatures.features = getPhysicalDeviceFeatures(vki, physicalDevice);
353 // Disable robustness by default, as it has an impact on performance on some HW.
354 coreFeatures.features.robustBufferAccess = false;
363 DefaultDevice (const PlatformInterface& vkPlatform, const tcu::CommandLine& cmdLine);
364 ~DefaultDevice (void);
366 VkInstance getInstance (void) const { return *m_instance; }
367 const InstanceInterface& getInstanceInterface (void) const { return m_instanceInterface; }
368 deUint32 getAvailableInstanceVersion (void) const { return m_availableInstanceVersion; }
369 const vector<string>& getInstanceExtensions (void) const { return m_instanceExtensions; }
371 VkPhysicalDevice getPhysicalDevice (void) const { return m_physicalDevice; }
372 deUint32 getDeviceVersion (void) const { return m_deviceVersion; }
373 const VkPhysicalDeviceFeatures& getDeviceFeatures (void) const { return m_deviceFeatures.coreFeatures.features; }
374 const VkPhysicalDeviceFeatures2& getDeviceFeatures2 (void) const { return m_deviceFeatures.coreFeatures; }
375 const VkPhysicalDeviceSamplerYcbcrConversionFeatures& getSamplerYCbCrConversionFeatures (void) const { return m_deviceFeatures.samplerYCbCrConversionFeatures; }
376 const VkPhysicalDevice16BitStorageFeatures& get16BitStorageFeatures (void) const { return m_deviceFeatures.sixteenBitStorageFeatures; }
377 const VkPhysicalDeviceVariablePointerFeatures& getVariablePointerFeatures (void) const { return m_deviceFeatures.variablePointerFeatures; }
378 VkDevice getDevice (void) const { return *m_device; }
379 const DeviceInterface& getDeviceInterface (void) const { return m_deviceInterface; }
380 const VkPhysicalDeviceProperties& getDeviceProperties (void) const { return m_deviceProperties; }
381 const vector<string>& getDeviceExtensions (void) const { return m_deviceExtensions; }
383 deUint32 getUsedApiVersion (void) const { return m_usedApiVersion; }
385 deUint32 getUniversalQueueFamilyIndex (void) const { return m_universalQueueFamilyIndex; }
386 VkQueue getUniversalQueue (void) const;
387 deUint32 getSparseQueueFamilyIndex (void) const { return m_sparseQueueFamilyIndex; }
388 VkQueue getSparseQueue (void) const;
392 const deUint32 m_availableInstanceVersion;
394 const std::pair<deUint32, deUint32> m_deviceVersions;
395 const deUint32 m_usedApiVersion;
397 const vector<string> m_instanceExtensions;
398 const Unique<VkInstance> m_instance;
399 const InstanceDriver m_instanceInterface;
401 const VkPhysicalDevice m_physicalDevice;
402 const deUint32 m_deviceVersion;
404 const vector<string> m_deviceExtensions;
405 const DeviceFeatures m_deviceFeatures;
407 const deUint32 m_universalQueueFamilyIndex;
408 const deUint32 m_sparseQueueFamilyIndex;
409 const VkPhysicalDeviceProperties m_deviceProperties;
411 const Unique<VkDevice> m_device;
412 const DeviceDriver m_deviceInterface;
416 DefaultDevice::DefaultDevice (const PlatformInterface& vkPlatform, const tcu::CommandLine& cmdLine)
417 : m_availableInstanceVersion (getTargetInstanceVersion(vkPlatform))
418 , m_deviceVersions (determineDeviceVersions(vkPlatform, m_availableInstanceVersion, cmdLine))
419 , m_usedApiVersion (deMinu32(m_availableInstanceVersion, m_deviceVersions.first))
421 , m_instanceExtensions (addCoreInstanceExtensions(filterExtensions(enumerateInstanceExtensionProperties(vkPlatform, DE_NULL)), m_usedApiVersion))
422 , m_instance (createInstance(vkPlatform, m_usedApiVersion, m_instanceExtensions, cmdLine))
424 , m_instanceInterface (vkPlatform, *m_instance)
425 , m_physicalDevice (chooseDevice(m_instanceInterface, *m_instance, cmdLine))
426 , m_deviceVersion (getPhysicalDeviceProperties(m_instanceInterface, m_physicalDevice).apiVersion)
428 , m_deviceExtensions (addCoreDeviceExtensions(filterExtensions(enumerateDeviceExtensionProperties(m_instanceInterface, m_physicalDevice, DE_NULL)), m_usedApiVersion))
429 , m_deviceFeatures (m_instanceInterface, m_usedApiVersion, m_physicalDevice, m_instanceExtensions, m_deviceExtensions)
430 , m_universalQueueFamilyIndex (findQueueFamilyIndexWithCaps(m_instanceInterface, m_physicalDevice, VK_QUEUE_GRAPHICS_BIT|VK_QUEUE_COMPUTE_BIT))
431 , m_sparseQueueFamilyIndex (m_deviceFeatures.coreFeatures.features.sparseBinding ? findQueueFamilyIndexWithCaps(m_instanceInterface, m_physicalDevice, VK_QUEUE_SPARSE_BINDING_BIT) : 0)
432 , m_deviceProperties (getPhysicalDeviceProperties(m_instanceInterface, m_physicalDevice))
433 , m_device (createDefaultDevice(m_instanceInterface, m_physicalDevice, m_usedApiVersion, m_universalQueueFamilyIndex, m_sparseQueueFamilyIndex, m_deviceFeatures.coreFeatures, m_deviceExtensions, cmdLine))
434 , m_deviceInterface (m_instanceInterface, *m_device)
436 DE_ASSERT(m_deviceVersions.first == m_deviceVersion);
439 DefaultDevice::~DefaultDevice (void)
443 VkQueue DefaultDevice::getUniversalQueue (void) const
445 return getDeviceQueue(m_deviceInterface, *m_device, m_universalQueueFamilyIndex, 0);
448 VkQueue DefaultDevice::getSparseQueue (void) const
450 if (!m_deviceFeatures.coreFeatures.features.sparseBinding)
451 TCU_THROW(NotSupportedError, "Sparse binding not supported.");
453 return getDeviceQueue(m_deviceInterface, *m_device, m_sparseQueueFamilyIndex, 0);
458 // Allocator utilities
460 vk::Allocator* createAllocator (DefaultDevice* device)
462 const VkPhysicalDeviceMemoryProperties memoryProperties = vk::getPhysicalDeviceMemoryProperties(device->getInstanceInterface(), device->getPhysicalDevice());
464 // \todo [2015-07-24 jarkko] support allocator selection/configuration from command line (or compile time)
465 return new SimpleAllocator(device->getDeviceInterface(), device->getDevice(), memoryProperties);
472 Context::Context (tcu::TestContext& testCtx,
473 const vk::PlatformInterface& platformInterface,
474 vk::BinaryCollection& progCollection)
475 : m_testCtx (testCtx)
476 , m_platformInterface (platformInterface)
477 , m_progCollection (progCollection)
478 , m_device (new DefaultDevice(m_platformInterface, testCtx.getCommandLine()))
479 , m_allocator (createAllocator(m_device.get()))
483 Context::~Context (void)
487 deUint32 Context::getAvailableInstanceVersion (void) const { return m_device->getAvailableInstanceVersion(); }
488 const vector<string>& Context::getInstanceExtensions (void) const { return m_device->getInstanceExtensions(); }
489 vk::VkInstance Context::getInstance (void) const { return m_device->getInstance(); }
490 const vk::InstanceInterface& Context::getInstanceInterface (void) const { return m_device->getInstanceInterface(); }
491 vk::VkPhysicalDevice Context::getPhysicalDevice (void) const { return m_device->getPhysicalDevice(); }
492 deUint32 Context::getDeviceVersion (void) const { return m_device->getDeviceVersion(); }
493 const vk::VkPhysicalDeviceFeatures& Context::getDeviceFeatures (void) const { return m_device->getDeviceFeatures(); }
494 const vk::VkPhysicalDeviceFeatures2& Context::getDeviceFeatures2 (void) const { return m_device->getDeviceFeatures2(); }
495 const vk::VkPhysicalDeviceSamplerYcbcrConversionFeatures&
496 Context::getSamplerYCbCrConversionFeatures
497 (void) const { return m_device->getSamplerYCbCrConversionFeatures(); }
498 const vk::VkPhysicalDevice16BitStorageFeatures&
499 Context::get16BitStorageFeatures (void) const { return m_device->get16BitStorageFeatures(); }
500 const vk::VkPhysicalDeviceVariablePointerFeatures&
501 Context::getVariablePointerFeatures (void) const { return m_device->getVariablePointerFeatures(); }
502 const vk::VkPhysicalDeviceProperties& Context::getDeviceProperties (void) const { return m_device->getDeviceProperties(); }
503 const vector<string>& Context::getDeviceExtensions (void) const { return m_device->getDeviceExtensions(); }
504 vk::VkDevice Context::getDevice (void) const { return m_device->getDevice(); }
505 const vk::DeviceInterface& Context::getDeviceInterface (void) const { return m_device->getDeviceInterface(); }
506 deUint32 Context::getUniversalQueueFamilyIndex (void) const { return m_device->getUniversalQueueFamilyIndex(); }
507 vk::VkQueue Context::getUniversalQueue (void) const { return m_device->getUniversalQueue(); }
508 deUint32 Context::getSparseQueueFamilyIndex (void) const { return m_device->getSparseQueueFamilyIndex(); }
509 vk::VkQueue Context::getSparseQueue (void) const { return m_device->getSparseQueue(); }
510 vk::Allocator& Context::getDefaultAllocator (void) const { return *m_allocator; }
511 deUint32 Context::getUsedApiVersion (void) const { return m_device->getUsedApiVersion(); }
512 bool Context::contextSupports (const deUint32 majorNum, const deUint32 minorNum, const deUint32 patchNum) const
513 { return m_device->getUsedApiVersion() >= VK_MAKE_VERSION(majorNum, minorNum, patchNum); }
514 bool Context::contextSupports (const ApiVersion version) const
515 { return m_device->getUsedApiVersion() >= pack(version); }
516 bool Context::contextSupports (const deUint32 requiredApiVersionBits) const
517 { return m_device->getUsedApiVersion() >= requiredApiVersionBits; }
521 void TestCase::initPrograms (SourceCollections&) const