Merge vk-gl-cts/vulkan-cts-1.0.2 into vk-gl-cts/vulkan-cts-1.1.0
[platform/upstream/VK-GL-CTS.git] / external / vulkancts / modules / vulkan / vktTestCase.cpp
1 /*-------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2015 Google Inc.
6  *
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
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
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.
18  *
19  *//*!
20  * \file
21  * \brief Vulkan test case base classes
22  *//*--------------------------------------------------------------------*/
23
24 #include "vktTestCase.hpp"
25
26 #include "vkRef.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"
34
35 #include "tcuCommandLine.hpp"
36
37 #include "deSTLUtil.hpp"
38 #include "deMemory.h"
39
40 #include <set>
41
42 namespace vkt
43 {
44
45 // Default device utilities
46
47 using std::vector;
48 using std::string;
49 using std::set;
50 using namespace vk;
51
52 namespace
53 {
54
55 vector<string> getValidationLayers (const vector<VkLayerProperties>& supportedLayers)
56 {
57         static const char*      s_magicLayer            = "VK_LAYER_LUNARG_standard_validation";
58         static const char*      s_defaultLayers[]       =
59         {
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"
68         };
69
70         vector<string>          enabledLayers;
71
72         if (isLayerSupported(supportedLayers, RequiredLayer(s_magicLayer)))
73                 enabledLayers.push_back(s_magicLayer);
74         else
75         {
76                 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_defaultLayers); ++ndx)
77                 {
78                         if (isLayerSupported(supportedLayers, RequiredLayer(s_defaultLayers[ndx])))
79                                 enabledLayers.push_back(s_defaultLayers[ndx]);
80                 }
81         }
82
83         return enabledLayers;
84 }
85
86 vector<string> getValidationLayers (const PlatformInterface& vkp)
87 {
88         return getValidationLayers(enumerateInstanceLayerProperties(vkp));
89 }
90
91 vector<string> getValidationLayers (const InstanceInterface& vki, VkPhysicalDevice physicalDevice)
92 {
93         return getValidationLayers(enumerateDeviceLayerProperties(vki, physicalDevice));
94 }
95
96 vector<string> filterExtensions (const vector<VkExtensionProperties>& extensions)
97 {
98         vector<string>  enabledExtensions;
99         const char*             extensionGroups[] =
100         {
101                 "VK_KHR_",
102                 "VK_EXT_",
103                 "VK_KHX_"
104         };
105
106         for (size_t extNdx = 0; extNdx < extensions.size(); extNdx++)
107         {
108                 for (int extGroupNdx = 0; extGroupNdx < DE_LENGTH_OF_ARRAY(extensionGroups); extGroupNdx++)
109                 {
110                         if (deStringBeginsWith(extensions[extNdx].extensionName, extensionGroups[extGroupNdx]))
111                                 enabledExtensions.push_back(extensions[extNdx].extensionName);
112                 }
113         }
114
115         return enabledExtensions;
116 }
117
118 vector<string> addExtensions (const vector<string>& a, const vector<const char*>& b)
119 {
120         vector<string>  res             (a);
121
122         for (vector<const char*>::const_iterator bIter = b.begin(); bIter != b.end(); ++bIter)
123         {
124                 if (!de::contains(res.begin(), res.end(), string(*bIter)))
125                         res.push_back(string(*bIter));
126         }
127
128         return res;
129 }
130
131 vector<string> removeExtensions (const vector<string>& a, const vector<const char*>& b)
132 {
133         vector<string>  res;
134         set<string>             removeExts      (b.begin(), b.end());
135
136         for (vector<string>::const_iterator aIter = a.begin(); aIter != a.end(); ++aIter)
137         {
138                 if (!de::contains(removeExts, *aIter))
139                         res.push_back(*aIter);
140         }
141
142         return res;
143 }
144
145 vector<string> addCoreInstanceExtensions (const vector<string>& extensions, deUint32 instanceVersion)
146 {
147         vector<const char*> coreExtensions;
148         getCoreInstanceExtensions(instanceVersion, coreExtensions);
149         return addExtensions(extensions, coreExtensions);
150 }
151
152 vector<string> addCoreDeviceExtensions(const vector<string>& extensions, deUint32 instanceVersion)
153 {
154         vector<const char*> coreExtensions;
155         getCoreDeviceExtensions(instanceVersion, coreExtensions);
156         return addExtensions(extensions, coreExtensions);
157 }
158
159 deUint32 getTargetInstanceVersion (const PlatformInterface& vkp)
160 {
161         deUint32 version = pack(ApiVersion(1, 0, 0));
162         if (vkp.enumerateInstanceVersion(&version) != VK_SUCCESS)
163                 TCU_THROW(InternalError, "Enumerate instance version error");
164         return version;
165 }
166
167 Move<VkInstance> createInstance (const PlatformInterface& vkp, deUint32 apiVersion, const vector<string>& enabledExtensions, const tcu::CommandLine& cmdLine)
168 {
169         const bool              isValidationEnabled     = cmdLine.isValidationEnabled();
170         vector<string>  enabledLayers;
171
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));
177
178         if (isValidationEnabled)
179         {
180                 if (!isDebugReportSupported(vkp))
181                         TCU_THROW(NotSupportedError, "VK_EXT_debug_report is not supported");
182
183                 enabledLayers = getValidationLayers(vkp);
184                 if (enabledLayers.empty())
185                         TCU_THROW(NotSupportedError, "No validation layers found");
186         }
187
188         return createDefaultInstance(vkp, apiVersion, enabledLayers, nonCoreExtensions);
189 }
190
191 static deUint32 findQueueFamilyIndexWithCaps (const InstanceInterface& vkInstance, VkPhysicalDevice physicalDevice, VkQueueFlags requiredCaps)
192 {
193         const vector<VkQueueFamilyProperties>   queueProps      = getPhysicalDeviceQueueFamilyProperties(vkInstance, physicalDevice);
194
195         for (size_t queueNdx = 0; queueNdx < queueProps.size(); queueNdx++)
196         {
197                 if ((queueProps[queueNdx].queueFlags & requiredCaps) == requiredCaps)
198                         return (deUint32)queueNdx;
199         }
200
201         TCU_THROW(NotSupportedError, "No matching queue found");
202 }
203
204 Move<VkDevice> createDefaultDevice (const InstanceInterface&                    vki,
205                                                                         VkPhysicalDevice                                        physicalDevice,
206                                                                         const deUint32                                          apiVersion,
207                                                                         deUint32                                                        queueIndex,
208                                                                         const VkPhysicalDeviceFeatures2&        enabledFeatures,
209                                                                         const vector<string>&                           enabledExtensions,
210                                                                         const tcu::CommandLine&                         cmdLine)
211 {
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;
218
219         deMemset(&queueInfo,    0, sizeof(queueInfo));
220         deMemset(&deviceInfo,   0, sizeof(deviceInfo));
221
222         if (cmdLine.isValidationEnabled())
223         {
224                 enabledLayers = getValidationLayers(vki, physicalDevice);
225                 if (enabledLayers.empty())
226                         TCU_THROW(NotSupportedError, "No validation layers found");
227         }
228
229         layerPtrs.resize(enabledLayers.size());
230
231         for (size_t ndx = 0; ndx < enabledLayers.size(); ++ndx)
232                 layerPtrs[ndx] = enabledLayers[ndx].c_str();
233
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));
239
240         extensionPtrs.resize(nonCoreExtensions.size());
241
242         for (size_t ndx = 0; ndx < nonCoreExtensions.size(); ++ndx)
243                 extensionPtrs[ndx] = nonCoreExtensions[ndx].c_str();
244
245         // VK_KHR_get_physical_device_propeties2 is used if enabledFeatures.pNext != 0
246
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;
253
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;
263
264         return createDevice(vki, physicalDevice, &deviceInfo);
265 };
266
267 bool isPhysicalDeviceFeatures2Supported (const deUint32 version, const vector<string>& instanceExtensions)
268 {
269         return isInstanceExtensionSupported(version, instanceExtensions, "VK_KHR_get_physical_device_properties2");
270 }
271
272 class DeviceFeatures
273 {
274 public:
275         VkPhysicalDeviceFeatures2                                               coreFeatures;
276         VkPhysicalDeviceSamplerYcbcrConversionFeatures  samplerYCbCrConversionFeatures;
277
278         DeviceFeatures (const InstanceInterface&        vki,
279                                         const deUint32                          apiVersion,
280                                         const VkPhysicalDevice&         physicalDevice,
281                                         const vector<string>&           instanceExtensions,
282                                         const vector<string>&           deviceExtensions)
283         {
284                 deMemset(&coreFeatures, 0, sizeof(coreFeatures));
285                 deMemset(&samplerYCbCrConversionFeatures, 0, sizeof(samplerYCbCrConversionFeatures));
286
287                 coreFeatures.sType                                              = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
288                 samplerYCbCrConversionFeatures.sType    = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES;
289
290                 if (isPhysicalDeviceFeatures2Supported(apiVersion, instanceExtensions))
291                 {
292                         if (de::contains(deviceExtensions.begin(), deviceExtensions.end(), "VK_KHR_sampler_ycbcr_conversion"))
293                                 coreFeatures.pNext = &samplerYCbCrConversionFeatures;
294
295                         vki.getPhysicalDeviceFeatures2(physicalDevice, &coreFeatures);
296                 }
297                 else
298                         coreFeatures.features = getPhysicalDeviceFeatures(vki, physicalDevice);
299
300                 // Disable robustness by default, as it has an impact on performance on some HW.
301                 coreFeatures.features.robustBufferAccess = false;
302         }
303 };
304
305 } // anonymous
306
307 class DefaultDevice
308 {
309 public:
310                                                                                                                         DefaultDevice                                           (const PlatformInterface& vkPlatform, const tcu::CommandLine& cmdLine);
311                                                                                                                         ~DefaultDevice                                          (void);
312
313         VkInstance                                                                                              getInstance                                                     (void) const    { return *m_instance;                                                                           }
314         const InstanceInterface&                                                                getInstanceInterface                            (void) const    { return m_instanceInterface;                                                           }
315         deUint32                                                                                                getInstanceVersion                                      (void) const    { return m_instanceVersion;                                                                     }
316         const vector<string>&                                                                   getInstanceExtensions                           (void) const    { return m_instanceExtensions;                                                          }
317
318         VkPhysicalDevice                                                                                getPhysicalDevice                                       (void) const    { return m_physicalDevice;                                                                      }
319         deUint32                                                                                                getDeviceVersion                                        (void) const    { return m_deviceVersion;                                                                       }
320         const VkPhysicalDeviceFeatures&                                                 getDeviceFeatures                                       (void) const    { return m_deviceFeatures.coreFeatures.features;                        }
321         const VkPhysicalDeviceFeatures2&                                                getDeviceFeatures2                                      (void) const    { return m_deviceFeatures.coreFeatures; }
322         const VkPhysicalDeviceSamplerYcbcrConversionFeatures&   getSamplerYCbCrConversionFeatures       (void) const    { return m_deviceFeatures.samplerYCbCrConversionFeatures;       }
323         VkDevice                                                                                                getDevice                                                       (void) const    { return *m_device;                                                                                     }
324         const DeviceInterface&                                                                  getDeviceInterface                                      (void) const    { return m_deviceInterface;                                                                     }
325         const VkPhysicalDeviceProperties&                                               getDeviceProperties                                     (void) const    { return m_deviceProperties;                                                            }
326         const vector<string>&                                                                   getDeviceExtensions                                     (void) const    { return m_deviceExtensions;                                                            }
327
328         deUint32                                                                                                getUsedApiVersion                                       (void) const    { return m_usedApiVersion;                                                                      }
329
330         deUint32                                                                                                getUniversalQueueFamilyIndex            (void) const    { return m_universalQueueFamilyIndex;                                           }
331         VkQueue                                                                                                 getUniversalQueue                                       (void) const;
332
333 private:
334
335         const deUint32                                          m_instanceVersion;
336         const vector<string>                            m_instanceExtensions;
337         const Unique<VkInstance>                        m_instance;
338         const InstanceDriver                            m_instanceInterface;
339
340         const VkPhysicalDevice                          m_physicalDevice;
341
342         const deUint32                                          m_deviceVersion;
343         const deUint32                                          m_usedApiVersion;
344
345         const deUint32                                          m_universalQueueFamilyIndex;
346         const VkPhysicalDeviceProperties        m_deviceProperties;
347
348         const vector<string>                            m_deviceExtensions;
349         const DeviceFeatures                            m_deviceFeatures;
350
351         const Unique<VkDevice>                          m_device;
352         const DeviceDriver                                      m_deviceInterface;
353
354 };
355
356 DefaultDevice::DefaultDevice (const PlatformInterface& vkPlatform, const tcu::CommandLine& cmdLine)
357         : m_instanceVersion                             (getTargetInstanceVersion(vkPlatform))
358         , m_instanceExtensions                  (addCoreInstanceExtensions(filterExtensions(enumerateInstanceExtensionProperties(vkPlatform, DE_NULL)), m_instanceVersion))
359         , m_instance                                    (createInstance(vkPlatform, m_instanceVersion, m_instanceExtensions, cmdLine))
360         , m_instanceInterface                   (vkPlatform, *m_instance)
361         , m_physicalDevice                              (chooseDevice(m_instanceInterface, *m_instance, cmdLine))
362         , m_deviceVersion                               (getPhysicalDeviceProperties(m_instanceInterface, m_physicalDevice).apiVersion)
363         , m_usedApiVersion                              (deMin32(m_instanceVersion, m_deviceVersion))
364         , m_universalQueueFamilyIndex   (findQueueFamilyIndexWithCaps(m_instanceInterface, m_physicalDevice, VK_QUEUE_GRAPHICS_BIT|VK_QUEUE_COMPUTE_BIT))
365         , m_deviceProperties                    (getPhysicalDeviceProperties(m_instanceInterface, m_physicalDevice))
366         , m_deviceExtensions                    (addCoreDeviceExtensions(filterExtensions(enumerateDeviceExtensionProperties(m_instanceInterface, m_physicalDevice, DE_NULL)), m_usedApiVersion))
367         , m_deviceFeatures                              (m_instanceInterface, m_usedApiVersion, m_physicalDevice, m_instanceExtensions, m_deviceExtensions)
368         , m_device                                              (createDefaultDevice(m_instanceInterface, m_physicalDevice, m_usedApiVersion, m_universalQueueFamilyIndex, m_deviceFeatures.coreFeatures, m_deviceExtensions, cmdLine))
369         , m_deviceInterface                             (m_instanceInterface, *m_device)
370 {
371 }
372
373 DefaultDevice::~DefaultDevice (void)
374 {
375 }
376
377 VkQueue DefaultDevice::getUniversalQueue (void) const
378 {
379         return getDeviceQueue(m_deviceInterface, *m_device, m_universalQueueFamilyIndex, 0);
380 }
381
382 // Allocator utilities
383
384 vk::Allocator* createAllocator (DefaultDevice* device)
385 {
386         const VkPhysicalDeviceMemoryProperties memoryProperties = vk::getPhysicalDeviceMemoryProperties(device->getInstanceInterface(), device->getPhysicalDevice());
387
388         // \todo [2015-07-24 jarkko] support allocator selection/configuration from command line (or compile time)
389         return new SimpleAllocator(device->getDeviceInterface(), device->getDevice(), memoryProperties);
390 }
391
392 // Context
393
394 Context::Context (tcu::TestContext&                             testCtx,
395                                   const vk::PlatformInterface&  platformInterface,
396                                   vk::BinaryCollection&                 progCollection)
397         : m_testCtx                             (testCtx)
398         , m_platformInterface   (platformInterface)
399         , m_progCollection              (progCollection)
400         , m_device                              (new DefaultDevice(m_platformInterface, testCtx.getCommandLine()))
401         , m_allocator                   (createAllocator(m_device.get()))
402 {
403 }
404
405 Context::~Context (void)
406 {
407 }
408
409 deUint32                                                                Context::getInstanceVersion                             (void) const { return m_device->getInstanceVersion();                   }
410 const vector<string>&                                   Context::getInstanceExtensions                  (void) const { return m_device->getInstanceExtensions();                }
411 vk::VkInstance                                                  Context::getInstance                                    (void) const { return m_device->getInstance();                                  }
412 const vk::InstanceInterface&                    Context::getInstanceInterface                   (void) const { return m_device->getInstanceInterface();                 }
413 vk::VkPhysicalDevice                                    Context::getPhysicalDevice                              (void) const { return m_device->getPhysicalDevice();                    }
414 deUint32                                                                Context::getDeviceVersion                               (void) const { return m_device->getDeviceVersion();                             }
415 const vk::VkPhysicalDeviceFeatures&             Context::getDeviceFeatures                              (void) const { return m_device->getDeviceFeatures();                    }
416 const vk::VkPhysicalDeviceFeatures2&    Context::getDeviceFeatures2                             (void) const { return m_device->getDeviceFeatures2();                   }
417 const vk::VkPhysicalDeviceSamplerYcbcrConversionFeatures&
418                                                                                 Context::getSamplerYCbCrConversionFeatures
419                                                                                                                                                                 (void) const { return m_device->getSamplerYCbCrConversionFeatures();    }
420 const vk::VkPhysicalDeviceProperties&   Context::getDeviceProperties                    (void) const { return m_device->getDeviceProperties();                  }
421 const vector<string>&                                   Context::getDeviceExtensions                    (void) const { return m_device->getDeviceExtensions();                  }
422 vk::VkDevice                                                    Context::getDevice                                              (void) const { return m_device->getDevice();                                    }
423 const vk::DeviceInterface&                              Context::getDeviceInterface                             (void) const { return m_device->getDeviceInterface();                   }
424 deUint32                                                                Context::getUniversalQueueFamilyIndex   (void) const { return m_device->getUniversalQueueFamilyIndex(); }
425 vk::VkQueue                                                             Context::getUniversalQueue                              (void) const { return m_device->getUniversalQueue();                    }
426 vk::Allocator&                                                  Context::getDefaultAllocator                    (void) const { return *m_allocator;                                                             }
427 deUint32                                                                Context::getUsedApiVersion                              (void) const { return m_device->getUsedApiVersion();                    }
428
429 // TestCase
430
431 void TestCase::initPrograms (SourceCollections&) const
432 {
433 }
434
435 } // vkt