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"
41 // Default device utilities
47 vector<string> getValidationLayers (const vector<VkLayerProperties>& supportedLayers)
49 static const char* s_magicLayer = "VK_LAYER_LUNARG_standard_validation";
50 static const char* s_defaultLayers[] =
52 "VK_LAYER_GOOGLE_threading",
53 "VK_LAYER_LUNARG_parameter_validation",
54 "VK_LAYER_LUNARG_device_limits",
55 "VK_LAYER_LUNARG_object_tracker",
56 "VK_LAYER_LUNARG_image",
57 "VK_LAYER_LUNARG_core_validation",
58 "VK_LAYER_LUNARG_swapchain",
59 "VK_LAYER_GOOGLE_unique_objects"
62 vector<string> enabledLayers;
64 if (isLayerSupported(supportedLayers, RequiredLayer(s_magicLayer)))
65 enabledLayers.push_back(s_magicLayer);
68 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_defaultLayers); ++ndx)
70 if (isLayerSupported(supportedLayers, RequiredLayer(s_defaultLayers[ndx])))
71 enabledLayers.push_back(s_defaultLayers[ndx]);
78 vector<string> getValidationLayers (const PlatformInterface& vkp)
80 return getValidationLayers(enumerateInstanceLayerProperties(vkp));
83 vector<string> getValidationLayers (const InstanceInterface& vki, VkPhysicalDevice physicalDevice)
85 return getValidationLayers(enumerateDeviceLayerProperties(vki, physicalDevice));
88 vector<string> filterExtensions(const vector<VkExtensionProperties>& deviceExtensions)
90 vector<string> enabledExtensions;
91 const char* extensionGroups[] =
98 for (size_t deviceExtNdx = 0; deviceExtNdx < deviceExtensions.size(); deviceExtNdx++)
100 for (int extGroupNdx = 0; extGroupNdx < DE_LENGTH_OF_ARRAY(extensionGroups); extGroupNdx++)
102 if (deStringBeginsWith(deviceExtensions[deviceExtNdx].extensionName, extensionGroups[extGroupNdx]))
103 enabledExtensions.push_back(deviceExtensions[deviceExtNdx].extensionName);
107 return enabledExtensions;
110 Move<VkInstance> createInstance (const PlatformInterface& vkp, const vector<string>& enabledExtensions, const tcu::CommandLine& cmdLine)
112 const bool isValidationEnabled = cmdLine.isValidationEnabled();
113 vector<string> enabledLayers;
115 if (isValidationEnabled)
117 if (!isDebugReportSupported(vkp))
118 TCU_THROW(NotSupportedError, "VK_EXT_debug_report is not supported");
120 enabledLayers = getValidationLayers(vkp);
121 if (enabledLayers.empty())
122 TCU_THROW(NotSupportedError, "No validation layers found");
125 return createDefaultInstance(vkp, enabledLayers, enabledExtensions);
128 static deUint32 findQueueFamilyIndexWithCaps (const InstanceInterface& vkInstance, VkPhysicalDevice physicalDevice, VkQueueFlags requiredCaps)
130 const vector<VkQueueFamilyProperties> queueProps = getPhysicalDeviceQueueFamilyProperties(vkInstance, physicalDevice);
132 for (size_t queueNdx = 0; queueNdx < queueProps.size(); queueNdx++)
134 if ((queueProps[queueNdx].queueFlags & requiredCaps) == requiredCaps)
135 return (deUint32)queueNdx;
138 TCU_THROW(NotSupportedError, "No matching queue found");
141 Move<VkDevice> createDefaultDevice (const InstanceInterface& vki,
142 VkPhysicalDevice physicalDevice,
144 const VkPhysicalDeviceFeatures& enabledFeatures,
145 const vector<string>& enabledExtensions,
146 const tcu::CommandLine& cmdLine)
148 VkDeviceQueueCreateInfo queueInfo;
149 VkDeviceCreateInfo deviceInfo;
150 vector<string> enabledLayers;
151 vector<const char*> layerPtrs;
152 vector<const char*> extensionPtrs;
153 const float queuePriority = 1.0f;
155 deMemset(&queueInfo, 0, sizeof(queueInfo));
156 deMemset(&deviceInfo, 0, sizeof(deviceInfo));
158 if (cmdLine.isValidationEnabled())
160 enabledLayers = getValidationLayers(vki, physicalDevice);
161 if (enabledLayers.empty())
162 TCU_THROW(NotSupportedError, "No validation layers found");
165 layerPtrs.resize(enabledLayers.size());
167 for (size_t ndx = 0; ndx < enabledLayers.size(); ++ndx)
168 layerPtrs[ndx] = enabledLayers[ndx].c_str();
170 extensionPtrs.resize(enabledExtensions.size());
172 for (size_t ndx = 0; ndx < enabledExtensions.size(); ++ndx)
173 extensionPtrs[ndx] = enabledExtensions[ndx].c_str();
175 queueInfo.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
176 queueInfo.pNext = DE_NULL;
177 queueInfo.flags = (VkDeviceQueueCreateFlags)0u;
178 queueInfo.queueFamilyIndex = queueIndex;
179 queueInfo.queueCount = 1u;
180 queueInfo.pQueuePriorities = &queuePriority;
182 deviceInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
183 deviceInfo.pNext = DE_NULL;
184 deviceInfo.queueCreateInfoCount = 1u;
185 deviceInfo.pQueueCreateInfos = &queueInfo;
186 deviceInfo.enabledExtensionCount = (deUint32)extensionPtrs.size();
187 deviceInfo.ppEnabledExtensionNames = (extensionPtrs.empty() ? DE_NULL : &extensionPtrs[0]);
188 deviceInfo.enabledLayerCount = (deUint32)layerPtrs.size();
189 deviceInfo.ppEnabledLayerNames = (layerPtrs.empty() ? DE_NULL : &layerPtrs[0]);
190 deviceInfo.pEnabledFeatures = &enabledFeatures;
192 return createDevice(vki, physicalDevice, &deviceInfo);
198 DefaultDevice (const PlatformInterface& vkPlatform, const tcu::CommandLine& cmdLine);
199 ~DefaultDevice (void);
201 VkInstance getInstance (void) const { return *m_instance; }
202 const InstanceInterface& getInstanceInterface (void) const { return m_instanceInterface; }
203 const vector<string>& getInstanceExtensions (void) const { return m_instanceExtensions; }
205 VkPhysicalDevice getPhysicalDevice (void) const { return m_physicalDevice; }
206 const VkPhysicalDeviceFeatures& getDeviceFeatures (void) const { return m_deviceFeatures; }
207 VkDevice getDevice (void) const { return *m_device; }
208 const DeviceInterface& getDeviceInterface (void) const { return m_deviceInterface; }
209 const VkPhysicalDeviceProperties& getDeviceProperties (void) const { return m_deviceProperties; }
210 const vector<string>& getDeviceExtensions (void) const { return m_deviceExtensions; }
212 deUint32 getUniversalQueueFamilyIndex (void) const { return m_universalQueueFamilyIndex; }
213 VkQueue getUniversalQueue (void) const;
216 static VkPhysicalDeviceFeatures filterDefaultDeviceFeatures (const VkPhysicalDeviceFeatures& deviceFeatures);
218 const vector<string> m_instanceExtensions;
219 const Unique<VkInstance> m_instance;
220 const InstanceDriver m_instanceInterface;
222 const VkPhysicalDevice m_physicalDevice;
224 const deUint32 m_universalQueueFamilyIndex;
225 const VkPhysicalDeviceFeatures m_deviceFeatures;
226 const VkPhysicalDeviceProperties m_deviceProperties;
227 const vector<string> m_deviceExtensions;
229 const Unique<VkDevice> m_device;
230 const DeviceDriver m_deviceInterface;
233 DefaultDevice::DefaultDevice (const PlatformInterface& vkPlatform, const tcu::CommandLine& cmdLine)
234 : m_instanceExtensions (filterExtensions(enumerateInstanceExtensionProperties(vkPlatform, DE_NULL)))
235 , m_instance (createInstance(vkPlatform, m_instanceExtensions, cmdLine))
236 , m_instanceInterface (vkPlatform, *m_instance)
237 , m_physicalDevice (chooseDevice(m_instanceInterface, *m_instance, cmdLine))
238 , m_universalQueueFamilyIndex (findQueueFamilyIndexWithCaps(m_instanceInterface, m_physicalDevice, VK_QUEUE_GRAPHICS_BIT|VK_QUEUE_COMPUTE_BIT))
239 , m_deviceFeatures (filterDefaultDeviceFeatures(getPhysicalDeviceFeatures(m_instanceInterface, m_physicalDevice)))
240 , m_deviceProperties (getPhysicalDeviceProperties(m_instanceInterface, m_physicalDevice))
241 , m_deviceExtensions (filterExtensions(enumerateDeviceExtensionProperties(m_instanceInterface, m_physicalDevice, DE_NULL)))
242 , m_device (createDefaultDevice(m_instanceInterface, m_physicalDevice, m_universalQueueFamilyIndex, m_deviceFeatures, m_deviceExtensions, cmdLine))
243 , m_deviceInterface (m_instanceInterface, *m_device)
247 DefaultDevice::~DefaultDevice (void)
251 VkQueue DefaultDevice::getUniversalQueue (void) const
253 return getDeviceQueue(m_deviceInterface, *m_device, m_universalQueueFamilyIndex, 0);
256 VkPhysicalDeviceFeatures DefaultDevice::filterDefaultDeviceFeatures (const VkPhysicalDeviceFeatures& deviceFeatures)
258 VkPhysicalDeviceFeatures enabledDeviceFeatures = deviceFeatures;
260 // Disable robustness by default, as it has an impact on performance on some HW.
261 enabledDeviceFeatures.robustBufferAccess = false;
263 return enabledDeviceFeatures;
266 // Allocator utilities
268 vk::Allocator* createAllocator (DefaultDevice* device)
270 const VkPhysicalDeviceMemoryProperties memoryProperties = vk::getPhysicalDeviceMemoryProperties(device->getInstanceInterface(), device->getPhysicalDevice());
272 // \todo [2015-07-24 jarkko] support allocator selection/configuration from command line (or compile time)
273 return new SimpleAllocator(device->getDeviceInterface(), device->getDevice(), memoryProperties);
278 Context::Context (tcu::TestContext& testCtx,
279 const vk::PlatformInterface& platformInterface,
280 vk::ProgramCollection<vk::ProgramBinary>& progCollection)
281 : m_testCtx (testCtx)
282 , m_platformInterface (platformInterface)
283 , m_progCollection (progCollection)
284 , m_device (new DefaultDevice(m_platformInterface, testCtx.getCommandLine()))
285 , m_allocator (createAllocator(m_device.get()))
289 Context::~Context (void)
293 const vector<string>& Context::getInstanceExtensions (void) const { return m_device->getInstanceExtensions(); }
294 vk::VkInstance Context::getInstance (void) const { return m_device->getInstance(); }
295 const vk::InstanceInterface& Context::getInstanceInterface (void) const { return m_device->getInstanceInterface(); }
296 vk::VkPhysicalDevice Context::getPhysicalDevice (void) const { return m_device->getPhysicalDevice(); }
297 const vk::VkPhysicalDeviceFeatures& Context::getDeviceFeatures (void) const { return m_device->getDeviceFeatures(); }
298 const vk::VkPhysicalDeviceProperties& Context::getDeviceProperties (void) const { return m_device->getDeviceProperties(); }
299 const vector<string>& Context::getDeviceExtensions (void) const { return m_device->getDeviceExtensions(); }
300 vk::VkDevice Context::getDevice (void) const { return m_device->getDevice(); }
301 const vk::DeviceInterface& Context::getDeviceInterface (void) const { return m_device->getDeviceInterface(); }
302 deUint32 Context::getUniversalQueueFamilyIndex (void) const { return m_device->getUniversalQueueFamilyIndex(); }
303 vk::VkQueue Context::getUniversalQueue (void) const { return m_device->getUniversalQueue(); }
304 vk::Allocator& Context::getDefaultAllocator (void) const { return *m_allocator; }
308 void TestCase::initPrograms (SourceCollections&) const