Merge remote-tracking branch 'aosp/master' into HEAD
[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
34 #include "tcuCommandLine.hpp"
35
36 #include "deSTLUtil.hpp"
37 #include "deMemory.h"
38
39 namespace vkt
40 {
41
42 // Default device utilities
43
44 using std::vector;
45 using std::string;
46 using namespace vk;
47
48 namespace
49 {
50
51 vector<string> getValidationLayers (const vector<VkLayerProperties>& supportedLayers)
52 {
53         static const char*      s_magicLayer            = "VK_LAYER_LUNARG_standard_validation";
54         static const char*      s_defaultLayers[]       =
55         {
56                 "VK_LAYER_GOOGLE_threading",
57                 "VK_LAYER_LUNARG_parameter_validation",
58                 "VK_LAYER_LUNARG_device_limits",
59                 "VK_LAYER_LUNARG_object_tracker",
60                 "VK_LAYER_LUNARG_image",
61                 "VK_LAYER_LUNARG_core_validation",
62                 "VK_LAYER_LUNARG_swapchain",
63                 "VK_LAYER_GOOGLE_unique_objects"
64         };
65
66         vector<string>          enabledLayers;
67
68         if (isLayerSupported(supportedLayers, RequiredLayer(s_magicLayer)))
69                 enabledLayers.push_back(s_magicLayer);
70         else
71         {
72                 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_defaultLayers); ++ndx)
73                 {
74                         if (isLayerSupported(supportedLayers, RequiredLayer(s_defaultLayers[ndx])))
75                                 enabledLayers.push_back(s_defaultLayers[ndx]);
76                 }
77         }
78
79         return enabledLayers;
80 }
81
82 vector<string> getValidationLayers (const PlatformInterface& vkp)
83 {
84         return getValidationLayers(enumerateInstanceLayerProperties(vkp));
85 }
86
87 vector<string> getValidationLayers (const InstanceInterface& vki, VkPhysicalDevice physicalDevice)
88 {
89         return getValidationLayers(enumerateDeviceLayerProperties(vki, physicalDevice));
90 }
91
92 vector<string> filterExtensions(const vector<VkExtensionProperties>& deviceExtensions)
93 {
94         vector<string>  enabledExtensions;
95         const char*             extensionGroups[] =
96         {
97                 "VK_KHR_",
98                 "VK_EXT_",
99                 "VK_KHX_"
100         };
101
102         for (size_t deviceExtNdx = 0; deviceExtNdx < deviceExtensions.size(); deviceExtNdx++)
103         {
104                 for (int extGroupNdx = 0; extGroupNdx < DE_LENGTH_OF_ARRAY(extensionGroups); extGroupNdx++)
105                 {
106                         if (deStringBeginsWith(deviceExtensions[deviceExtNdx].extensionName, extensionGroups[extGroupNdx]))
107                                 enabledExtensions.push_back(deviceExtensions[deviceExtNdx].extensionName);
108                 }
109         }
110
111         return enabledExtensions;
112 }
113
114 Move<VkInstance> createInstance (const PlatformInterface& vkp, const vector<string>& enabledExtensions, const tcu::CommandLine& cmdLine)
115 {
116         const bool                                                      isValidationEnabled     = cmdLine.isValidationEnabled();
117         vector<string>                                          enabledLayers;
118
119         if (isValidationEnabled)
120         {
121                 if (!isDebugReportSupported(vkp))
122                         TCU_THROW(NotSupportedError, "VK_EXT_debug_report is not supported");
123
124                 enabledLayers = getValidationLayers(vkp);
125                 if (enabledLayers.empty())
126                         TCU_THROW(NotSupportedError, "No validation layers found");
127         }
128
129         return createDefaultInstance(vkp, enabledLayers, enabledExtensions);
130 }
131
132 static deUint32 findQueueFamilyIndexWithCaps (const InstanceInterface& vkInstance, VkPhysicalDevice physicalDevice, VkQueueFlags requiredCaps)
133 {
134         const vector<VkQueueFamilyProperties>   queueProps      = getPhysicalDeviceQueueFamilyProperties(vkInstance, physicalDevice);
135
136         for (size_t queueNdx = 0; queueNdx < queueProps.size(); queueNdx++)
137         {
138                 if ((queueProps[queueNdx].queueFlags & requiredCaps) == requiredCaps)
139                         return (deUint32)queueNdx;
140         }
141
142         TCU_THROW(NotSupportedError, "No matching queue found");
143 }
144
145 Move<VkDevice> createDefaultDevice (const InstanceInterface&                    vki,
146                                                                         VkPhysicalDevice                                        physicalDevice,
147                                                                         deUint32                                                        queueIndex,
148                                                                         deUint32                                                        sparseQueueIndex,
149                                                                         const VkPhysicalDeviceFeatures2KHR&     enabledFeatures,
150                                                                         const vector<string>&                           enabledExtensions,
151                                                                         const tcu::CommandLine&                         cmdLine)
152 {
153         VkDeviceQueueCreateInfo         queueInfo[2];
154         VkDeviceCreateInfo                      deviceInfo;
155         vector<string>                          enabledLayers;
156         vector<const char*>                     layerPtrs;
157         vector<const char*>                     extensionPtrs;
158         const float                                     queuePriority   = 1.0f;
159         const deUint32                          numQueues = enabledFeatures.features.sparseBinding ? 2 : 1;
160
161         deMemset(&queueInfo,    0, sizeof(queueInfo));
162         deMemset(&deviceInfo,   0, sizeof(deviceInfo));
163
164         if (cmdLine.isValidationEnabled())
165         {
166                 enabledLayers = getValidationLayers(vki, physicalDevice);
167                 if (enabledLayers.empty())
168                         TCU_THROW(NotSupportedError, "No validation layers found");
169         }
170
171         layerPtrs.resize(enabledLayers.size());
172
173         for (size_t ndx = 0; ndx < enabledLayers.size(); ++ndx)
174                 layerPtrs[ndx] = enabledLayers[ndx].c_str();
175
176         extensionPtrs.resize(enabledExtensions.size());
177
178         for (size_t ndx = 0; ndx < enabledExtensions.size(); ++ndx)
179                 extensionPtrs[ndx] = enabledExtensions[ndx].c_str();
180
181         queueInfo[0].sType                                              = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
182         queueInfo[0].pNext                                              = DE_NULL;
183         queueInfo[0].flags                                              = (VkDeviceQueueCreateFlags)0u;
184         queueInfo[0].queueFamilyIndex                   = queueIndex;
185         queueInfo[0].queueCount                                 = 1u;
186         queueInfo[0].pQueuePriorities                   = &queuePriority;
187
188         queueInfo[1].sType                                              = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
189         queueInfo[1].pNext                                              = DE_NULL;
190         queueInfo[1].flags                                              = (VkDeviceQueueCreateFlags)0u;
191         queueInfo[1].queueFamilyIndex                   = sparseQueueIndex;
192         queueInfo[1].queueCount                                 = 1u;
193         queueInfo[1].pQueuePriorities                   = &queuePriority;
194
195         // VK_KHR_get_physical_device_properties2 is used if enabledFeatures.pNext != 0
196         deviceInfo.sType                                                = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
197         deviceInfo.pNext                                                = enabledFeatures.pNext ? &enabledFeatures : DE_NULL;
198         deviceInfo.queueCreateInfoCount                 = numQueues;
199         deviceInfo.pQueueCreateInfos                    = queueInfo;
200         deviceInfo.enabledExtensionCount                = (deUint32)extensionPtrs.size();
201         deviceInfo.ppEnabledExtensionNames              = (extensionPtrs.empty() ? DE_NULL : &extensionPtrs[0]);
202         deviceInfo.enabledLayerCount                    = (deUint32)layerPtrs.size();
203         deviceInfo.ppEnabledLayerNames                  = (layerPtrs.empty() ? DE_NULL : &layerPtrs[0]);
204         deviceInfo.pEnabledFeatures                             = enabledFeatures.pNext ? DE_NULL : &enabledFeatures.features;
205
206         return createDevice(vki, physicalDevice, &deviceInfo);
207 };
208
209 bool isPhysicalDeviceFeatures2Supported (const vector<string>& instanceExtensions)
210 {
211         return de::contains(instanceExtensions.begin(), instanceExtensions.end(), "VK_KHR_get_physical_device_properties2");
212 }
213
214 struct DeviceFeatures
215 {
216         VkPhysicalDeviceFeatures2KHR                                            coreFeatures;
217         VkPhysicalDeviceSamplerYcbcrConversionFeaturesKHR       samplerYCbCrConversionFeatures;
218
219         DeviceFeatures (const InstanceInterface&        vki,
220                                         VkPhysicalDevice                        physicalDevice,
221                                         const vector<string>&           instanceExtensions,
222                                         const vector<string>&           deviceExtensions)
223         {
224                 void**  curExtPoint             = &coreFeatures.pNext;
225
226                 deMemset(&coreFeatures, 0, sizeof(coreFeatures));
227                 deMemset(&samplerYCbCrConversionFeatures, 0, sizeof(samplerYCbCrConversionFeatures));
228
229                 coreFeatures.sType                                              = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2_KHR;
230                 samplerYCbCrConversionFeatures.sType    = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES_KHR;
231
232                 if (isPhysicalDeviceFeatures2Supported(instanceExtensions))
233                 {
234                         if (de::contains(deviceExtensions.begin(), deviceExtensions.end(), "VK_KHR_sampler_ycbcr_conversion"))
235                         {
236                                 *curExtPoint = &samplerYCbCrConversionFeatures;
237                                 curExtPoint = &samplerYCbCrConversionFeatures.pNext;
238                         }
239
240                         vki.getPhysicalDeviceFeatures2KHR(physicalDevice, &coreFeatures);
241                 }
242                 else
243                         coreFeatures.features = getPhysicalDeviceFeatures(vki, physicalDevice);
244
245                 // Disable robustness by default, as it has an impact on performance on some HW.
246                 coreFeatures.features.robustBufferAccess = false;
247         }
248 };
249
250 } // anonymous
251
252 class DefaultDevice
253 {
254 public:
255                                                                                 DefaultDevice                                   (const PlatformInterface& vkPlatform, const tcu::CommandLine& cmdLine);
256                                                                                 ~DefaultDevice                                  (void);
257
258         VkInstance                                                      getInstance                                             (void) const    { return *m_instance;                                                           }
259         const InstanceInterface&                        getInstanceInterface                    (void) const    { return m_instanceInterface;                                           }
260         const vector<string>&                           getInstanceExtensions                   (void) const    { return m_instanceExtensions;                                          }
261
262         VkPhysicalDevice                                        getPhysicalDevice                               (void) const    { return m_physicalDevice;                                                      }
263         const VkPhysicalDeviceFeatures&         getDeviceFeatures                               (void) const    { return m_deviceFeatures.coreFeatures.features;        }
264         const VkPhysicalDeviceFeatures2KHR&     getDeviceFeatures2                              (void) const    { return m_deviceFeatures.coreFeatures;                         }
265         VkDevice                                                        getDevice                                               (void) const    { return *m_device;                                                                     }
266         const DeviceInterface&                          getDeviceInterface                              (void) const    { return m_deviceInterface;                                                     }
267         const VkPhysicalDeviceProperties&       getDeviceProperties                             (void) const    { return m_deviceProperties;                                            }
268         const vector<string>&                           getDeviceExtensions                             (void) const    { return m_deviceExtensions;                                            }
269
270         deUint32                                                        getUniversalQueueFamilyIndex    (void) const    { return m_universalQueueFamilyIndex;                           }
271         VkQueue                                                         getUniversalQueue                               (void) const;
272         deUint32                                                        getSparseQueueFamilyIndex               (void) const    { return m_sparseQueueFamilyIndex;                                      }
273         VkQueue                                                         getSparseQueue                                  (void) const;
274
275 private:
276         static VkPhysicalDeviceFeatures         filterDefaultDeviceFeatures             (const VkPhysicalDeviceFeatures& deviceFeatures);
277
278         const vector<string>                            m_instanceExtensions;
279         const Unique<VkInstance>                        m_instance;
280         const InstanceDriver                            m_instanceInterface;
281
282         const VkPhysicalDevice                          m_physicalDevice;
283         const vector<string>                            m_deviceExtensions;
284         const DeviceFeatures                            m_deviceFeatures;
285
286         const deUint32                                          m_universalQueueFamilyIndex;
287         const deUint32                                          m_sparseQueueFamilyIndex;
288         const VkPhysicalDeviceProperties        m_deviceProperties;
289
290         const Unique<VkDevice>                          m_device;
291         const DeviceDriver                                      m_deviceInterface;
292 };
293
294 DefaultDevice::DefaultDevice (const PlatformInterface& vkPlatform, const tcu::CommandLine& cmdLine)
295         : m_instanceExtensions                  (filterExtensions(enumerateInstanceExtensionProperties(vkPlatform, DE_NULL)))
296         , m_instance                                    (createInstance(vkPlatform, m_instanceExtensions, cmdLine))
297         , m_instanceInterface                   (vkPlatform, *m_instance)
298         , m_physicalDevice                              (chooseDevice(m_instanceInterface, *m_instance, cmdLine))
299         , m_deviceExtensions                    (filterExtensions(enumerateDeviceExtensionProperties(m_instanceInterface, m_physicalDevice, DE_NULL)))
300         , m_deviceFeatures                              (m_instanceInterface, m_physicalDevice, m_instanceExtensions, m_deviceExtensions)
301         , m_universalQueueFamilyIndex   (findQueueFamilyIndexWithCaps(m_instanceInterface, m_physicalDevice, VK_QUEUE_GRAPHICS_BIT|VK_QUEUE_COMPUTE_BIT))
302         , m_sparseQueueFamilyIndex              (m_deviceFeatures.coreFeatures.features.sparseBinding ? findQueueFamilyIndexWithCaps(m_instanceInterface, m_physicalDevice, VK_QUEUE_SPARSE_BINDING_BIT) : 0)
303         , m_deviceProperties                    (getPhysicalDeviceProperties(m_instanceInterface, m_physicalDevice))
304         , m_device                                              (createDefaultDevice(m_instanceInterface, m_physicalDevice, m_universalQueueFamilyIndex, m_sparseQueueFamilyIndex, m_deviceFeatures.coreFeatures, m_deviceExtensions, cmdLine))
305         , m_deviceInterface                             (m_instanceInterface, *m_device)
306 {
307 }
308
309 DefaultDevice::~DefaultDevice (void)
310 {
311 }
312
313 VkQueue DefaultDevice::getUniversalQueue (void) const
314 {
315         return getDeviceQueue(m_deviceInterface, *m_device, m_universalQueueFamilyIndex, 0);
316 }
317
318 VkQueue DefaultDevice::getSparseQueue (void) const
319 {
320         if (!m_deviceFeatures.coreFeatures.features.sparseBinding)
321                 TCU_THROW(NotSupportedError, "Sparse binding not supported.");
322
323         return getDeviceQueue(m_deviceInterface, *m_device, m_sparseQueueFamilyIndex, 0);
324 }
325
326 namespace
327 {
328 // Allocator utilities
329
330 vk::Allocator* createAllocator (DefaultDevice* device)
331 {
332         const VkPhysicalDeviceMemoryProperties memoryProperties = vk::getPhysicalDeviceMemoryProperties(device->getInstanceInterface(), device->getPhysicalDevice());
333
334         // \todo [2015-07-24 jarkko] support allocator selection/configuration from command line (or compile time)
335         return new SimpleAllocator(device->getDeviceInterface(), device->getDevice(), memoryProperties);
336 }
337
338 } // anonymous
339
340 // Context
341
342 Context::Context (tcu::TestContext&                                                     testCtx,
343                                   const vk::PlatformInterface&                          platformInterface,
344                                   vk::ProgramCollection<vk::ProgramBinary>&     progCollection)
345         : m_testCtx                             (testCtx)
346         , m_platformInterface   (platformInterface)
347         , m_progCollection              (progCollection)
348         , m_device                              (new DefaultDevice(m_platformInterface, testCtx.getCommandLine()))
349         , m_allocator                   (createAllocator(m_device.get()))
350 {
351 }
352
353 Context::~Context (void)
354 {
355 }
356
357 const vector<string>&                                   Context::getInstanceExtensions                  (void) const { return m_device->getInstanceExtensions();                }
358 vk::VkInstance                                                  Context::getInstance                                    (void) const { return m_device->getInstance();                                  }
359 const vk::InstanceInterface&                    Context::getInstanceInterface                   (void) const { return m_device->getInstanceInterface();                 }
360 vk::VkPhysicalDevice                                    Context::getPhysicalDevice                              (void) const { return m_device->getPhysicalDevice();                    }
361 const vk::VkPhysicalDeviceFeatures&             Context::getDeviceFeatures                              (void) const { return m_device->getDeviceFeatures();                    }
362 const vk::VkPhysicalDeviceFeatures2KHR& Context::getDeviceFeatures2                             (void) const { return m_device->getDeviceFeatures2();                   }
363 const vk::VkPhysicalDeviceProperties&   Context::getDeviceProperties                    (void) const { return m_device->getDeviceProperties();                  }
364 const vector<string>&                                   Context::getDeviceExtensions                    (void) const { return m_device->getDeviceExtensions();                  }
365 vk::VkDevice                                                    Context::getDevice                                              (void) const { return m_device->getDevice();                                    }
366 const vk::DeviceInterface&                              Context::getDeviceInterface                             (void) const { return m_device->getDeviceInterface();                   }
367 deUint32                                                                Context::getUniversalQueueFamilyIndex   (void) const { return m_device->getUniversalQueueFamilyIndex(); }
368 vk::VkQueue                                                             Context::getUniversalQueue                              (void) const { return m_device->getUniversalQueue();                    }
369 deUint32                                                                Context::getSparseQueueFamilyIndex              (void) const { return m_device->getSparseQueueFamilyIndex();    }
370 vk::VkQueue                                                             Context::getSparseQueue                                 (void) const { return m_device->getSparseQueue();                               }
371 vk::Allocator&                                                  Context::getDefaultAllocator                    (void) const { return *m_allocator;                                                             }
372
373 // TestCase
374
375 void TestCase::initPrograms (SourceCollections&) const
376 {
377 }
378
379 } // vkt