Fix missing dependency on sparse binds
[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 #ifdef CTS_USES_VULKANSC
37 #include "vkSafetyCriticalUtil.hpp"
38 #include "vkAppParamsUtil.hpp"
39 #endif // CTS_USES_VULKANSC
40
41 #include "tcuCommandLine.hpp"
42 #include "tcuTestLog.hpp"
43
44 #include "deSTLUtil.hpp"
45 #include "deMemory.h"
46
47 #include <set>
48
49 namespace vkt
50 {
51
52 // Default device utilities
53
54 using std::vector;
55 using std::string;
56 using std::set;
57 using namespace vk;
58
59 namespace
60 {
61
62 vector<string> filterExtensions (const vector<VkExtensionProperties>& extensions)
63 {
64         vector<string>  enabledExtensions;
65         bool                    khrBufferDeviceAddress  = false;
66
67         const char*             extensionGroups[]               =
68         {
69                 "VK_KHR_",
70                 "VK_EXT_",
71                 "VK_KHX_",
72                 "VK_NV_cooperative_matrix",
73                 "VK_NV_ray_tracing",
74                 "VK_NV_inherited_viewport_scissor",
75                 "VK_NV_mesh_shader",
76                 "VK_AMD_mixed_attachment_samples",
77                 "VK_AMD_buffer_marker",
78                 "VK_AMD_shader_explicit_vertex_parameter",
79                 "VK_AMD_shader_image_load_store_lod",
80                 "VK_AMD_shader_trinary_minmax",
81                 "VK_AMD_texture_gather_bias_lod",
82                 "VK_AMD_shader_early_and_late_fragment_tests",
83                 "VK_ANDROID_external_memory_android_hardware_buffer",
84                 "VK_VALVE_mutable_descriptor_type",
85                 "VK_NV_shader_subgroup_partitioned",
86                 "VK_NV_clip_space_w_scaling",
87                 "VK_NV_scissor_exclusive",
88                 "VK_NV_shading_rate_image",
89                 "VK_ARM_rasterization_order_attachment_access",
90                 "VK_GOOGLE_surfaceless_query",
91                 "VK_FUCHSIA_",
92                 "VK_NV_fragment_coverage_to_color",
93                 "VK_NV_framebuffer_mixed_samples",
94                 "VK_NV_coverage_reduction_mode",
95                 "VK_NV_viewport_swizzle",
96                 "VK_NV_representative_fragment_test",
97         };
98
99         for (size_t extNdx = 0; extNdx < extensions.size(); extNdx++)
100         {
101                 if (deStringEqual(extensions[extNdx].extensionName, "VK_KHR_buffer_device_address"))
102                 {
103                         khrBufferDeviceAddress = true;
104                         break;
105                 }
106         }
107
108         for (size_t extNdx = 0; extNdx < extensions.size(); extNdx++)
109         {
110                 const auto& extName = extensions[extNdx].extensionName;
111
112                 // VK_EXT_buffer_device_address is deprecated and must not be enabled if VK_KHR_buffer_device_address is enabled
113                 if (khrBufferDeviceAddress && deStringEqual(extName, "VK_EXT_buffer_device_address"))
114                         continue;
115
116                 for (int extGroupNdx = 0; extGroupNdx < DE_LENGTH_OF_ARRAY(extensionGroups); extGroupNdx++)
117                 {
118                         if (deStringBeginsWith(extName, extensionGroups[extGroupNdx]))
119                                 enabledExtensions.push_back(extName);
120                 }
121         }
122
123         return enabledExtensions;
124 }
125
126 vector<string> addExtensions (const vector<string>& a, const vector<const char*>& b)
127 {
128         vector<string>  res             (a);
129
130         for (vector<const char*>::const_iterator bIter = b.begin(); bIter != b.end(); ++bIter)
131         {
132                 if (!de::contains(res.begin(), res.end(), string(*bIter)))
133                         res.push_back(string(*bIter));
134         }
135
136         return res;
137 }
138
139 vector<string> removeExtensions (const vector<string>& a, const vector<const char*>& b)
140 {
141         vector<string>  res;
142         set<string>             removeExts      (b.begin(), b.end());
143
144         for (vector<string>::const_iterator aIter = a.begin(); aIter != a.end(); ++aIter)
145         {
146                 if (!de::contains(removeExts, *aIter))
147                         res.push_back(*aIter);
148         }
149
150         return res;
151 }
152
153 vector<string> addCoreInstanceExtensions (const vector<string>& extensions, deUint32 instanceVersion)
154 {
155         vector<const char*> coreExtensions;
156         getCoreInstanceExtensions(instanceVersion, coreExtensions);
157         return addExtensions(extensions, coreExtensions);
158 }
159
160 vector<string> addCoreDeviceExtensions(const vector<string>& extensions, deUint32 instanceVersion)
161 {
162         vector<const char*> coreExtensions;
163         getCoreDeviceExtensions(instanceVersion, coreExtensions);
164         return addExtensions(extensions, coreExtensions);
165 }
166
167 deUint32 getTargetInstanceVersion (const PlatformInterface& vkp)
168 {
169         deUint32 version = pack(ApiVersion(0, 1, 0, 0));
170
171         if (vkp.enumerateInstanceVersion(&version) != VK_SUCCESS)
172                 TCU_THROW(InternalError, "Enumerate instance version error");
173 #ifdef CTS_USES_VULKANSC
174         // Temporary workaround for Vulkan loader problem - currently Vulkan loader always returs API variant == 0
175         version = pack(ApiVersion(1, 1, 0, 0));
176 #endif
177         return version;
178 }
179
180 std::pair<deUint32, deUint32> determineDeviceVersions(const PlatformInterface& vkp, deUint32 apiVersion, const tcu::CommandLine& cmdLine)
181 {
182         Move<VkInstance>                                                preinstance                             = createDefaultInstance(vkp, apiVersion, cmdLine);
183         InstanceDriver                                                  preinterface                    (vkp, preinstance.get());
184
185         const vector<VkPhysicalDevice>                  devices                                 = enumeratePhysicalDevices(preinterface, preinstance.get());
186         deUint32                                                                lowestDeviceVersion             = 0xFFFFFFFFu;
187         for (deUint32 deviceNdx = 0u; deviceNdx < devices.size(); ++deviceNdx)
188         {
189                 const VkPhysicalDeviceProperties        props                                   = getPhysicalDeviceProperties(preinterface, devices[deviceNdx]);
190                 if (props.apiVersion < lowestDeviceVersion)
191                         lowestDeviceVersion = props.apiVersion;
192         }
193
194         const vk::VkPhysicalDevice                              choosenDevice                   = chooseDevice(preinterface, *preinstance, cmdLine);
195         const VkPhysicalDeviceProperties                props                                   = getPhysicalDeviceProperties(preinterface, choosenDevice);
196         const deUint32                                                  choosenDeviceVersion    = props.apiVersion;
197
198         return std::make_pair(choosenDeviceVersion, lowestDeviceVersion);
199 }
200
201 #ifndef CTS_USES_VULKANSC
202 Move<VkInstance> createInstance (const PlatformInterface& vkp, deUint32 apiVersion, const vector<string>& enabledExtensions, const tcu::CommandLine& cmdLine, DebugReportRecorder* recorder)
203 #else
204 Move<VkInstance> createInstance (const PlatformInterface& vkp, deUint32 apiVersion, const vector<string>& enabledExtensions, const tcu::CommandLine& cmdLine)
205 #endif // CTS_USES_VULKANSC
206 {
207 #ifndef CTS_USES_VULKANSC
208         const bool                      isValidationEnabled     = (recorder != nullptr);
209 #else
210         const bool                      isValidationEnabled = false;
211 #endif // CTS_USES_VULKANSC
212         vector<const char*>     enabledLayers;
213
214         // \note Extensions in core are not explicitly enabled even though
215         //               they are in the extension list advertised to tests.
216         vector<const char*> coreExtensions;
217         getCoreInstanceExtensions(apiVersion, coreExtensions);
218         const auto nonCoreExtensions = removeExtensions(enabledExtensions, coreExtensions);
219
220         if (isValidationEnabled)
221         {
222                 if (!isDebugReportSupported(vkp))
223                         TCU_THROW(NotSupportedError, "VK_EXT_debug_report is not supported");
224
225                 enabledLayers = vkt::getValidationLayers(vkp);
226                 if (enabledLayers.empty())
227                         TCU_THROW(NotSupportedError, "No validation layers found");
228         }
229
230 #ifndef CTS_USES_VULKANSC
231         return createDefaultInstance(vkp, apiVersion, vector<string>(begin(enabledLayers), end(enabledLayers)), nonCoreExtensions, cmdLine, recorder);
232 #else
233         return createDefaultInstance(vkp, apiVersion, vector<string>(begin(enabledLayers), end(enabledLayers)), nonCoreExtensions, cmdLine);
234 #endif // CTS_USES_VULKANSC
235 }
236
237 static deUint32 findQueueFamilyIndexWithCaps (const InstanceInterface& vkInstance, VkPhysicalDevice physicalDevice, VkQueueFlags requiredCaps)
238 {
239         const vector<VkQueueFamilyProperties>   queueProps      = getPhysicalDeviceQueueFamilyProperties(vkInstance, physicalDevice);
240
241         for (size_t queueNdx = 0; queueNdx < queueProps.size(); queueNdx++)
242         {
243                 if ((queueProps[queueNdx].queueFlags & requiredCaps) == requiredCaps)
244                         return (deUint32)queueNdx;
245         }
246
247         TCU_THROW(NotSupportedError, "No matching queue found");
248 }
249
250 Move<VkDevice> createDefaultDevice (const PlatformInterface&                            vkp,
251                                                                         VkInstance                                                              instance,
252                                                                         const InstanceInterface&                                vki,
253                                                                         VkPhysicalDevice                                                physicalDevice,
254                                                                         const deUint32                                                  apiVersion,
255                                                                         deUint32                                                                queueIndex,
256                                                                         deUint32                                                                sparseQueueIndex,
257                                                                         const VkPhysicalDeviceFeatures2&                enabledFeatures,
258                                                                         const vector<string>&                                   enabledExtensions,
259                                                                         const tcu::CommandLine&                                 cmdLine,
260                                                                         de::SharedPtr<vk::ResourceInterface>    resourceInterface)
261 {
262         VkDeviceQueueCreateInfo         queueInfo[2];
263         VkDeviceCreateInfo                      deviceInfo;
264         vector<const char*>                     enabledLayers;
265         vector<const char*>                     extensionPtrs;
266         const float                                     queuePriority   = 1.0f;
267         const deUint32                          numQueues = (enabledFeatures.features.sparseBinding && (queueIndex != sparseQueueIndex)) ? 2 : 1;
268
269         deMemset(&queueInfo,    0, sizeof(queueInfo));
270         deMemset(&deviceInfo,   0, sizeof(deviceInfo));
271
272         if (cmdLine.isValidationEnabled())
273         {
274                 enabledLayers = vkt::getValidationLayers(vki, physicalDevice);
275                 if (enabledLayers.empty())
276                         TCU_THROW(NotSupportedError, "No validation layers found");
277         }
278
279         // \note Extensions in core are not explicitly enabled even though
280         //               they are in the extension list advertised to tests.
281         vector<const char*> coreExtensions;
282         getCoreDeviceExtensions(apiVersion, coreExtensions);
283         vector<string>  nonCoreExtensions(removeExtensions(enabledExtensions, coreExtensions));
284
285         extensionPtrs.resize(nonCoreExtensions.size());
286
287         for (size_t ndx = 0; ndx < nonCoreExtensions.size(); ++ndx)
288                 extensionPtrs[ndx] = nonCoreExtensions[ndx].c_str();
289
290         queueInfo[0].sType                                              = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
291         queueInfo[0].pNext                                              = DE_NULL;
292         queueInfo[0].flags                                              = (VkDeviceQueueCreateFlags)0u;
293         queueInfo[0].queueFamilyIndex                   = queueIndex;
294         queueInfo[0].queueCount                                 = 1u;
295         queueInfo[0].pQueuePriorities                   = &queuePriority;
296
297         if (numQueues > 1)
298         {
299                 queueInfo[1].sType                                              = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
300                 queueInfo[1].pNext                                              = DE_NULL;
301                 queueInfo[1].flags                                              = (VkDeviceQueueCreateFlags)0u;
302                 queueInfo[1].queueFamilyIndex                   = sparseQueueIndex;
303                 queueInfo[1].queueCount                                 = 1u;
304                 queueInfo[1].pQueuePriorities                   = &queuePriority;
305         }
306
307         // VK_KHR_get_physical_device_properties2 is used if enabledFeatures.pNext != 0
308         deviceInfo.sType                                                = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
309         deviceInfo.pNext                                                = enabledFeatures.pNext ? &enabledFeatures : DE_NULL;
310         deviceInfo.queueCreateInfoCount                 = numQueues;
311         deviceInfo.pQueueCreateInfos                    = queueInfo;
312         deviceInfo.enabledExtensionCount                = (deUint32)extensionPtrs.size();
313         deviceInfo.ppEnabledExtensionNames              = (extensionPtrs.empty() ? DE_NULL : &extensionPtrs[0]);
314         deviceInfo.enabledLayerCount                    = (deUint32)enabledLayers.size();
315         deviceInfo.ppEnabledLayerNames                  = (enabledLayers.empty() ? DE_NULL : enabledLayers.data());
316         deviceInfo.pEnabledFeatures                             = enabledFeatures.pNext ? DE_NULL : &enabledFeatures.features;
317
318 #ifdef CTS_USES_VULKANSC
319         // devices created for Vulkan SC must have VkDeviceObjectReservationCreateInfo structure defined in VkDeviceCreateInfo::pNext chain
320         VkDeviceObjectReservationCreateInfo     dmrCI   = resetDeviceObjectReservationCreateInfo();
321         VkPipelineCacheCreateInfo                       pcCI    =
322         {
323                 VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO,                           // VkStructureType                              sType;
324                 DE_NULL,                                                                                                        // const void*                                  pNext;
325                 VK_PIPELINE_CACHE_CREATE_READ_ONLY_BIT |
326                         VK_PIPELINE_CACHE_CREATE_USE_APPLICATION_STORAGE_BIT,   // VkPipelineCacheCreateFlags   flags;
327                 0U,                                                                                                                     // deUintptr                                    initialDataSize;
328                 DE_NULL                                                                                                         // const void*                                  pInitialData;
329         };
330
331         std::vector<VkPipelinePoolSize> poolSizes;
332         if (cmdLine.isSubProcess())
333         {
334                 resourceInterface->importPipelineCacheData(vkp, instance, vki, physicalDevice, queueIndex);
335
336                 dmrCI                                                                   = resourceInterface->getStatMax();
337
338                 if(resourceInterface->getCacheDataSize() > 0)
339                 {
340                         pcCI.initialDataSize                            = resourceInterface->getCacheDataSize();
341                         pcCI.pInitialData                                       = resourceInterface->getCacheData();
342                         dmrCI.pipelineCacheCreateInfoCount      = 1;
343                         dmrCI.pPipelineCacheCreateInfos         = &pcCI;
344                 }
345
346                 poolSizes                                                               = resourceInterface->getPipelinePoolSizes();
347                 if (!poolSizes.empty())
348                 {
349                         dmrCI.pipelinePoolSizeCount                     = deUint32(poolSizes.size());
350                         dmrCI.pPipelinePoolSizes                        = poolSizes.data();
351                 }
352         }
353
354         dmrCI.pNext                                                                             = deviceInfo.pNext;
355         VkPhysicalDeviceVulkanSC10Features sc10Features = createDefaultSC10Features();
356         if (findStructureInChain(dmrCI.pNext, getStructureType<VkPhysicalDeviceVulkanSC10Features>()) == nullptr)
357         {
358                 sc10Features.pNext = &dmrCI;
359                 deviceInfo.pNext = &sc10Features;
360         }
361         else
362                 deviceInfo.pNext = &dmrCI;
363
364         vector<VkApplicationParametersEXT> appParams;
365         if (readApplicationParameters(appParams, cmdLine, false))
366         {
367                 appParams[appParams.size() - 1].pNext = deviceInfo.pNext;
368                 deviceInfo.pNext = &appParams[0];
369         }
370
371 #else
372         DE_UNREF(resourceInterface);
373 #endif // CTS_USES_VULKANSC
374
375         return createDevice(vkp, instance, vki, physicalDevice, &deviceInfo);
376 }
377
378 } // anonymous
379
380 class DefaultDevice
381 {
382 public:
383                                                                                                                                         DefaultDevice                                                   (const PlatformInterface& vkPlatform, const tcu::CommandLine& cmdLine, de::SharedPtr<vk::ResourceInterface> resourceInterface);
384                                                                                                                                         ~DefaultDevice                                                  (void);
385
386         VkInstance                                                                                                              getInstance                                                             (void) const { return *m_instance;                                                                                      }
387         const InstanceInterface&                                                                                getInstanceInterface                                    (void) const { return m_instanceInterface;                                                                      }
388         deUint32                                                                                                                getMaximumFrameworkVulkanVersion                (void) const { return m_maximumFrameworkVulkanVersion;                                          }
389         deUint32                                                                                                                getAvailableInstanceVersion                             (void) const { return m_availableInstanceVersion;                                                       }
390         deUint32                                                                                                                getUsedInstanceVersion                                  (void) const { return m_usedInstanceVersion;                                                            }
391         const vector<string>&                                                                                   getInstanceExtensions                                   (void) const { return m_instanceExtensions;                                                                     }
392
393         VkPhysicalDevice                                                                                                getPhysicalDevice                                               (void) const { return m_physicalDevice;                                                                         }
394         deUint32                                                                                                                getDeviceVersion                                                (void) const { return m_deviceVersion;                                                                          }
395
396         bool                                                                                                                    isDeviceFeatureInitialized                              (VkStructureType sType) const { return m_deviceFeatures.isDeviceFeatureInitialized(sType);              }
397         const VkPhysicalDeviceFeatures&                                                                 getDeviceFeatures                                               (void) const { return m_deviceFeatures.getCoreFeatures2().features;                     }
398         const VkPhysicalDeviceFeatures2&                                                                getDeviceFeatures2                                              (void) const { return m_deviceFeatures.getCoreFeatures2();                                      }
399         const VkPhysicalDeviceVulkan11Features&                                                 getVulkan11Features                                             (void) const { return m_deviceFeatures.getVulkan11Features();                           }
400         const VkPhysicalDeviceVulkan12Features&                                                 getVulkan12Features                                             (void) const { return m_deviceFeatures.getVulkan12Features();                           }
401 #ifndef CTS_USES_VULKANSC
402         const VkPhysicalDeviceVulkan13Features&                                                 getVulkan13Features                                             (void) const { return m_deviceFeatures.getVulkan13Features();                           }
403 #endif // CTS_USES_VULKANSC
404
405 #include "vkDeviceFeaturesForDefaultDeviceDefs.inl"
406
407         bool                                                                                                                    isDevicePropertyInitialized                             (VkStructureType sType) const { return m_deviceProperties.isDevicePropertyInitialized(sType);   }
408         const VkPhysicalDeviceProperties&                                                               getDeviceProperties                                             (void) const { return m_deviceProperties.getCoreProperties2().properties;       }
409         const VkPhysicalDeviceProperties2&                                                              getDeviceProperties2                                    (void) const { return m_deviceProperties.getCoreProperties2();                          }
410         const VkPhysicalDeviceVulkan11Properties&                                               getDeviceVulkan11Properties                             (void) const { return m_deviceProperties.getVulkan11Properties();                       }
411         const VkPhysicalDeviceVulkan12Properties&                                               getDeviceVulkan12Properties                             (void) const { return m_deviceProperties.getVulkan12Properties();                       }
412 #ifndef CTS_USES_VULKANSC
413         const VkPhysicalDeviceVulkan13Properties&                                               getDeviceVulkan13Properties                             (void) const { return m_deviceProperties.getVulkan13Properties();                       }
414 #endif // CTS_USES_VULKANSC
415 #ifdef CTS_USES_VULKANSC
416         const VkPhysicalDeviceVulkanSC10Properties&                                             getDeviceVulkanSC10Properties                   (void) const { return m_deviceProperties.getVulkanSC10Properties(); }
417 #endif // CTS_USES_VULKANSC
418
419 #include "vkDevicePropertiesForDefaultDeviceDefs.inl"
420
421         VkDevice                                                                                                                getDevice                                                               (void) const { return *m_device;                                                                                        }
422         const DeviceInterface&                                                                                  getDeviceInterface                                              (void) const { return *m_deviceInterface;                                                                       }
423         const vector<string>&                                                                                   getDeviceExtensions                                             (void) const { return m_deviceExtensions;                                                                       }
424         deUint32                                                                                                                getUsedApiVersion                                               (void) const { return m_usedApiVersion;                                                                         }
425         deUint32                                                                                                                getUniversalQueueFamilyIndex                    (void) const { return m_universalQueueFamilyIndex;                                                      }
426         VkQueue                                                                                                                 getUniversalQueue                                               (void) const;
427         deUint32                                                                                                                getSparseQueueFamilyIndex                               (void) const { return m_sparseQueueFamilyIndex;                                                         }
428         VkQueue                                                                                                                 getSparseQueue                                                  (void) const;
429
430 #ifndef CTS_USES_VULKANSC
431         bool                                                                                                                    hasDebugReportRecorder                                  (void) const { return m_debugReportRecorder.get() != nullptr;                           }
432         vk::DebugReportRecorder&                                                                                getDebugReportRecorder                                  (void) const { return *m_debugReportRecorder.get();                                                     }
433 #endif // CTS_USES_VULKANSC
434
435 private:
436 #ifndef CTS_USES_VULKANSC
437         using DebugReportRecorderPtr            = de::UniquePtr<vk::DebugReportRecorder>;
438         using DebugReportCallbackPtr            = vk::Move<VkDebugReportCallbackEXT>;
439 #endif // CTS_USES_VULKANSC
440
441         const deUint32                                          m_maximumFrameworkVulkanVersion;
442         const deUint32                                          m_availableInstanceVersion;
443         const deUint32                                          m_usedInstanceVersion;
444
445         const std::pair<deUint32, deUint32> m_deviceVersions;
446         const deUint32                                          m_usedApiVersion;
447
448 #ifndef CTS_USES_VULKANSC
449         const DebugReportRecorderPtr            m_debugReportRecorder;
450 #endif // CTS_USES_VULKANSC
451         const vector<string>                            m_instanceExtensions;
452         const Unique<VkInstance>                        m_instance;
453 #ifndef CTS_USES_VULKANSC
454         const InstanceDriver                            m_instanceInterface;
455         const DebugReportCallbackPtr            m_debugReportCallback;
456 #else
457         const InstanceDriverSC                          m_instanceInterface;
458 #endif // CTS_USES_VULKANSC
459         const VkPhysicalDevice                          m_physicalDevice;
460         const deUint32                                          m_deviceVersion;
461
462         const vector<string>                            m_deviceExtensions;
463         const DeviceFeatures                            m_deviceFeatures;
464
465         const deUint32                                          m_universalQueueFamilyIndex;
466         const deUint32                                          m_sparseQueueFamilyIndex;
467         const DeviceProperties                          m_deviceProperties;
468
469         const Unique<VkDevice>                          m_device;
470         const de::MovePtr<DeviceDriver>         m_deviceInterface;
471 };
472
473 namespace
474 {
475
476 deUint32 sanitizeApiVersion(deUint32 v)
477 {
478         return VK_MAKE_API_VERSION(VK_API_VERSION_VARIANT(v), VK_API_VERSION_MAJOR(v), VK_API_VERSION_MINOR(v), 0 );
479 }
480
481 #ifndef CTS_USES_VULKANSC
482 de::MovePtr<vk::DebugReportRecorder> createDebugReportRecorder (const vk::PlatformInterface& vkp, bool printValidationErrors)
483 {
484         if (isDebugReportSupported(vkp))
485                 return de::MovePtr<vk::DebugReportRecorder>(new vk::DebugReportRecorder(printValidationErrors));
486         else
487                 TCU_THROW(NotSupportedError, "VK_EXT_debug_report is not supported");
488 }
489 #endif // CTS_USES_VULKANSC
490 } // anonymous
491
492 DefaultDevice::DefaultDevice (const PlatformInterface& vkPlatform, const tcu::CommandLine& cmdLine, de::SharedPtr<vk::ResourceInterface> resourceInterface)
493 #ifndef CTS_USES_VULKANSC
494         : m_maximumFrameworkVulkanVersion       (VK_API_MAX_FRAMEWORK_VERSION)
495 #else
496         : m_maximumFrameworkVulkanVersion       (VKSC_API_MAX_FRAMEWORK_VERSION)
497 #endif // CTS_USES_VULKANSC
498         , m_availableInstanceVersion            (getTargetInstanceVersion(vkPlatform))
499         , m_usedInstanceVersion                         (sanitizeApiVersion(minVulkanAPIVersion(m_availableInstanceVersion, m_maximumFrameworkVulkanVersion)))
500         , m_deviceVersions                                      (determineDeviceVersions(vkPlatform, m_usedInstanceVersion, cmdLine))
501         , m_usedApiVersion                                      (sanitizeApiVersion(minVulkanAPIVersion(m_usedInstanceVersion, m_deviceVersions.first)))
502
503 #ifndef CTS_USES_VULKANSC
504         , m_debugReportRecorder                         (cmdLine.isValidationEnabled()
505                                                                                  ? createDebugReportRecorder(vkPlatform, cmdLine.printValidationErrors())
506                                                                                  : de::MovePtr<vk::DebugReportRecorder>())
507 #endif // CTS_USES_VULKANSC
508         , m_instanceExtensions                          (addCoreInstanceExtensions(filterExtensions(enumerateInstanceExtensionProperties(vkPlatform, DE_NULL)), m_usedApiVersion))
509 #ifndef CTS_USES_VULKANSC
510         , m_instance                                            (createInstance(vkPlatform, m_usedApiVersion, m_instanceExtensions, cmdLine, m_debugReportRecorder.get()))
511 #else
512         , m_instance                                            (createInstance(vkPlatform, m_usedApiVersion, m_instanceExtensions, cmdLine))
513 #endif // CTS_USES_VULKANSC
514
515 #ifndef CTS_USES_VULKANSC
516         , m_instanceInterface                           (vkPlatform, *m_instance)
517
518         , m_debugReportCallback                         (cmdLine.isValidationEnabled()
519                                                                                  ? m_debugReportRecorder->createCallback(m_instanceInterface, m_instance.get())
520                                                                                  : DebugReportCallbackPtr())
521 #else
522         , m_instanceInterface                           (vkPlatform, *m_instance, cmdLine, resourceInterface)
523 #endif // CTS_USES_VULKANSC
524         , m_physicalDevice                                      (chooseDevice(m_instanceInterface, *m_instance, cmdLine))
525         , m_deviceVersion                                       (getPhysicalDeviceProperties(m_instanceInterface, m_physicalDevice).apiVersion)
526
527         , m_deviceExtensions                            (addCoreDeviceExtensions(filterExtensions(enumerateDeviceExtensionProperties(m_instanceInterface, m_physicalDevice, DE_NULL)), m_usedApiVersion))
528         , m_deviceFeatures                                      (m_instanceInterface, m_usedApiVersion, m_physicalDevice, m_instanceExtensions, m_deviceExtensions)
529         , m_universalQueueFamilyIndex           (findQueueFamilyIndexWithCaps(m_instanceInterface, m_physicalDevice, VK_QUEUE_GRAPHICS_BIT|VK_QUEUE_COMPUTE_BIT))
530 #ifndef CTS_USES_VULKANSC
531         , m_sparseQueueFamilyIndex                      (m_deviceFeatures.getCoreFeatures2().features.sparseBinding ? findQueueFamilyIndexWithCaps(m_instanceInterface, m_physicalDevice, VK_QUEUE_SPARSE_BINDING_BIT) : 0)
532 #else
533         , m_sparseQueueFamilyIndex                      (0)
534 #endif // CTS_USES_VULKANSC
535         , m_deviceProperties                            (m_instanceInterface, m_usedApiVersion, m_physicalDevice, m_instanceExtensions, m_deviceExtensions)
536         , m_device                                                      (createDefaultDevice(vkPlatform, *m_instance, m_instanceInterface, m_physicalDevice, m_usedApiVersion, m_universalQueueFamilyIndex, m_sparseQueueFamilyIndex, m_deviceFeatures.getCoreFeatures2(), m_deviceExtensions, cmdLine, resourceInterface))
537 #ifndef CTS_USES_VULKANSC
538         , m_deviceInterface                                     (de::MovePtr<DeviceDriver>(new DeviceDriver(vkPlatform, *m_instance, *m_device)))
539 #else
540         , m_deviceInterface                                     (de::MovePtr<DeviceDriverSC>(new DeviceDriverSC(vkPlatform, *m_instance, *m_device, cmdLine, resourceInterface, getDeviceVulkanSC10Properties(), getDeviceProperties())))
541 #endif // CTS_USES_VULKANSC
542 {
543 #ifndef CTS_USES_VULKANSC
544         DE_UNREF(resourceInterface);
545 #endif
546         DE_ASSERT(m_deviceVersions.first == m_deviceVersion);
547 }
548
549 DefaultDevice::~DefaultDevice (void)
550 {
551 }
552
553 VkQueue DefaultDevice::getUniversalQueue (void) const
554 {
555         return getDeviceQueue(*m_deviceInterface, *m_device, m_universalQueueFamilyIndex, 0);
556 }
557
558 VkQueue DefaultDevice::getSparseQueue (void) const
559 {
560         if (!m_deviceFeatures.getCoreFeatures2().features.sparseBinding)
561                 TCU_THROW(NotSupportedError, "Sparse binding not supported.");
562
563         return getDeviceQueue(*m_deviceInterface, *m_device, m_sparseQueueFamilyIndex, 0);
564 }
565
566 namespace
567 {
568 // Allocator utilities
569
570 vk::Allocator* createAllocator (DefaultDevice* device)
571 {
572         const VkPhysicalDeviceMemoryProperties memoryProperties = vk::getPhysicalDeviceMemoryProperties(device->getInstanceInterface(), device->getPhysicalDevice());
573
574         // \todo [2015-07-24 jarkko] support allocator selection/configuration from command line (or compile time)
575         return new SimpleAllocator(device->getDeviceInterface(), device->getDevice(), memoryProperties);
576 }
577
578 } // anonymous
579
580 // Context
581
582 Context::Context (tcu::TestContext&                                             testCtx,
583                                   const vk::PlatformInterface&                  platformInterface,
584                                   vk::BinaryCollection&                                 progCollection,
585                                   de::SharedPtr<vk::ResourceInterface>  resourceInterface )
586         : m_testCtx                                     (testCtx)
587         , m_platformInterface           (platformInterface)
588         , m_progCollection                      (progCollection)
589         , m_resourceInterface           (resourceInterface)
590         , m_device                                      (new DefaultDevice(m_platformInterface, testCtx.getCommandLine(), resourceInterface))
591         , m_allocator                           (createAllocator(m_device.get()))
592         , m_resultSetOnValidation       (false)
593 {
594 }
595
596 Context::~Context (void)
597 {
598 }
599
600 deUint32                                                                                Context::getMaximumFrameworkVulkanVersion               (void) const { return m_device->getMaximumFrameworkVulkanVersion();                     }
601 deUint32                                                                                Context::getAvailableInstanceVersion                    (void) const { return m_device->getAvailableInstanceVersion();                          }
602 const vector<string>&                                                   Context::getInstanceExtensions                                  (void) const { return m_device->getInstanceExtensions();                                        }
603 vk::VkInstance                                                                  Context::getInstance                                                    (void) const { return m_device->getInstance();                                                          }
604 const vk::InstanceInterface&                                    Context::getInstanceInterface                                   (void) const { return m_device->getInstanceInterface();                                         }
605 vk::VkPhysicalDevice                                                    Context::getPhysicalDevice                                              (void) const { return m_device->getPhysicalDevice();                                            }
606 deUint32                                                                                Context::getDeviceVersion                                               (void) const { return m_device->getDeviceVersion();                                                     }
607 const vk::VkPhysicalDeviceFeatures&                             Context::getDeviceFeatures                                              (void) const { return m_device->getDeviceFeatures();                                            }
608 const vk::VkPhysicalDeviceFeatures2&                    Context::getDeviceFeatures2                                             (void) const { return m_device->getDeviceFeatures2();                                           }
609 const vk::VkPhysicalDeviceVulkan11Features&             Context::getDeviceVulkan11Features                              (void) const { return m_device->getVulkan11Features();                                          }
610 const vk::VkPhysicalDeviceVulkan12Features&             Context::getDeviceVulkan12Features                              (void) const { return m_device->getVulkan12Features();                                          }
611 #ifndef CTS_USES_VULKANSC
612 const vk::VkPhysicalDeviceVulkan13Features&             Context::getDeviceVulkan13Features                              (void) const { return m_device->getVulkan13Features();                                          }
613 #endif // CTS_USES_VULKANSC
614 #ifdef CTS_USES_VULKANSC
615 const vk::VkPhysicalDeviceVulkanSC10Features&   Context::getDeviceVulkanSC10Features                    (void) const { return m_device->getVulkanSC10Features();                                        }
616 #endif // CTS_USES_VULKANSC
617
618 bool Context::isDeviceFunctionalitySupported (const std::string& extension) const
619 {
620         // If extension was promoted to core then check using the core mechanism. This is required so that
621         // all core implementations have the functionality tested, even if they don't support the extension.
622         // (It also means that core-optional extensions will not be reported as supported unless the
623         // features are really supported if the CTS code adds all core extensions to the extension list).
624         deUint32 apiVersion = getUsedApiVersion();
625         if (isCoreDeviceExtension(apiVersion, extension))
626         {
627                 if (apiVersion < VK_MAKE_API_VERSION(0, 1, 2, 0))
628                 {
629                         // Check feature bits in extension-specific structures.
630                         if (extension == "VK_KHR_multiview")
631                                 return !!m_device->getMultiviewFeatures().multiview;
632                         if (extension == "VK_KHR_variable_pointers")
633                                 return !!m_device->getVariablePointersFeatures().variablePointersStorageBuffer;
634                         if (extension == "VK_KHR_sampler_ycbcr_conversion")
635                                 return !!m_device->getSamplerYcbcrConversionFeatures().samplerYcbcrConversion;
636                         if (extension == "VK_KHR_shader_draw_parameters")
637                                 return !!m_device->getShaderDrawParametersFeatures().shaderDrawParameters;
638                 }
639                 else
640                 {
641                         // Check feature bits using the new Vulkan 1.2 structures.
642                         const auto& vk11Features = m_device->getVulkan11Features();
643                         if (extension == "VK_KHR_multiview")
644                                 return !!vk11Features.multiview;
645                         if (extension == "VK_KHR_variable_pointers")
646                                 return !!vk11Features.variablePointersStorageBuffer;
647                         if (extension == "VK_KHR_sampler_ycbcr_conversion")
648                                 return !!vk11Features.samplerYcbcrConversion;
649                         if (extension == "VK_KHR_shader_draw_parameters")
650                                 return !!vk11Features.shaderDrawParameters;
651
652                         const auto& vk12Features = m_device->getVulkan12Features();
653                         if (extension == "VK_KHR_timeline_semaphore")
654                                 return !!vk12Features.timelineSemaphore;
655                         if (extension == "VK_KHR_buffer_device_address")
656                                 return !!vk12Features.bufferDeviceAddress;
657                         if (extension == "VK_EXT_descriptor_indexing")
658                                 return !!vk12Features.descriptorIndexing;
659                         if (extension == "VK_KHR_draw_indirect_count")
660                                 return !!vk12Features.drawIndirectCount;
661                         if (extension == "VK_KHR_sampler_mirror_clamp_to_edge")
662                                 return !!vk12Features.samplerMirrorClampToEdge;
663                         if (extension == "VK_EXT_sampler_filter_minmax")
664                                 return !!vk12Features.samplerFilterMinmax;
665                         if (extension == "VK_EXT_shader_viewport_index_layer")
666                                 return !!vk12Features.shaderOutputViewportIndex && !!vk12Features.shaderOutputLayer;
667
668 #ifndef CTS_USES_VULKANSC
669                         const auto& vk13Features = m_device->getVulkan13Features();
670                         if (extension == "VK_EXT_inline_uniform_block")
671                                 return !!vk13Features.inlineUniformBlock;
672                         if (extension == "VK_EXT_pipeline_creation_cache_control")
673                                 return !!vk13Features.pipelineCreationCacheControl;
674                         if (extension == "VK_EXT_private_data")
675                                 return !!vk13Features.privateData;
676                         if (extension == "VK_EXT_shader_demote_to_helper_invocation")
677                                 return !!vk13Features.shaderDemoteToHelperInvocation;
678                         if (extension == "VK_KHR_shader_terminate_invocation")
679                                 return !!vk13Features.shaderTerminateInvocation;
680                         if (extension == "VK_EXT_subgroup_size_control")
681                                 return !!vk13Features.subgroupSizeControl;
682                         if (extension == "VK_KHR_synchronization2")
683                                 return !!vk13Features.synchronization2;
684                         if (extension == "VK_EXT_texture_compression_astc_hdr")
685                                 return !!vk13Features.textureCompressionASTC_HDR;
686                         if (extension == "VK_KHR_zero_initialize_workgroup_memory")
687                                 return !!vk13Features.shaderZeroInitializeWorkgroupMemory;
688                         if (extension == "VK_KHR_dynamic_rendering")
689                                 return !!vk13Features.dynamicRendering;
690                         if (extension == "VK_KHR_shader_integer_dot_product")
691                                 return !!vk13Features.shaderIntegerDotProduct;
692                         if (extension == "VK_KHR_maintenance4")
693                                 return !!vk13Features.maintenance4;
694 #endif // CTS_USES_VULKANSC
695
696 #ifdef CTS_USES_VULKANSC
697                         const auto& vk12Properties = m_device->getDeviceVulkan12Properties();
698                         if (extension == "VK_KHR_depth_stencil_resolve")
699                                 return (vk12Properties.supportedDepthResolveModes != VK_RESOLVE_MODE_NONE) && (vk12Properties.supportedStencilResolveModes != VK_RESOLVE_MODE_NONE);
700 #endif // CTS_USES_VULKANSC
701                 }
702
703                 // No feature flags to check.
704                 return true;
705         }
706
707         // If this is not a core extension then just return whether the implementation says it's supported.
708         const auto& extensions = getDeviceExtensions();
709         return de::contains(extensions.begin(), extensions.end(), extension);
710 }
711
712 bool Context::isInstanceFunctionalitySupported(const std::string& extension) const
713 {
714         // NOTE: current implementation uses isInstanceExtensionSupported but
715         // this will change when some instance extensions will be promoted to the
716         // core; don't use isInstanceExtensionSupported directly, use this method instead
717         return isInstanceExtensionSupported(getUsedApiVersion(), getInstanceExtensions(), extension);
718 }
719
720 #include "vkDeviceFeaturesForContextDefs.inl"
721
722 const vk::VkPhysicalDeviceProperties&                   Context::getDeviceProperties                            (void) const { return m_device->getDeviceProperties();                  }
723 const vk::VkPhysicalDeviceProperties2&                  Context::getDeviceProperties2                           (void) const { return m_device->getDeviceProperties2();                 }
724 const vk::VkPhysicalDeviceVulkan11Properties&   Context::getDeviceVulkan11Properties            (void) const { return m_device->getDeviceVulkan11Properties();  }
725 const vk::VkPhysicalDeviceVulkan12Properties&   Context::getDeviceVulkan12Properties            (void) const { return m_device->getDeviceVulkan12Properties();  }
726 #ifndef CTS_USES_VULKANSC
727 const vk::VkPhysicalDeviceVulkan13Properties&   Context::getDeviceVulkan13Properties            (void) const { return m_device->getDeviceVulkan13Properties();  }
728 #endif // CTS_USES_VULKANSC
729 #ifdef CTS_USES_VULKANSC
730 const vk::VkPhysicalDeviceVulkanSC10Properties& Context::getDeviceVulkanSC10Properties          (void) const { return m_device->getDeviceVulkanSC10Properties(); }
731 #endif // CTS_USES_VULKANSC
732
733 #include "vkDevicePropertiesForContextDefs.inl"
734
735 const vector<string>&                                   Context::getDeviceExtensions                            (void) const { return m_device->getDeviceExtensions();                  }
736 vk::VkDevice                                                    Context::getDevice                                                      (void) const { return m_device->getDevice();                                    }
737 const vk::DeviceInterface&                              Context::getDeviceInterface                                     (void) const { return m_device->getDeviceInterface();                   }
738 deUint32                                                                Context::getUniversalQueueFamilyIndex           (void) const { return m_device->getUniversalQueueFamilyIndex(); }
739 vk::VkQueue                                                             Context::getUniversalQueue                                      (void) const { return m_device->getUniversalQueue();                    }
740 deUint32                                                                Context::getSparseQueueFamilyIndex                      (void) const { return m_device->getSparseQueueFamilyIndex();    }
741 vk::VkQueue                                                             Context::getSparseQueue                                         (void) const { return m_device->getSparseQueue();                               }
742 de::SharedPtr<vk::ResourceInterface>    Context::getResourceInterface                           (void) const { return m_resourceInterface;                                              }
743 vk::Allocator&                                                  Context::getDefaultAllocator                            (void) const { return *m_allocator;                                                             }
744 deUint32                                                                Context::getUsedApiVersion                                      (void) const { return m_device->getUsedApiVersion();                    }
745 bool                                                                    Context::contextSupports                                        (const deUint32 variantNum, const deUint32 majorNum, const deUint32 minorNum, const deUint32 patchNum) const
746                                                                                                                                                                                         { return isApiVersionSupported(m_device->getUsedApiVersion(), VK_MAKE_API_VERSION(variantNum, majorNum, minorNum, patchNum)); }
747 bool                                                                    Context::contextSupports                                        (const ApiVersion version) const
748                                                                                                                                                                                         { return isApiVersionSupported(m_device->getUsedApiVersion(), pack(version)); }
749 bool                                                                    Context::contextSupports                                        (const deUint32 requiredApiVersionBits) const
750                                                                                                                                                                                         { return isApiVersionSupported(m_device->getUsedApiVersion(), requiredApiVersionBits); }
751 bool                                                                    Context::isDeviceFeatureInitialized                     (vk::VkStructureType sType) const
752                                                                                                                                                                                         { return m_device->isDeviceFeatureInitialized(sType);   }
753 bool                                                                    Context::isDevicePropertyInitialized            (vk::VkStructureType sType) const
754                                                                                                                                                                                         { return m_device->isDevicePropertyInitialized(sType);  }
755
756 bool Context::requireDeviceFunctionality (const std::string& required) const
757 {
758         if (!isDeviceFunctionalitySupported(required))
759                 TCU_THROW(NotSupportedError, required + " is not supported");
760
761         return true;
762 }
763
764 bool Context::requireInstanceFunctionality (const std::string& required) const
765 {
766         if (!isInstanceFunctionalitySupported(required))
767                 TCU_THROW(NotSupportedError, required + " is not supported");
768
769         return true;
770 }
771
772 struct DeviceCoreFeaturesTable
773 {
774         const char*             featureName;
775         const deUint32  featureArrayIndex;
776         const deUint32  featureArrayOffset;
777 };
778
779 #define DEVICE_CORE_FEATURE_OFFSET(FEATURE_FIELD_NAME)  DE_OFFSET_OF(VkPhysicalDeviceFeatures, FEATURE_FIELD_NAME)
780 #define DEVICE_CORE_FEATURE_ENTRY(BITNAME, FIELDNAME)   { #FIELDNAME, BITNAME, DEVICE_CORE_FEATURE_OFFSET(FIELDNAME) }
781
782 const DeviceCoreFeaturesTable   deviceCoreFeaturesTable[] =
783 {
784         DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_ROBUST_BUFFER_ACCESS                                                      ,       robustBufferAccess                                              ),
785         DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_FULL_DRAW_INDEX_UINT32                                            ,       fullDrawIndexUint32                                             ),
786         DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_IMAGE_CUBE_ARRAY                                                          ,       imageCubeArray                                                  ),
787         DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_INDEPENDENT_BLEND                                                         ,       independentBlend                                                ),
788         DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_GEOMETRY_SHADER                                                           ,       geometryShader                                                  ),
789         DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_TESSELLATION_SHADER                                                       ,       tessellationShader                                              ),
790         DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SAMPLE_RATE_SHADING                                                       ,       sampleRateShading                                               ),
791         DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_DUAL_SRC_BLEND                                                            ,       dualSrcBlend                                                    ),
792         DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_LOGIC_OP                                                                          ,       logicOp                                                                 ),
793         DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_MULTI_DRAW_INDIRECT                                                       ,       multiDrawIndirect                                               ),
794         DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_DRAW_INDIRECT_FIRST_INSTANCE                                      ,       drawIndirectFirstInstance                               ),
795         DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_DEPTH_CLAMP                                                                       ,       depthClamp                                                              ),
796         DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_DEPTH_BIAS_CLAMP                                                          ,       depthBiasClamp                                                  ),
797         DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_FILL_MODE_NON_SOLID                                                       ,       fillModeNonSolid                                                ),
798         DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_DEPTH_BOUNDS                                                                      ,       depthBounds                                                             ),
799         DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_WIDE_LINES                                                                        ,       wideLines                                                               ),
800         DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_LARGE_POINTS                                                                      ,       largePoints                                                             ),
801         DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_ALPHA_TO_ONE                                                                      ,       alphaToOne                                                              ),
802         DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_MULTI_VIEWPORT                                                            ,       multiViewport                                                   ),
803         DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SAMPLER_ANISOTROPY                                                        ,       samplerAnisotropy                                               ),
804         DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_TEXTURE_COMPRESSION_ETC2                                          ,       textureCompressionETC2                                  ),
805         DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_TEXTURE_COMPRESSION_ASTC_LDR                                      ,       textureCompressionASTC_LDR                              ),
806         DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_TEXTURE_COMPRESSION_BC                                            ,       textureCompressionBC                                    ),
807         DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_OCCLUSION_QUERY_PRECISE                                           ,       occlusionQueryPrecise                                   ),
808         DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_PIPELINE_STATISTICS_QUERY                                         ,       pipelineStatisticsQuery                                 ),
809         DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_VERTEX_PIPELINE_STORES_AND_ATOMICS                        ,       vertexPipelineStoresAndAtomics                  ),
810         DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_FRAGMENT_STORES_AND_ATOMICS                                       ,       fragmentStoresAndAtomics                                ),
811         DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_TESSELLATION_AND_GEOMETRY_POINT_SIZE       ,       shaderTessellationAndGeometryPointSize  ),
812         DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_IMAGE_GATHER_EXTENDED                                      ,       shaderImageGatherExtended                               ),
813         DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_STORAGE_IMAGE_EXTENDED_FORMATS                     ,       shaderStorageImageExtendedFormats               ),
814         DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_STORAGE_IMAGE_MULTISAMPLE                          ,       shaderStorageImageMultisample                   ),
815         DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_STORAGE_IMAGE_READ_WITHOUT_FORMAT          ,       shaderStorageImageReadWithoutFormat             ),
816         DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_STORAGE_IMAGE_WRITE_WITHOUT_FORMAT         ,       shaderStorageImageWriteWithoutFormat    ),
817         DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_UNIFORM_BUFFER_ARRAY_DYNAMIC_INDEXING      ,       shaderUniformBufferArrayDynamicIndexing ),
818         DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_SAMPLED_IMAGE_ARRAY_DYNAMIC_INDEXING       ,       shaderSampledImageArrayDynamicIndexing  ),
819         DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_STORAGE_BUFFER_ARRAY_DYNAMIC_INDEXING      ,       shaderStorageBufferArrayDynamicIndexing ),
820         DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_STORAGE_IMAGE_ARRAY_DYNAMIC_INDEXING       ,       shaderStorageImageArrayDynamicIndexing  ),
821         DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_CLIP_DISTANCE                                                      ,       shaderClipDistance                                              ),
822         DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_CULL_DISTANCE                                                      ,       shaderCullDistance                                              ),
823         DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_FLOAT64                                                            ,       shaderFloat64                                                   ),
824         DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_INT64                                                                      ,       shaderInt64                                                             ),
825         DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_INT16                                                                      ,       shaderInt16                                                             ),
826         DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_RESOURCE_RESIDENCY                                         ,       shaderResourceResidency                                 ),
827         DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_RESOURCE_MIN_LOD                                           ,       shaderResourceMinLod                                    ),
828         DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SPARSE_BINDING                                                            ,       sparseBinding                                                   ),
829         DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SPARSE_RESIDENCY_BUFFER                                           ,       sparseResidencyBuffer                                   ),
830         DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SPARSE_RESIDENCY_IMAGE2D                                          ,       sparseResidencyImage2D                                  ),
831         DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SPARSE_RESIDENCY_IMAGE3D                                          ,       sparseResidencyImage3D                                  ),
832         DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SPARSE_RESIDENCY2_SAMPLES                                         ,       sparseResidency2Samples                                 ),
833         DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SPARSE_RESIDENCY4_SAMPLES                                         ,       sparseResidency4Samples                                 ),
834         DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SPARSE_RESIDENCY8_SAMPLES                                         ,       sparseResidency8Samples                                 ),
835         DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SPARSE_RESIDENCY16_SAMPLES                                        ,       sparseResidency16Samples                                ),
836         DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SPARSE_RESIDENCY_ALIASED                                          ,       sparseResidencyAliased                                  ),
837         DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_VARIABLE_MULTISAMPLE_RATE                                         ,       variableMultisampleRate                                 ),
838         DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_INHERITED_QUERIES                                                         ,       inheritedQueries                                                ),
839 };
840
841 bool Context::requireDeviceCoreFeature (const DeviceCoreFeature requiredFeature)
842 {
843         const vk::VkPhysicalDeviceFeatures& featuresAvailable           = getDeviceFeatures();
844         const vk::VkBool32*                                     featuresAvailableArray  = (vk::VkBool32*)(&featuresAvailable);
845         const deUint32                                          requiredFeatureIndex    = static_cast<deUint32>(requiredFeature);
846
847         DE_ASSERT(requiredFeatureIndex * sizeof(vk::VkBool32) < sizeof(featuresAvailable));
848         DE_ASSERT(deviceCoreFeaturesTable[requiredFeatureIndex].featureArrayIndex * sizeof(vk::VkBool32) == deviceCoreFeaturesTable[requiredFeatureIndex].featureArrayOffset);
849
850         if (featuresAvailableArray[requiredFeatureIndex] == DE_FALSE)
851                 TCU_THROW(NotSupportedError, "Requested core feature is not supported: " + std::string(deviceCoreFeaturesTable[requiredFeatureIndex].featureName));
852
853         return true;
854 }
855
856 #ifndef CTS_USES_VULKANSC
857
858 static bool isExtendedStorageFormat (VkFormat format)
859 {
860         switch(format)
861         {
862                 case VK_FORMAT_R8G8B8A8_UNORM:
863                 case VK_FORMAT_R8G8B8A8_SNORM:
864                 case VK_FORMAT_R8G8B8A8_UINT:
865                 case VK_FORMAT_R8G8B8A8_SINT:
866                 case VK_FORMAT_R32_UINT:
867                 case VK_FORMAT_R32_SINT:
868                 case VK_FORMAT_R32_SFLOAT:
869                 case VK_FORMAT_R32G32_UINT:
870                 case VK_FORMAT_R32G32_SINT:
871                 case VK_FORMAT_R32G32_SFLOAT:
872                 case VK_FORMAT_R32G32B32A32_UINT:
873                 case VK_FORMAT_R32G32B32A32_SINT:
874                 case VK_FORMAT_R32G32B32A32_SFLOAT:
875                 case VK_FORMAT_R16G16B16A16_UINT:
876                 case VK_FORMAT_R16G16B16A16_SINT:
877                 case VK_FORMAT_R16G16B16A16_SFLOAT:
878                 case VK_FORMAT_R16G16_SFLOAT:
879                 case VK_FORMAT_B10G11R11_UFLOAT_PACK32:
880                 case VK_FORMAT_R16_SFLOAT:
881                 case VK_FORMAT_R16G16B16A16_UNORM:
882                 case VK_FORMAT_A2B10G10R10_UNORM_PACK32:
883                 case VK_FORMAT_R16G16_UNORM:
884                 case VK_FORMAT_R8G8_UNORM:
885                 case VK_FORMAT_R16_UNORM:
886                 case VK_FORMAT_R8_UNORM:
887                 case VK_FORMAT_R16G16B16A16_SNORM:
888                 case VK_FORMAT_R16G16_SNORM:
889                 case VK_FORMAT_R8G8_SNORM:
890                 case VK_FORMAT_R16_SNORM:
891                 case VK_FORMAT_R8_SNORM:
892                 case VK_FORMAT_R16G16_SINT:
893                 case VK_FORMAT_R8G8_SINT:
894                 case VK_FORMAT_R16_SINT:
895                 case VK_FORMAT_R8_SINT:
896                 case VK_FORMAT_A2B10G10R10_UINT_PACK32:
897                 case VK_FORMAT_R16G16_UINT:
898                 case VK_FORMAT_R8G8_UINT:
899                 case VK_FORMAT_R16_UINT:
900                 case VK_FORMAT_R8_UINT:
901                         return true;
902                 default:
903                         return false;
904         }
905 }
906
907 static bool isDepthFormat (VkFormat format)
908 {
909         switch(format)
910         {
911                 case VK_FORMAT_D16_UNORM:
912                 case VK_FORMAT_X8_D24_UNORM_PACK32:
913                 case VK_FORMAT_D32_SFLOAT:
914                 case VK_FORMAT_D16_UNORM_S8_UINT:
915                 case VK_FORMAT_D24_UNORM_S8_UINT:
916                 case VK_FORMAT_D32_SFLOAT_S8_UINT:
917                         return true;
918                 default:
919                         return false;
920         }
921 }
922
923 vk::VkFormatProperties3 Context::getRequiredFormatProperties(const vk::VkFormat& format) const
924 {
925         vk::VkFormatProperties3 p;
926         p.sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_3;
927         p.pNext = DE_NULL;
928
929         vk::VkFormatProperties properties;
930         getInstanceInterface().getPhysicalDeviceFormatProperties(getPhysicalDevice(), format, &properties);
931         p.linearTilingFeatures  = properties.linearTilingFeatures;
932         p.optimalTilingFeatures = properties.optimalTilingFeatures;
933         p.bufferFeatures                = properties.bufferFeatures;
934
935         const vk::VkPhysicalDeviceFeatures& featuresAvailable = getDeviceFeatures();
936         if (isExtendedStorageFormat(format) && featuresAvailable.shaderStorageImageReadWithoutFormat)
937         {
938                 if (p.linearTilingFeatures & VK_FORMAT_FEATURE_2_STORAGE_IMAGE_BIT_KHR)
939                         p.linearTilingFeatures  |= VK_FORMAT_FEATURE_2_STORAGE_READ_WITHOUT_FORMAT_BIT_KHR;
940                 if (p.optimalTilingFeatures & VK_FORMAT_FEATURE_2_STORAGE_IMAGE_BIT_KHR)
941                         p.optimalTilingFeatures |= VK_FORMAT_FEATURE_2_STORAGE_READ_WITHOUT_FORMAT_BIT_KHR;
942         }
943         if (isExtendedStorageFormat(format) && featuresAvailable.shaderStorageImageWriteWithoutFormat)
944         {
945                 if (p.linearTilingFeatures & VK_FORMAT_FEATURE_2_STORAGE_IMAGE_BIT_KHR)
946                         p.linearTilingFeatures  |= VK_FORMAT_FEATURE_2_STORAGE_WRITE_WITHOUT_FORMAT_BIT_KHR;
947                 if (p.optimalTilingFeatures & VK_FORMAT_FEATURE_2_STORAGE_IMAGE_BIT_KHR)
948                         p.optimalTilingFeatures |= VK_FORMAT_FEATURE_2_STORAGE_WRITE_WITHOUT_FORMAT_BIT_KHR;
949         }
950         if (isDepthFormat(format) && (p.linearTilingFeatures & (VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_BIT_KHR)))
951                 p.linearTilingFeatures |= VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_DEPTH_COMPARISON_BIT_KHR;
952         if (isDepthFormat(format) && (p.optimalTilingFeatures & (VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_BIT_KHR)))
953                 p.optimalTilingFeatures |= VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_DEPTH_COMPARISON_BIT_KHR;
954
955         return p;
956 }
957
958 vk::VkFormatProperties3 Context::getFormatProperties(const vk::VkFormat& format) const
959 {
960         if (isDeviceFunctionalitySupported("VK_KHR_format_feature_flags2"))
961         {
962                 vk::VkFormatProperties3 p;
963                 p.sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_3;
964                 p.pNext = DE_NULL;
965
966                 vk::VkFormatProperties2 properties;
967                 properties.sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2;
968                 properties.pNext = &p;
969
970                 getInstanceInterface().getPhysicalDeviceFormatProperties2(getPhysicalDevice(), format, &properties);
971                 return p;
972         }
973         else
974                 return Context::getRequiredFormatProperties(format);
975 }
976
977 #endif // CTS_USES_VULKANSC
978
979 void* Context::getInstanceProcAddr      ()
980 {
981         return (void*)m_platformInterface.getGetInstanceProcAddr();
982 }
983
984 bool Context::isBufferDeviceAddressSupported(void) const
985 {
986         return isDeviceFunctionalitySupported("VK_KHR_buffer_device_address") ||
987                    isDeviceFunctionalitySupported("VK_EXT_buffer_device_address");
988 }
989
990 #ifndef CTS_USES_VULKANSC
991
992 bool Context::hasDebugReportRecorder () const
993 {
994         return m_device->hasDebugReportRecorder();
995 }
996
997 vk::DebugReportRecorder& Context::getDebugReportRecorder () const
998 {
999         return m_device->getDebugReportRecorder();
1000 }
1001
1002 #endif // CTS_USES_VULKANSC
1003
1004 void Context::resetCommandPoolForVKSC   (const VkDevice                                 device,
1005                                                                                  const VkCommandPool                    commandPool)
1006 {
1007 #ifdef CTS_USES_VULKANSC
1008         if (getDeviceVulkanSC10Properties().commandPoolResetCommandBuffer == VK_FALSE) {
1009                 const DeviceInterface &vk = getDeviceInterface();
1010                 VK_CHECK(vk.resetCommandPool(device, commandPool, 0u));
1011         }
1012 #else
1013         DE_UNREF(device);
1014         DE_UNREF(commandPool);
1015 #endif
1016 }
1017
1018 ContextCommonData Context::getContextCommonData() {
1019         return ContextCommonData {
1020                 getInstanceInterface(),
1021                 getDevice(),
1022                 getDeviceInterface(),
1023                 getPhysicalDevice(),
1024                 getDefaultAllocator(),
1025                 getUniversalQueueFamilyIndex(),
1026                 getUniversalQueue()
1027         };
1028 }
1029
1030 // TestCase
1031
1032 void TestCase::initPrograms (SourceCollections&) const
1033 {
1034 }
1035
1036 void TestCase::checkSupport (Context&) const
1037 {
1038 }
1039
1040 void TestCase::delayedInit (void)
1041 {
1042 }
1043
1044 #ifndef CTS_USES_VULKANSC
1045
1046 void collectAndReportDebugMessages(vk::DebugReportRecorder &debugReportRecorder, Context& context)
1047 {
1048         using DebugMessages = vk::DebugReportRecorder::MessageList;
1049
1050         const DebugMessages&    messages        = debugReportRecorder.getMessages();
1051         tcu::TestLog&                   log                     = context.getTestContext().getLog();
1052
1053         if (messages.size() > 0)
1054         {
1055                 const tcu::ScopedLogSection     section         (log, "DebugMessages", "Debug Messages");
1056                 int                                                     numErrors       = 0;
1057
1058                 for (const auto& msg : messages)
1059                 {
1060                         if (msg.shouldBeLogged())
1061                                 log << tcu::TestLog::Message << msg << tcu::TestLog::EndMessage;
1062
1063                         if (msg.isError())
1064                                 numErrors += 1;
1065                 }
1066
1067                 debugReportRecorder.clearMessages();
1068
1069                 if (numErrors > 0)
1070                 {
1071                         string errorMsg = de::toString(numErrors) + " API usage errors found";
1072                         context.resultSetOnValidation(true);
1073                         context.getTestContext().setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, errorMsg.c_str());
1074                 }
1075         }
1076 }
1077
1078 #endif // CTS_USES_VULKANSC
1079
1080 } // vkt