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"
33 #include "vkApiVersion.hpp"
35 #include "tcuCommandLine.hpp"
37 #include "deSTLUtil.hpp"
45 // Default device utilities
55 vector<string> getValidationLayers (const vector<VkLayerProperties>& supportedLayers)
57 static const char* s_magicLayer = "VK_LAYER_LUNARG_standard_validation";
58 static const char* s_defaultLayers[] =
60 "VK_LAYER_GOOGLE_threading",
61 "VK_LAYER_LUNARG_parameter_validation",
62 "VK_LAYER_LUNARG_device_limits",
63 "VK_LAYER_LUNARG_object_tracker",
64 "VK_LAYER_LUNARG_image",
65 "VK_LAYER_LUNARG_core_validation",
66 "VK_LAYER_LUNARG_swapchain",
67 "VK_LAYER_GOOGLE_unique_objects"
70 vector<string> enabledLayers;
72 if (isLayerSupported(supportedLayers, RequiredLayer(s_magicLayer)))
73 enabledLayers.push_back(s_magicLayer);
76 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_defaultLayers); ++ndx)
78 if (isLayerSupported(supportedLayers, RequiredLayer(s_defaultLayers[ndx])))
79 enabledLayers.push_back(s_defaultLayers[ndx]);
86 vector<string> getValidationLayers (const PlatformInterface& vkp)
88 return getValidationLayers(enumerateInstanceLayerProperties(vkp));
91 vector<string> getValidationLayers (const InstanceInterface& vki, VkPhysicalDevice physicalDevice)
93 return getValidationLayers(enumerateDeviceLayerProperties(vki, physicalDevice));
96 vector<string> filterExtensions (const vector<VkExtensionProperties>& extensions)
98 vector<string> enabledExtensions;
99 const char* extensionGroups[] =
106 for (size_t extNdx = 0; extNdx < extensions.size(); extNdx++)
108 for (int extGroupNdx = 0; extGroupNdx < DE_LENGTH_OF_ARRAY(extensionGroups); extGroupNdx++)
110 if (deStringBeginsWith(extensions[extNdx].extensionName, extensionGroups[extGroupNdx]))
111 enabledExtensions.push_back(extensions[extNdx].extensionName);
115 return enabledExtensions;
118 vector<string> addExtensions (const vector<string>& a, const vector<const char*>& b)
120 vector<string> res (a);
122 for (vector<const char*>::const_iterator bIter = b.begin(); bIter != b.end(); ++bIter)
124 if (!de::contains(res.begin(), res.end(), string(*bIter)))
125 res.push_back(string(*bIter));
131 vector<string> removeExtensions (const vector<string>& a, const vector<const char*>& b)
134 set<string> removeExts (b.begin(), b.end());
136 for (vector<string>::const_iterator aIter = a.begin(); aIter != a.end(); ++aIter)
138 if (!de::contains(removeExts, *aIter))
139 res.push_back(*aIter);
145 vector<string> addCoreInstanceExtensions (const vector<string>& extensions, deUint32 instanceVersion)
147 vector<const char*> coreExtensions;
148 getCoreInstanceExtensions(instanceVersion, coreExtensions);
149 return addExtensions(extensions, coreExtensions);
152 vector<string> addCoreDeviceExtensions(const vector<string>& extensions, deUint32 instanceVersion)
154 vector<const char*> coreExtensions;
155 getCoreDeviceExtensions(instanceVersion, coreExtensions);
156 return addExtensions(extensions, coreExtensions);
159 deUint32 getTargetInstanceVersion (const PlatformInterface& vkp)
161 deUint32 version = pack(ApiVersion(1, 0, 0));
162 if (vkp.enumerateInstanceVersion(&version) != VK_SUCCESS)
163 TCU_THROW(InternalError, "Enumerate instance version error");
167 Move<VkInstance> createInstance (const PlatformInterface& vkp, deUint32 apiVersion, const vector<string>& enabledExtensions, const tcu::CommandLine& cmdLine)
169 const bool isValidationEnabled = cmdLine.isValidationEnabled();
170 vector<string> enabledLayers;
172 // \note Extensions in core are not explicitly enabled even though
173 // they are in the extension list advertised to tests.
174 vector<const char*> coreExtensions;
175 getCoreInstanceExtensions(apiVersion, coreExtensions);
176 vector<string> nonCoreExtensions (removeExtensions(enabledExtensions, coreExtensions));
178 if (isValidationEnabled)
180 if (!isDebugReportSupported(vkp))
181 TCU_THROW(NotSupportedError, "VK_EXT_debug_report is not supported");
183 enabledLayers = getValidationLayers(vkp);
184 if (enabledLayers.empty())
185 TCU_THROW(NotSupportedError, "No validation layers found");
188 return createDefaultInstance(vkp, apiVersion, enabledLayers, nonCoreExtensions);
191 static deUint32 findQueueFamilyIndexWithCaps (const InstanceInterface& vkInstance, VkPhysicalDevice physicalDevice, VkQueueFlags requiredCaps)
193 const vector<VkQueueFamilyProperties> queueProps = getPhysicalDeviceQueueFamilyProperties(vkInstance, physicalDevice);
195 for (size_t queueNdx = 0; queueNdx < queueProps.size(); queueNdx++)
197 if ((queueProps[queueNdx].queueFlags & requiredCaps) == requiredCaps)
198 return (deUint32)queueNdx;
201 TCU_THROW(NotSupportedError, "No matching queue found");
204 Move<VkDevice> createDefaultDevice (const InstanceInterface& vki,
205 VkPhysicalDevice physicalDevice,
206 const deUint32 apiVersion,
208 const VkPhysicalDeviceFeatures2& enabledFeatures,
209 const vector<string>& enabledExtensions,
210 const tcu::CommandLine& cmdLine)
212 VkDeviceQueueCreateInfo queueInfo;
213 VkDeviceCreateInfo deviceInfo;
214 vector<string> enabledLayers;
215 vector<const char*> layerPtrs;
216 vector<const char*> extensionPtrs;
217 const float queuePriority = 1.0f;
219 deMemset(&queueInfo, 0, sizeof(queueInfo));
220 deMemset(&deviceInfo, 0, sizeof(deviceInfo));
222 if (cmdLine.isValidationEnabled())
224 enabledLayers = getValidationLayers(vki, physicalDevice);
225 if (enabledLayers.empty())
226 TCU_THROW(NotSupportedError, "No validation layers found");
229 layerPtrs.resize(enabledLayers.size());
231 for (size_t ndx = 0; ndx < enabledLayers.size(); ++ndx)
232 layerPtrs[ndx] = enabledLayers[ndx].c_str();
234 // \note Extensions in core are not explicitly enabled even though
235 // they are in the extension list advertised to tests.
236 vector<const char*> coreExtensions;
237 getCoreDeviceExtensions(apiVersion, coreExtensions);
238 vector<string> nonCoreExtensions(removeExtensions(enabledExtensions, coreExtensions));
240 extensionPtrs.resize(nonCoreExtensions.size());
242 for (size_t ndx = 0; ndx < nonCoreExtensions.size(); ++ndx)
243 extensionPtrs[ndx] = nonCoreExtensions[ndx].c_str();
245 // VK_KHR_get_physical_device_propeties2 is used if enabledFeatures.pNext != 0
247 queueInfo.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
248 queueInfo.pNext = enabledFeatures.pNext ? &enabledFeatures : DE_NULL;
249 queueInfo.flags = (VkDeviceQueueCreateFlags)0u;
250 queueInfo.queueFamilyIndex = queueIndex;
251 queueInfo.queueCount = 1u;
252 queueInfo.pQueuePriorities = &queuePriority;
254 deviceInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
255 deviceInfo.pNext = DE_NULL;
256 deviceInfo.queueCreateInfoCount = 1u;
257 deviceInfo.pQueueCreateInfos = &queueInfo;
258 deviceInfo.enabledExtensionCount = (deUint32)extensionPtrs.size();
259 deviceInfo.ppEnabledExtensionNames = (extensionPtrs.empty() ? DE_NULL : &extensionPtrs[0]);
260 deviceInfo.enabledLayerCount = (deUint32)layerPtrs.size();
261 deviceInfo.ppEnabledLayerNames = (layerPtrs.empty() ? DE_NULL : &layerPtrs[0]);
262 deviceInfo.pEnabledFeatures = enabledFeatures.pNext ? DE_NULL : &enabledFeatures.features;
264 return createDevice(vki, physicalDevice, &deviceInfo);
267 bool isPhysicalDeviceFeatures2Supported (const deUint32 version, const vector<string>& instanceExtensions)
269 return isInstanceExtensionSupported(version, instanceExtensions, "VK_KHR_get_physical_device_properties");
272 struct DeviceFeatures
274 VkPhysicalDeviceFeatures2 coreFeatures;
275 VkPhysicalDeviceSamplerYcbcrConversionFeatures samplerYCbCrConversionFeatures;
277 DeviceFeatures (const InstanceInterface& vki,
278 const deUint32 apiVersion,
279 VkPhysicalDevice physicalDevice,
280 const vector<string>& instanceExtensions,
281 const vector<string>& deviceExtensions)
283 void** curExtPoint = &coreFeatures.pNext;
285 deMemset(&coreFeatures, 0, sizeof(coreFeatures));
286 deMemset(&samplerYCbCrConversionFeatures, 0, sizeof(samplerYCbCrConversionFeatures));
288 coreFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
289 samplerYCbCrConversionFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES_KHR;
291 if (isPhysicalDeviceFeatures2Supported(apiVersion, instanceExtensions))
293 if (de::contains(deviceExtensions.begin(), deviceExtensions.end(), "VK_KHR_sampler_ycbcr_conversion"))
295 *curExtPoint = &samplerYCbCrConversionFeatures;
296 curExtPoint = &samplerYCbCrConversionFeatures.pNext;
299 vki.getPhysicalDeviceFeatures2(physicalDevice, &coreFeatures);
302 coreFeatures.features = getPhysicalDeviceFeatures(vki, physicalDevice);
304 // Disable robustness by default, as it has an impact on performance on some HW.
305 coreFeatures.features.robustBufferAccess = false;
314 DefaultDevice (const PlatformInterface& vkPlatform, const tcu::CommandLine& cmdLine);
315 ~DefaultDevice (void);
317 VkInstance getInstance (void) const { return *m_instance; }
318 const InstanceInterface& getInstanceInterface (void) const { return m_instanceInterface; }
319 deUint32 getInstanceVersion (void) const { return m_instanceVersion; }
320 const vector<string>& getInstanceExtensions (void) const { return m_instanceExtensions; }
322 VkPhysicalDevice getPhysicalDevice (void) const { return m_physicalDevice; }
323 deUint32 getDeviceVersion (void) const { return m_deviceVersion; }
324 const VkPhysicalDeviceFeatures& getDeviceFeatures (void) const { return m_deviceFeatures; }
325 const VkPhysicalDeviceFeatures2& getDeviceFeatures2 (void) const { return m_deviceFeatures2; }
326 VkDevice getDevice (void) const { return *m_device; }
327 const DeviceInterface& getDeviceInterface (void) const { return m_deviceInterface; }
328 const VkPhysicalDeviceProperties& getDeviceProperties (void) const { return m_deviceProperties; }
329 const vector<string>& getDeviceExtensions (void) const { return m_deviceExtensions; }
331 deUint32 getUsedApiVersion (void) const { return m_usedApiVersion; }
333 deUint32 getUniversalQueueFamilyIndex (void) const { return m_universalQueueFamilyIndex; }
334 VkQueue getUniversalQueue (void) const;
337 static VkPhysicalDeviceFeatures filterDefaultDeviceFeatures (const VkPhysicalDeviceFeatures& deviceFeatures);
339 const deUint32 m_instanceVersion;
340 const vector<string> m_instanceExtensions;
341 const Unique<VkInstance> m_instance;
342 const InstanceDriver m_instanceInterface;
344 const VkPhysicalDevice m_physicalDevice;
346 const deUint32 m_deviceVersion;
347 const deUint32 m_usedApiVersion;
349 const deUint32 m_universalQueueFamilyIndex;
350 const VkPhysicalDeviceFeatures m_deviceFeatures;
351 const VkPhysicalDeviceFeatures2 m_deviceFeatures2;
352 const VkPhysicalDeviceProperties m_deviceProperties;
353 const vector<string> m_deviceExtensions;
355 const Unique<VkDevice> m_device;
356 const DeviceDriver m_deviceInterface;
360 DefaultDevice::DefaultDevice (const PlatformInterface& vkPlatform, const tcu::CommandLine& cmdLine)
361 : m_instanceVersion (getTargetInstanceVersion(vkPlatform))
362 , m_instanceExtensions (addCoreInstanceExtensions(filterExtensions(enumerateInstanceExtensionProperties(vkPlatform, DE_NULL)), m_instanceVersion))
363 , m_instance (createInstance(vkPlatform, m_instanceVersion, m_instanceExtensions, cmdLine))
364 , m_instanceInterface (vkPlatform, *m_instance)
365 , m_physicalDevice (chooseDevice(m_instanceInterface, *m_instance, cmdLine))
366 , m_deviceVersion (getPhysicalDeviceProperties(m_instanceInterface, m_physicalDevice).apiVersion)
367 , m_usedApiVersion (deMin32(m_instanceVersion, m_deviceVersion))
368 , m_universalQueueFamilyIndex (findQueueFamilyIndexWithCaps(m_instanceInterface, m_physicalDevice, VK_QUEUE_GRAPHICS_BIT|VK_QUEUE_COMPUTE_BIT))
369 , m_deviceFeatures (filterDefaultDeviceFeatures(getPhysicalDeviceFeatures(m_instanceInterface, m_physicalDevice)))
370 , m_deviceFeatures2 (getPhysicalDeviceFeatures2(m_instanceInterface, m_physicalDevice))
371 , m_deviceProperties (getPhysicalDeviceProperties(m_instanceInterface, m_physicalDevice))
372 , m_deviceExtensions (addCoreDeviceExtensions(filterExtensions(enumerateDeviceExtensionProperties(m_instanceInterface, m_physicalDevice, DE_NULL)), m_deviceVersion))
373 , m_device (createDefaultDevice(m_instanceInterface, m_physicalDevice, m_deviceVersion, m_universalQueueFamilyIndex, m_deviceFeatures2, m_deviceExtensions, cmdLine))
374 , m_deviceInterface (m_instanceInterface, *m_device)
378 DefaultDevice::~DefaultDevice (void)
382 VkQueue DefaultDevice::getUniversalQueue (void) const
384 return getDeviceQueue(m_deviceInterface, *m_device, m_universalQueueFamilyIndex, 0);
387 VkPhysicalDeviceFeatures DefaultDevice::filterDefaultDeviceFeatures (const VkPhysicalDeviceFeatures& deviceFeatures)
389 VkPhysicalDeviceFeatures enabledDeviceFeatures = deviceFeatures;
391 // Disable robustness by default, as it has an impact on performance on some HW.
392 enabledDeviceFeatures.robustBufferAccess = false;
394 return enabledDeviceFeatures;
397 // Allocator utilities
399 vk::Allocator* createAllocator (DefaultDevice* device)
401 const VkPhysicalDeviceMemoryProperties memoryProperties = vk::getPhysicalDeviceMemoryProperties(device->getInstanceInterface(), device->getPhysicalDevice());
403 // \todo [2015-07-24 jarkko] support allocator selection/configuration from command line (or compile time)
404 return new SimpleAllocator(device->getDeviceInterface(), device->getDevice(), memoryProperties);
409 Context::Context (tcu::TestContext& testCtx,
410 const vk::PlatformInterface& platformInterface,
411 vk::ProgramCollection<vk::ProgramBinary>& progCollection)
412 : m_testCtx (testCtx)
413 , m_platformInterface (platformInterface)
414 , m_progCollection (progCollection)
415 , m_device (new DefaultDevice(m_platformInterface, testCtx.getCommandLine()))
416 , m_allocator (createAllocator(m_device.get()))
420 Context::~Context (void)
424 deUint32 Context::getInstanceVersion (void) const { return m_device->getInstanceVersion(); }
425 const vector<string>& Context::getInstanceExtensions (void) const { return m_device->getInstanceExtensions(); }
426 vk::VkInstance Context::getInstance (void) const { return m_device->getInstance(); }
427 const vk::InstanceInterface& Context::getInstanceInterface (void) const { return m_device->getInstanceInterface(); }
428 vk::VkPhysicalDevice Context::getPhysicalDevice (void) const { return m_device->getPhysicalDevice(); }
429 deUint32 Context::getDeviceVersion (void) const { return m_device->getDeviceVersion(); }
430 const vk::VkPhysicalDeviceFeatures& Context::getDeviceFeatures (void) const { return m_device->getDeviceFeatures(); }
431 const vk::VkPhysicalDeviceFeatures2& Context::getDeviceFeatures2 (void) const { return m_device->getDeviceFeatures2(); }
432 const vk::VkPhysicalDeviceProperties& Context::getDeviceProperties (void) const { return m_device->getDeviceProperties(); }
433 const vector<string>& Context::getDeviceExtensions (void) const { return m_device->getDeviceExtensions(); }
434 vk::VkDevice Context::getDevice (void) const { return m_device->getDevice(); }
435 const vk::DeviceInterface& Context::getDeviceInterface (void) const { return m_device->getDeviceInterface(); }
436 deUint32 Context::getUniversalQueueFamilyIndex (void) const { return m_device->getUniversalQueueFamilyIndex(); }
437 vk::VkQueue Context::getUniversalQueue (void) const { return m_device->getUniversalQueue(); }
438 vk::Allocator& Context::getDefaultAllocator (void) const { return *m_allocator; }
439 deUint32 Context::getUsedApiVersion (void) const { return m_device->getUsedApiVersion(); }
443 void TestCase::initPrograms (SourceCollections&) const