Update Vulkan Headers
[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 #include "vktCustomInstancesDevices.hpp"
26
27 #include "vkRef.hpp"
28 #include "vkRefUtil.hpp"
29 #include "vkQueryUtil.hpp"
30 #include "vkDeviceUtil.hpp"
31 #include "vkMemUtil.hpp"
32 #include "vkPlatform.hpp"
33 #include "vkDebugReportUtil.hpp"
34 #include "vkDeviceFeatures.hpp"
35 #include "vkDeviceProperties.hpp"
36
37 #include "tcuCommandLine.hpp"
38 #include "tcuTestLog.hpp"
39
40 #include "deSTLUtil.hpp"
41 #include "deMemory.h"
42
43 #include <set>
44
45 namespace vkt
46 {
47
48 // Default device utilities
49
50 using std::vector;
51 using std::string;
52 using std::set;
53 using namespace vk;
54
55 namespace
56 {
57
58 vector<string> filterExtensions (const vector<VkExtensionProperties>& extensions)
59 {
60         vector<string>  enabledExtensions;
61         bool                    khrBufferDeviceAddress  = false;
62
63         const char*             extensionGroups[]               =
64         {
65                 "VK_KHR_",
66                 "VK_EXT_",
67                 "VK_KHX_",
68                 "VK_NV_cooperative_matrix",
69                 "VK_NV_ray_tracing",
70                 "VK_AMD_mixed_attachment_samples",
71                 "VK_AMD_shader_fragment_mask",
72                 "VK_AMD_buffer_marker",
73                 "VK_AMD_shader_explicit_vertex_parameter",
74                 "VK_AMD_shader_image_load_store_lod",
75                 "VK_AMD_shader_trinary_minmax",
76                 "VK_AMD_texture_gather_bias_lod",
77                 "VK_ANDROID_external_memory_android_hardware_buffer",
78         };
79
80         for (size_t extNdx = 0; extNdx < extensions.size(); extNdx++)
81         {
82                 if (deStringEqual(extensions[extNdx].extensionName, "VK_KHR_buffer_device_address"))
83                 {
84                         khrBufferDeviceAddress = true;
85                         break;
86                 }
87         }
88
89         for (size_t extNdx = 0; extNdx < extensions.size(); extNdx++)
90         {
91                 const auto& extName = extensions[extNdx].extensionName;
92
93                 // Skip enabling VK_KHR_pipeline_library unless needed.
94                 if (deStringEqual(extName, "VK_KHR_pipeline_library"))
95                         continue;
96
97                 // VK_EXT_buffer_device_address is deprecated and must not be enabled if VK_KHR_buffer_device_address is enabled
98                 if (khrBufferDeviceAddress && deStringEqual(extName, "VK_EXT_buffer_device_address"))
99                         continue;
100
101                 for (int extGroupNdx = 0; extGroupNdx < DE_LENGTH_OF_ARRAY(extensionGroups); extGroupNdx++)
102                 {
103                         if (deStringBeginsWith(extName, extensionGroups[extGroupNdx]))
104                                 enabledExtensions.push_back(extName);
105                 }
106         }
107
108         return enabledExtensions;
109 }
110
111 vector<string> addExtensions (const vector<string>& a, const vector<const char*>& b)
112 {
113         vector<string>  res             (a);
114
115         for (vector<const char*>::const_iterator bIter = b.begin(); bIter != b.end(); ++bIter)
116         {
117                 if (!de::contains(res.begin(), res.end(), string(*bIter)))
118                         res.push_back(string(*bIter));
119         }
120
121         return res;
122 }
123
124 vector<string> removeExtensions (const vector<string>& a, const vector<const char*>& b)
125 {
126         vector<string>  res;
127         set<string>             removeExts      (b.begin(), b.end());
128
129         for (vector<string>::const_iterator aIter = a.begin(); aIter != a.end(); ++aIter)
130         {
131                 if (!de::contains(removeExts, *aIter))
132                         res.push_back(*aIter);
133         }
134
135         return res;
136 }
137
138 vector<string> addCoreInstanceExtensions (const vector<string>& extensions, deUint32 instanceVersion)
139 {
140         vector<const char*> coreExtensions;
141         getCoreInstanceExtensions(instanceVersion, coreExtensions);
142         return addExtensions(extensions, coreExtensions);
143 }
144
145 vector<string> addCoreDeviceExtensions(const vector<string>& extensions, deUint32 instanceVersion)
146 {
147         vector<const char*> coreExtensions;
148         getCoreDeviceExtensions(instanceVersion, coreExtensions);
149         return addExtensions(extensions, coreExtensions);
150 }
151
152 deUint32 getTargetInstanceVersion (const PlatformInterface& vkp)
153 {
154         deUint32 version = pack(ApiVersion(1, 0, 0));
155
156         if (vkp.enumerateInstanceVersion(&version) != VK_SUCCESS)
157                 TCU_THROW(InternalError, "Enumerate instance version error");
158         return version;
159 }
160
161 std::pair<deUint32, deUint32> determineDeviceVersions(const PlatformInterface& vkp, deUint32 apiVersion, const tcu::CommandLine& cmdLine)
162 {
163         Move<VkInstance>                                                preinstance                             = createDefaultInstance(vkp, apiVersion);
164         InstanceDriver                                                  preinterface                    (vkp, preinstance.get());
165
166         const vector<VkPhysicalDevice>                  devices                                 = enumeratePhysicalDevices(preinterface, preinstance.get());
167         deUint32                                                                lowestDeviceVersion             = 0xFFFFFFFFu;
168         for (deUint32 deviceNdx = 0u; deviceNdx < devices.size(); ++deviceNdx)
169         {
170                 const VkPhysicalDeviceProperties        props                                   = getPhysicalDeviceProperties(preinterface, devices[deviceNdx]);
171                 if (props.apiVersion < lowestDeviceVersion)
172                         lowestDeviceVersion = props.apiVersion;
173         }
174
175         const vk::VkPhysicalDevice                              choosenDevice                   = chooseDevice(preinterface, *preinstance, cmdLine);
176         const VkPhysicalDeviceProperties                props                                   = getPhysicalDeviceProperties(preinterface, choosenDevice);
177         const deUint32                                                  choosenDeviceVersion    = props.apiVersion;
178
179         return std::make_pair(choosenDeviceVersion, lowestDeviceVersion);
180 }
181
182
183 Move<VkInstance> createInstance (const PlatformInterface& vkp, deUint32 apiVersion, const vector<string>& enabledExtensions, const tcu::CommandLine& cmdLine)
184 {
185         const bool                                                              isValidationEnabled     = cmdLine.isValidationEnabled();
186         vector<const char*>                                             enabledLayers;
187
188         // \note Extensions in core are not explicitly enabled even though
189         //               they are in the extension list advertised to tests.
190         vector<const char*>                                             coreExtensions;
191         getCoreInstanceExtensions(apiVersion, coreExtensions);
192         vector<string>                                                  nonCoreExtensions       (removeExtensions(enabledExtensions, coreExtensions));
193
194         if (isValidationEnabled)
195         {
196                 if (!isDebugReportSupported(vkp))
197                         TCU_THROW(NotSupportedError, "VK_EXT_debug_report is not supported");
198
199                 enabledLayers = vkt::getValidationLayers(vkp);
200                 if (enabledLayers.empty())
201                         TCU_THROW(NotSupportedError, "No validation layers found");
202         }
203
204         return createDefaultInstance(vkp, apiVersion, vector<string>(begin(enabledLayers), end(enabledLayers)), nonCoreExtensions);
205 }
206
207 static deUint32 findQueueFamilyIndexWithCaps (const InstanceInterface& vkInstance, VkPhysicalDevice physicalDevice, VkQueueFlags requiredCaps)
208 {
209         const vector<VkQueueFamilyProperties>   queueProps      = getPhysicalDeviceQueueFamilyProperties(vkInstance, physicalDevice);
210
211         for (size_t queueNdx = 0; queueNdx < queueProps.size(); queueNdx++)
212         {
213                 if ((queueProps[queueNdx].queueFlags & requiredCaps) == requiredCaps)
214                         return (deUint32)queueNdx;
215         }
216
217         TCU_THROW(NotSupportedError, "No matching queue found");
218 }
219
220 Move<VkDevice> createDefaultDevice (const PlatformInterface&                    vkp,
221                                                                         VkInstance                                                      instance,
222                                                                         const InstanceInterface&                        vki,
223                                                                         VkPhysicalDevice                                        physicalDevice,
224                                                                         const deUint32                                          apiVersion,
225                                                                         deUint32                                                        queueIndex,
226                                                                         deUint32                                                        sparseQueueIndex,
227                                                                         const VkPhysicalDeviceFeatures2&        enabledFeatures,
228                                                                         const vector<string>&                           enabledExtensions,
229                                                                         const tcu::CommandLine&                         cmdLine)
230 {
231         VkDeviceQueueCreateInfo         queueInfo[2];
232         VkDeviceCreateInfo                      deviceInfo;
233         vector<const char*>                     enabledLayers;
234         vector<const char*>                     extensionPtrs;
235         const float                                     queuePriority   = 1.0f;
236         const deUint32                          numQueues = (enabledFeatures.features.sparseBinding && (queueIndex != sparseQueueIndex)) ? 2 : 1;
237
238         deMemset(&queueInfo,    0, sizeof(queueInfo));
239         deMemset(&deviceInfo,   0, sizeof(deviceInfo));
240
241         if (cmdLine.isValidationEnabled())
242         {
243                 enabledLayers = vkt::getValidationLayers(vki, physicalDevice);
244                 if (enabledLayers.empty())
245                         TCU_THROW(NotSupportedError, "No validation layers found");
246         }
247
248         // \note Extensions in core are not explicitly enabled even though
249         //               they are in the extension list advertised to tests.
250         vector<const char*> coreExtensions;
251         getCoreDeviceExtensions(apiVersion, coreExtensions);
252         vector<string>  nonCoreExtensions(removeExtensions(enabledExtensions, coreExtensions));
253
254         extensionPtrs.resize(nonCoreExtensions.size());
255
256         for (size_t ndx = 0; ndx < nonCoreExtensions.size(); ++ndx)
257                 extensionPtrs[ndx] = nonCoreExtensions[ndx].c_str();
258
259         queueInfo[0].sType                                              = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
260         queueInfo[0].pNext                                              = DE_NULL;
261         queueInfo[0].flags                                              = (VkDeviceQueueCreateFlags)0u;
262         queueInfo[0].queueFamilyIndex                   = queueIndex;
263         queueInfo[0].queueCount                                 = 1u;
264         queueInfo[0].pQueuePriorities                   = &queuePriority;
265
266         if (numQueues > 1)
267         {
268                 queueInfo[1].sType                                              = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
269                 queueInfo[1].pNext                                              = DE_NULL;
270                 queueInfo[1].flags                                              = (VkDeviceQueueCreateFlags)0u;
271                 queueInfo[1].queueFamilyIndex                   = sparseQueueIndex;
272                 queueInfo[1].queueCount                                 = 1u;
273                 queueInfo[1].pQueuePriorities                   = &queuePriority;
274         }
275
276         // VK_KHR_get_physical_device_properties2 is used if enabledFeatures.pNext != 0
277         deviceInfo.sType                                                = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
278         deviceInfo.pNext                                                = enabledFeatures.pNext ? &enabledFeatures : DE_NULL;
279         deviceInfo.queueCreateInfoCount                 = numQueues;
280         deviceInfo.pQueueCreateInfos                    = queueInfo;
281         deviceInfo.enabledExtensionCount                = (deUint32)extensionPtrs.size();
282         deviceInfo.ppEnabledExtensionNames              = (extensionPtrs.empty() ? DE_NULL : &extensionPtrs[0]);
283         deviceInfo.enabledLayerCount                    = (deUint32)enabledLayers.size();
284         deviceInfo.ppEnabledLayerNames                  = (enabledLayers.empty() ? DE_NULL : enabledLayers.data());
285         deviceInfo.pEnabledFeatures                             = enabledFeatures.pNext ? DE_NULL : &enabledFeatures.features;
286
287         return createDevice(vkp, instance, vki, physicalDevice, &deviceInfo);
288 };
289
290 } // anonymous
291
292 class DefaultDevice
293 {
294 public:
295                                                                                                                                         DefaultDevice                                                   (const PlatformInterface& vkPlatform, const tcu::CommandLine& cmdLine);
296                                                                                                                                         ~DefaultDevice                                                  (void);
297
298         VkInstance                                                                                                              getInstance                                                             (void) const { return *m_instance;                                                                                      }
299         const InstanceInterface&                                                                                getInstanceInterface                                    (void) const { return m_instanceInterface;                                                                      }
300         deUint32                                                                                                                getMaximumFrameworkVulkanVersion                (void) const { return m_maximumFrameworkVulkanVersion;                                          }
301         deUint32                                                                                                                getAvailableInstanceVersion                             (void) const { return m_availableInstanceVersion;                                                       }
302         deUint32                                                                                                                getUsedInstanceVersion                                  (void) const { return m_usedInstanceVersion;                                                            }
303         const vector<string>&                                                                                   getInstanceExtensions                                   (void) const { return m_instanceExtensions;                                                                     }
304
305         VkPhysicalDevice                                                                                                getPhysicalDevice                                               (void) const { return m_physicalDevice;                                                                         }
306         deUint32                                                                                                                getDeviceVersion                                                (void) const { return m_deviceVersion;                                                                          }
307
308         bool                                                                                                                    isDeviceFeatureInitialized                              (VkStructureType sType) const { return m_deviceFeatures.isDeviceFeatureInitialized(sType);              }
309         const VkPhysicalDeviceFeatures&                                                                 getDeviceFeatures                                               (void) const { return m_deviceFeatures.getCoreFeatures2().features;                     }
310         const VkPhysicalDeviceFeatures2&                                                                getDeviceFeatures2                                              (void) const { return m_deviceFeatures.getCoreFeatures2();                                      }
311         const VkPhysicalDeviceVulkan11Features&                                                 getVulkan11Features                                             (void) const { return m_deviceFeatures.getVulkan11Features();                           }
312         const VkPhysicalDeviceVulkan12Features&                                                 getVulkan12Features                                             (void) const { return m_deviceFeatures.getVulkan12Features();                           }
313
314 #include "vkDeviceFeaturesForDefaultDeviceDefs.inl"
315
316         bool                                                                                                                    isDevicePropertyInitialized                             (VkStructureType sType) const { return m_deviceProperties.isDevicePropertyInitialized(sType);   }
317         const VkPhysicalDeviceProperties&                                                               getDeviceProperties                                             (void) const { return m_deviceProperties.getCoreProperties2().properties;       }
318         const VkPhysicalDeviceProperties2&                                                              getDeviceProperties2                                    (void) const { return m_deviceProperties.getCoreProperties2();                          }
319         const VkPhysicalDeviceVulkan11Properties&                                               getDeviceVulkan11Properties                             (void) const { return m_deviceProperties.getVulkan11Properties();                       }
320         const VkPhysicalDeviceVulkan12Properties&                                               getDeviceVulkan12Properties                             (void) const { return m_deviceProperties.getVulkan12Properties();                       }
321
322 #include "vkDevicePropertiesForDefaultDeviceDefs.inl"
323
324         VkDevice                                                                                                                getDevice                                                               (void) const { return *m_device;                                                                                        }
325         const DeviceInterface&                                                                                  getDeviceInterface                                              (void) const { return m_deviceInterface;                                                                        }
326         const vector<string>&                                                                                   getDeviceExtensions                                             (void) const { return m_deviceExtensions;                                                                       }
327         deUint32                                                                                                                getUsedApiVersion                                               (void) const { return m_usedApiVersion;                                                                         }
328         deUint32                                                                                                                getUniversalQueueFamilyIndex                    (void) const { return m_universalQueueFamilyIndex;                                                      }
329         VkQueue                                                                                                                 getUniversalQueue                                               (void) const;
330         deUint32                                                                                                                getSparseQueueFamilyIndex                               (void) const { return m_sparseQueueFamilyIndex;                                                         }
331         VkQueue                                                                                                                 getSparseQueue                                                  (void) const;
332
333         bool                                                                                                                    hasDebugReportRecorder                                  (void) const { return m_debugReportRecorder.get() != nullptr;                           }
334         vk::DebugReportRecorder&                                                                                getDebugReportRecorder                                  (void) const { return *m_debugReportRecorder.get();                                                     }
335
336 private:
337         using DebugReportRecorderPtr            = de::UniquePtr<vk::DebugReportRecorder>;
338
339         const deUint32                                          m_maximumFrameworkVulkanVersion;
340         const deUint32                                          m_availableInstanceVersion;
341         const deUint32                                          m_usedInstanceVersion;
342
343         const std::pair<deUint32, deUint32> m_deviceVersions;
344         const deUint32                                          m_usedApiVersion;
345
346         const vector<string>                            m_instanceExtensions;
347         const Unique<VkInstance>                        m_instance;
348         const InstanceDriver                            m_instanceInterface;
349         const DebugReportRecorderPtr            m_debugReportRecorder;
350
351         const VkPhysicalDevice                          m_physicalDevice;
352         const deUint32                                          m_deviceVersion;
353
354         const vector<string>                            m_deviceExtensions;
355         const DeviceFeatures                            m_deviceFeatures;
356
357         const deUint32                                          m_universalQueueFamilyIndex;
358         const deUint32                                          m_sparseQueueFamilyIndex;
359         const DeviceProperties                          m_deviceProperties;
360
361         const Unique<VkDevice>                          m_device;
362         const DeviceDriver                                      m_deviceInterface;
363 };
364
365 namespace
366 {
367
368 deUint32 sanitizeApiVersion(deUint32 v)
369 {
370         return VK_MAKE_VERSION(VK_API_VERSION_MAJOR(v), VK_API_VERSION_MINOR(v), 0 );
371 }
372
373 de::MovePtr<vk::DebugReportRecorder> createDebugReportRecorder (const vk::PlatformInterface& vkp, const vk::InstanceInterface& vki, vk::VkInstance instance, bool printValidationErrors)
374 {
375         if (isDebugReportSupported(vkp))
376                 return de::MovePtr<vk::DebugReportRecorder>(new vk::DebugReportRecorder(vki, instance, printValidationErrors));
377         else
378                 TCU_THROW(NotSupportedError, "VK_EXT_debug_report is not supported");
379 }
380
381 } // anonymous
382
383 DefaultDevice::DefaultDevice (const PlatformInterface& vkPlatform, const tcu::CommandLine& cmdLine)
384         : m_maximumFrameworkVulkanVersion       (VK_API_MAX_FRAMEWORK_VERSION)
385         , m_availableInstanceVersion            (getTargetInstanceVersion(vkPlatform))
386         , m_usedInstanceVersion                         (sanitizeApiVersion(deMinu32(m_availableInstanceVersion, m_maximumFrameworkVulkanVersion)))
387         , m_deviceVersions                                      (determineDeviceVersions(vkPlatform, m_usedInstanceVersion, cmdLine))
388         , m_usedApiVersion                                      (sanitizeApiVersion(deMinu32(m_usedInstanceVersion, m_deviceVersions.first)))
389
390         , m_instanceExtensions                          (addCoreInstanceExtensions(filterExtensions(enumerateInstanceExtensionProperties(vkPlatform, DE_NULL)), m_usedApiVersion))
391         , m_instance                                            (createInstance(vkPlatform, m_usedApiVersion, m_instanceExtensions, cmdLine))
392
393         , m_instanceInterface                           (vkPlatform, *m_instance)
394         , m_debugReportRecorder                         (cmdLine.isValidationEnabled()
395                                                                                  ? createDebugReportRecorder(vkPlatform,
396                                                                                                                                          m_instanceInterface,
397                                                                                                                                          *m_instance,
398                                                                                                                                          cmdLine.printValidationErrors())
399                                                                                  : de::MovePtr<vk::DebugReportRecorder>(DE_NULL))
400         , m_physicalDevice                                      (chooseDevice(m_instanceInterface, *m_instance, cmdLine))
401         , m_deviceVersion                                       (getPhysicalDeviceProperties(m_instanceInterface, m_physicalDevice).apiVersion)
402
403         , m_deviceExtensions                            (addCoreDeviceExtensions(filterExtensions(enumerateDeviceExtensionProperties(m_instanceInterface, m_physicalDevice, DE_NULL)), m_usedApiVersion))
404         , m_deviceFeatures                                      (m_instanceInterface, m_usedApiVersion, m_physicalDevice, m_instanceExtensions, m_deviceExtensions)
405         , m_universalQueueFamilyIndex           (findQueueFamilyIndexWithCaps(m_instanceInterface, m_physicalDevice, VK_QUEUE_GRAPHICS_BIT|VK_QUEUE_COMPUTE_BIT))
406         , m_sparseQueueFamilyIndex                      (m_deviceFeatures.getCoreFeatures2().features.sparseBinding ? findQueueFamilyIndexWithCaps(m_instanceInterface, m_physicalDevice, VK_QUEUE_SPARSE_BINDING_BIT) : 0)
407         , m_deviceProperties                            (m_instanceInterface, m_usedApiVersion, m_physicalDevice, m_instanceExtensions, m_deviceExtensions)
408         , m_device                                                      (createDefaultDevice(vkPlatform, *m_instance, m_instanceInterface, m_physicalDevice, m_usedApiVersion, m_universalQueueFamilyIndex, m_sparseQueueFamilyIndex, m_deviceFeatures.getCoreFeatures2(), m_deviceExtensions, cmdLine))
409         , m_deviceInterface                                     (vkPlatform, *m_instance, *m_device)
410 {
411         DE_ASSERT(m_deviceVersions.first == m_deviceVersion);
412 }
413
414 DefaultDevice::~DefaultDevice (void)
415 {
416 }
417
418 VkQueue DefaultDevice::getUniversalQueue (void) const
419 {
420         return getDeviceQueue(m_deviceInterface, *m_device, m_universalQueueFamilyIndex, 0);
421 }
422
423 VkQueue DefaultDevice::getSparseQueue (void) const
424 {
425         if (!m_deviceFeatures.getCoreFeatures2().features.sparseBinding)
426                 TCU_THROW(NotSupportedError, "Sparse binding not supported.");
427
428         return getDeviceQueue(m_deviceInterface, *m_device, m_sparseQueueFamilyIndex, 0);
429 }
430
431 namespace
432 {
433 // Allocator utilities
434
435 vk::Allocator* createAllocator (DefaultDevice* device)
436 {
437         const VkPhysicalDeviceMemoryProperties memoryProperties = vk::getPhysicalDeviceMemoryProperties(device->getInstanceInterface(), device->getPhysicalDevice());
438
439         // \todo [2015-07-24 jarkko] support allocator selection/configuration from command line (or compile time)
440         return new SimpleAllocator(device->getDeviceInterface(), device->getDevice(), memoryProperties);
441 }
442
443 } // anonymous
444
445 // Context
446
447 Context::Context (tcu::TestContext&                             testCtx,
448                                   const vk::PlatformInterface&  platformInterface,
449                                   vk::BinaryCollection&                 progCollection)
450         : m_testCtx                                     (testCtx)
451         , m_platformInterface           (platformInterface)
452         , m_progCollection                      (progCollection)
453         , m_device                                      (new DefaultDevice(m_platformInterface, testCtx.getCommandLine()))
454         , m_allocator                           (createAllocator(m_device.get()))
455         , m_resultSetOnValidation       (false)
456 {
457 }
458
459 Context::~Context (void)
460 {
461 }
462
463 deUint32                                                                                Context::getMaximumFrameworkVulkanVersion               (void) const { return m_device->getMaximumFrameworkVulkanVersion();                     }
464 deUint32                                                                                Context::getAvailableInstanceVersion                    (void) const { return m_device->getAvailableInstanceVersion();                          }
465 const vector<string>&                                                   Context::getInstanceExtensions                                  (void) const { return m_device->getInstanceExtensions();                                        }
466 vk::VkInstance                                                                  Context::getInstance                                                    (void) const { return m_device->getInstance();                                                          }
467 const vk::InstanceInterface&                                    Context::getInstanceInterface                                   (void) const { return m_device->getInstanceInterface();                                         }
468 vk::VkPhysicalDevice                                                    Context::getPhysicalDevice                                              (void) const { return m_device->getPhysicalDevice();                                            }
469 deUint32                                                                                Context::getDeviceVersion                                               (void) const { return m_device->getDeviceVersion();                                                     }
470 const vk::VkPhysicalDeviceFeatures&                             Context::getDeviceFeatures                                              (void) const { return m_device->getDeviceFeatures();                                            }
471 const vk::VkPhysicalDeviceFeatures2&                    Context::getDeviceFeatures2                                             (void) const { return m_device->getDeviceFeatures2();                                           }
472 const vk::VkPhysicalDeviceVulkan11Features&             Context::getDeviceVulkan11Features                              (void) const { return m_device->getVulkan11Features();                                          }
473 const vk::VkPhysicalDeviceVulkan12Features&             Context::getDeviceVulkan12Features                              (void) const { return m_device->getVulkan12Features();                                          }
474
475 bool Context::isDeviceFunctionalitySupported (const std::string& extension) const
476 {
477         // check if extension was promoted to core
478         deUint32 apiVersion = getUsedApiVersion();
479         if (isCoreDeviceExtension(apiVersion, extension))
480         {
481                 if (apiVersion < VK_MAKE_VERSION(1, 2, 0))
482                 {
483                         // Check feature bits in extension-specific structures.
484                         if (extension == "VK_KHR_multiview")
485                                 return !!m_device->getMultiviewFeatures().multiview;
486                         if (extension == "VK_KHR_variable_pointers")
487                                 return !!m_device->getVariablePointersFeatures().variablePointersStorageBuffer;
488                         if (extension == "VK_KHR_sampler_ycbcr_conversion")
489                                 return !!m_device->getSamplerYcbcrConversionFeatures().samplerYcbcrConversion;
490                         if (extension == "VK_KHR_shader_draw_parameters")
491                                 return !!m_device->getShaderDrawParametersFeatures().shaderDrawParameters;
492                 }
493                 else
494                 {
495                         // Check feature bits using the new Vulkan 1.2 structures.
496                         const auto& vk11Features = m_device->getVulkan11Features();
497                         if (extension == "VK_KHR_multiview")
498                                 return !!vk11Features.multiview;
499                         if (extension == "VK_KHR_variable_pointers")
500                                 return !!vk11Features.variablePointersStorageBuffer;
501                         if (extension == "VK_KHR_sampler_ycbcr_conversion")
502                                 return !!vk11Features.samplerYcbcrConversion;
503                         if (extension == "VK_KHR_shader_draw_parameters")
504                                 return !!vk11Features.shaderDrawParameters;
505
506                         const auto& vk12Features = m_device->getVulkan12Features();
507                         if (extension == "VK_KHR_timeline_semaphore")
508                                 return !!vk12Features.timelineSemaphore;
509                         if (extension == "VK_KHR_buffer_device_address")
510                                 return !!vk12Features.bufferDeviceAddress;
511                         if (extension == "VK_EXT_descriptor_indexing")
512                                 return !!vk12Features.descriptorIndexing;
513                         if (extension == "VK_KHR_draw_indirect_count")
514                                 return !!vk12Features.drawIndirectCount;
515                         if (extension == "VK_KHR_sampler_mirror_clamp_to_edge")
516                                 return !!vk12Features.samplerMirrorClampToEdge;
517                         if (extension == "VK_EXT_sampler_filter_minmax")
518                                 return !!vk12Features.samplerFilterMinmax;
519                         if (extension == "VK_EXT_shader_viewport_index_layer")
520                                 return !!vk12Features.shaderOutputViewportIndex && !!vk12Features.shaderOutputLayer;
521                 }
522
523                 // No feature flags to check.
524                 return true;
525         }
526
527         // check if extension is on the lits of extensions for current device
528         const auto& extensions = getDeviceExtensions();
529         if (de::contains(extensions.begin(), extensions.end(), extension))
530         {
531                 if (extension == "VK_KHR_timeline_semaphore")
532                         return !!getTimelineSemaphoreFeatures().timelineSemaphore;
533                 if (extension == "VK_KHR_synchronization2")
534                         return !!getSynchronization2Features().synchronization2;
535                 if (extension == "VK_EXT_extended_dynamic_state")
536                         return !!getExtendedDynamicStateFeaturesEXT().extendedDynamicState;
537                 if (extension == "VK_EXT_shader_demote_to_helper_invocation")
538                         return !!getShaderDemoteToHelperInvocationFeaturesEXT().shaderDemoteToHelperInvocation;
539                 if (extension == "VK_KHR_workgroup_memory_explicit_layout")
540                         return !!getWorkgroupMemoryExplicitLayoutFeatures().workgroupMemoryExplicitLayout;
541
542                 return true;
543         }
544
545         return false;
546 }
547
548 bool Context::isInstanceFunctionalitySupported(const std::string& extension) const
549 {
550         // NOTE: current implementation uses isInstanceExtensionSupported but
551         // this will change when some instance extensions will be promoted to the
552         // core; don't use isInstanceExtensionSupported directly, use this method instead
553         return isInstanceExtensionSupported(getUsedApiVersion(), getInstanceExtensions(), extension);
554 }
555
556 #include "vkDeviceFeaturesForContextDefs.inl"
557
558 const vk::VkPhysicalDeviceProperties&                   Context::getDeviceProperties                            (void) const { return m_device->getDeviceProperties();                  }
559 const vk::VkPhysicalDeviceProperties2&                  Context::getDeviceProperties2                           (void) const { return m_device->getDeviceProperties2();                 }
560 const vk::VkPhysicalDeviceVulkan11Properties&   Context::getDeviceVulkan11Properties            (void) const { return m_device->getDeviceVulkan11Properties();  }
561 const vk::VkPhysicalDeviceVulkan12Properties&   Context::getDeviceVulkan12Properties            (void) const { return m_device->getDeviceVulkan12Properties();  }
562
563 #include "vkDevicePropertiesForContextDefs.inl"
564
565 const vector<string>&                                   Context::getDeviceExtensions                            (void) const { return m_device->getDeviceExtensions();                  }
566 vk::VkDevice                                                    Context::getDevice                                                      (void) const { return m_device->getDevice();                                    }
567 const vk::DeviceInterface&                              Context::getDeviceInterface                                     (void) const { return m_device->getDeviceInterface();                   }
568 deUint32                                                                Context::getUniversalQueueFamilyIndex           (void) const { return m_device->getUniversalQueueFamilyIndex(); }
569 vk::VkQueue                                                             Context::getUniversalQueue                                      (void) const { return m_device->getUniversalQueue();                    }
570 deUint32                                                                Context::getSparseQueueFamilyIndex                      (void) const { return m_device->getSparseQueueFamilyIndex();    }
571 vk::VkQueue                                                             Context::getSparseQueue                                         (void) const { return m_device->getSparseQueue();                               }
572 vk::Allocator&                                                  Context::getDefaultAllocator                            (void) const { return *m_allocator;                                                             }
573 deUint32                                                                Context::getUsedApiVersion                                      (void) const { return m_device->getUsedApiVersion();                    }
574 bool                                                                    Context::contextSupports                                        (const deUint32 majorNum, const deUint32 minorNum, const deUint32 patchNum) const
575                                                                                                                                                                                         { return m_device->getUsedApiVersion() >= VK_MAKE_VERSION(majorNum, minorNum, patchNum); }
576 bool                                                                    Context::contextSupports                                        (const ApiVersion version) const
577                                                                                                                                                                                         { return m_device->getUsedApiVersion() >= pack(version); }
578 bool                                                                    Context::contextSupports                                        (const deUint32 requiredApiVersionBits) const
579                                                                                                                                                                                         { return m_device->getUsedApiVersion() >= requiredApiVersionBits; }
580 bool                                                                    Context::isDeviceFeatureInitialized                     (vk::VkStructureType sType) const
581                                                                                                                                                                                         { return m_device->isDeviceFeatureInitialized(sType);   }
582 bool                                                                    Context::isDevicePropertyInitialized            (vk::VkStructureType sType) const
583                                                                                                                                                                                         { return m_device->isDevicePropertyInitialized(sType);  }
584
585 bool Context::requireDeviceFunctionality (const std::string& required) const
586 {
587         if (!isDeviceFunctionalitySupported(required))
588                 TCU_THROW(NotSupportedError, required + " is not supported");
589
590         return true;
591 }
592
593 bool Context::requireInstanceFunctionality (const std::string& required) const
594 {
595         if (!isInstanceFunctionalitySupported(required))
596                 TCU_THROW(NotSupportedError, required + " is not supported");
597
598         return true;
599 }
600
601 struct DeviceCoreFeaturesTable
602 {
603         const char*             featureName;
604         const deUint32  featureArrayIndex;
605         const deUint32  featureArrayOffset;
606 };
607
608 #define DEVICE_CORE_FEATURE_OFFSET(FEATURE_FIELD_NAME)  DE_OFFSET_OF(VkPhysicalDeviceFeatures, FEATURE_FIELD_NAME)
609 #define DEVICE_CORE_FEATURE_ENTRY(BITNAME, FIELDNAME)   { #FIELDNAME, BITNAME, DEVICE_CORE_FEATURE_OFFSET(FIELDNAME) }
610
611 const DeviceCoreFeaturesTable   deviceCoreFeaturesTable[] =
612 {
613         DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_ROBUST_BUFFER_ACCESS                                                      ,       robustBufferAccess                                              ),
614         DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_FULL_DRAW_INDEX_UINT32                                            ,       fullDrawIndexUint32                                             ),
615         DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_IMAGE_CUBE_ARRAY                                                          ,       imageCubeArray                                                  ),
616         DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_INDEPENDENT_BLEND                                                         ,       independentBlend                                                ),
617         DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_GEOMETRY_SHADER                                                           ,       geometryShader                                                  ),
618         DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_TESSELLATION_SHADER                                                       ,       tessellationShader                                              ),
619         DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SAMPLE_RATE_SHADING                                                       ,       sampleRateShading                                               ),
620         DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_DUAL_SRC_BLEND                                                            ,       dualSrcBlend                                                    ),
621         DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_LOGIC_OP                                                                          ,       logicOp                                                                 ),
622         DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_MULTI_DRAW_INDIRECT                                                       ,       multiDrawIndirect                                               ),
623         DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_DRAW_INDIRECT_FIRST_INSTANCE                                      ,       drawIndirectFirstInstance                               ),
624         DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_DEPTH_CLAMP                                                                       ,       depthClamp                                                              ),
625         DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_DEPTH_BIAS_CLAMP                                                          ,       depthBiasClamp                                                  ),
626         DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_FILL_MODE_NON_SOLID                                                       ,       fillModeNonSolid                                                ),
627         DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_DEPTH_BOUNDS                                                                      ,       depthBounds                                                             ),
628         DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_WIDE_LINES                                                                        ,       wideLines                                                               ),
629         DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_LARGE_POINTS                                                                      ,       largePoints                                                             ),
630         DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_ALPHA_TO_ONE                                                                      ,       alphaToOne                                                              ),
631         DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_MULTI_VIEWPORT                                                            ,       multiViewport                                                   ),
632         DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SAMPLER_ANISOTROPY                                                        ,       samplerAnisotropy                                               ),
633         DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_TEXTURE_COMPRESSION_ETC2                                          ,       textureCompressionETC2                                  ),
634         DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_TEXTURE_COMPRESSION_ASTC_LDR                                      ,       textureCompressionASTC_LDR                              ),
635         DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_TEXTURE_COMPRESSION_BC                                            ,       textureCompressionBC                                    ),
636         DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_OCCLUSION_QUERY_PRECISE                                           ,       occlusionQueryPrecise                                   ),
637         DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_PIPELINE_STATISTICS_QUERY                                         ,       pipelineStatisticsQuery                                 ),
638         DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_VERTEX_PIPELINE_STORES_AND_ATOMICS                        ,       vertexPipelineStoresAndAtomics                  ),
639         DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_FRAGMENT_STORES_AND_ATOMICS                                       ,       fragmentStoresAndAtomics                                ),
640         DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_TESSELLATION_AND_GEOMETRY_POINT_SIZE       ,       shaderTessellationAndGeometryPointSize  ),
641         DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_IMAGE_GATHER_EXTENDED                                      ,       shaderImageGatherExtended                               ),
642         DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_STORAGE_IMAGE_EXTENDED_FORMATS                     ,       shaderStorageImageExtendedFormats               ),
643         DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_STORAGE_IMAGE_MULTISAMPLE                          ,       shaderStorageImageMultisample                   ),
644         DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_STORAGE_IMAGE_READ_WITHOUT_FORMAT          ,       shaderStorageImageReadWithoutFormat             ),
645         DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_STORAGE_IMAGE_WRITE_WITHOUT_FORMAT         ,       shaderStorageImageWriteWithoutFormat    ),
646         DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_UNIFORM_BUFFER_ARRAY_DYNAMIC_INDEXING      ,       shaderUniformBufferArrayDynamicIndexing ),
647         DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_SAMPLED_IMAGE_ARRAY_DYNAMIC_INDEXING       ,       shaderSampledImageArrayDynamicIndexing  ),
648         DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_STORAGE_BUFFER_ARRAY_DYNAMIC_INDEXING      ,       shaderStorageBufferArrayDynamicIndexing ),
649         DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_STORAGE_IMAGE_ARRAY_DYNAMIC_INDEXING       ,       shaderStorageImageArrayDynamicIndexing  ),
650         DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_CLIP_DISTANCE                                                      ,       shaderClipDistance                                              ),
651         DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_CULL_DISTANCE                                                      ,       shaderCullDistance                                              ),
652         DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_FLOAT64                                                            ,       shaderFloat64                                                   ),
653         DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_INT64                                                                      ,       shaderInt64                                                             ),
654         DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_INT16                                                                      ,       shaderInt16                                                             ),
655         DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_RESOURCE_RESIDENCY                                         ,       shaderResourceResidency                                 ),
656         DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_RESOURCE_MIN_LOD                                           ,       shaderResourceMinLod                                    ),
657         DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SPARSE_BINDING                                                            ,       sparseBinding                                                   ),
658         DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SPARSE_RESIDENCY_BUFFER                                           ,       sparseResidencyBuffer                                   ),
659         DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SPARSE_RESIDENCY_IMAGE2D                                          ,       sparseResidencyImage2D                                  ),
660         DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SPARSE_RESIDENCY_IMAGE3D                                          ,       sparseResidencyImage3D                                  ),
661         DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SPARSE_RESIDENCY2_SAMPLES                                         ,       sparseResidency2Samples                                 ),
662         DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SPARSE_RESIDENCY4_SAMPLES                                         ,       sparseResidency4Samples                                 ),
663         DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SPARSE_RESIDENCY8_SAMPLES                                         ,       sparseResidency8Samples                                 ),
664         DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SPARSE_RESIDENCY16_SAMPLES                                        ,       sparseResidency16Samples                                ),
665         DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SPARSE_RESIDENCY_ALIASED                                          ,       sparseResidencyAliased                                  ),
666         DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_VARIABLE_MULTISAMPLE_RATE                                         ,       variableMultisampleRate                                 ),
667         DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_INHERITED_QUERIES                                                         ,       inheritedQueries                                                ),
668 };
669
670 bool Context::requireDeviceCoreFeature (const DeviceCoreFeature requiredFeature)
671 {
672         const vk::VkPhysicalDeviceFeatures& featuresAvailable           = getDeviceFeatures();
673         const vk::VkBool32*                                     featuresAvailableArray  = (vk::VkBool32*)(&featuresAvailable);
674         const deUint32                                          requiredFeatureIndex    = static_cast<deUint32>(requiredFeature);
675
676         DE_ASSERT(requiredFeatureIndex * sizeof(vk::VkBool32) < sizeof(featuresAvailable));
677         DE_ASSERT(deviceCoreFeaturesTable[requiredFeatureIndex].featureArrayIndex * sizeof(vk::VkBool32) == deviceCoreFeaturesTable[requiredFeatureIndex].featureArrayOffset);
678
679         if (featuresAvailableArray[requiredFeatureIndex] == DE_FALSE)
680                 TCU_THROW(NotSupportedError, "Requested core feature is not supported: " + std::string(deviceCoreFeaturesTable[requiredFeatureIndex].featureName));
681
682         return true;
683 }
684
685 void* Context::getInstanceProcAddr      ()
686 {
687         return (void*)m_platformInterface.getGetInstanceProcAddr();
688 }
689
690 bool Context::isBufferDeviceAddressSupported(void) const
691 {
692         return isDeviceFunctionalitySupported("VK_KHR_buffer_device_address") ||
693                    isDeviceFunctionalitySupported("VK_EXT_buffer_device_address");
694 }
695
696 bool Context::hasDebugReportRecorder () const
697 {
698         return m_device->hasDebugReportRecorder();
699 }
700
701 vk::DebugReportRecorder& Context::getDebugReportRecorder () const
702 {
703         return m_device->getDebugReportRecorder();
704 }
705
706 // TestCase
707
708 void TestCase::initPrograms (SourceCollections&) const
709 {
710 }
711
712 void TestCase::checkSupport (Context&) const
713 {
714 }
715
716 void TestCase::delayedInit (void)
717 {
718 }
719
720 void collectAndReportDebugMessages(vk::DebugReportRecorder &debugReportRecorder, Context& context)
721 {
722         using DebugMessages = vk::DebugReportRecorder::MessageList;
723
724         const DebugMessages&    messages        = debugReportRecorder.getMessages();
725         tcu::TestLog&                   log                     = context.getTestContext().getLog();
726
727         if (messages.size() > 0)
728         {
729                 const tcu::ScopedLogSection     section         (log, "DebugMessages", "Debug Messages");
730                 int                                                     numErrors       = 0;
731
732                 for (const auto& msg : messages)
733                 {
734                         if (msg.shouldBeLogged())
735                                 log << tcu::TestLog::Message << msg << tcu::TestLog::EndMessage;
736
737                         if (msg.isError())
738                                 numErrors += 1;
739                 }
740
741                 debugReportRecorder.clearMessages();
742
743                 if (numErrors > 0)
744                 {
745                         string errorMsg = de::toString(numErrors) + " API usage errors found";
746                         context.resultSetOnValidation(true);
747                         context.getTestContext().setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, errorMsg.c_str());
748                 }
749         }
750 }
751
752 } // vkt