• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*-------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2015 Google Inc.
6  * Copyright (c) 2023 LunarG, Inc.
7  * Copyright (c) 2023 Nintendo
8  *
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  *      http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  *
21  *//*!
22  * \file
23  * \brief Vulkan test case base classes
24  *//*--------------------------------------------------------------------*/
25 
26 #include "vktTestCase.hpp"
27 #include "vktCustomInstancesDevices.hpp"
28 
29 #include "vkRef.hpp"
30 #include "vkRefUtil.hpp"
31 #include "vkQueryUtil.hpp"
32 #include "vkDeviceUtil.hpp"
33 #include "vkMemUtil.hpp"
34 #include "vkPlatform.hpp"
35 #include "vkDebugReportUtil.hpp"
36 #include "vkDeviceFeatures.hpp"
37 #include "vkDeviceProperties.hpp"
38 #ifdef CTS_USES_VULKANSC
39 #include "vkSafetyCriticalUtil.hpp"
40 #include "vkAppParamsUtil.hpp"
41 #endif // CTS_USES_VULKANSC
42 
43 #include "tcuCommandLine.hpp"
44 #include "tcuTestLog.hpp"
45 
46 #include "deSTLUtil.hpp"
47 #include "deMemory.h"
48 
49 #include <set>
50 #include <cstring>
51 #include <iterator>
52 #include <algorithm>
53 
54 namespace vkt
55 {
56 
57 // Default device utilities
58 
59 using std::set;
60 using std::string;
61 using std::vector;
62 using namespace vk;
63 
64 namespace
65 {
66 
filterExtensions(const vector<VkExtensionProperties> & extensions)67 vector<string> filterExtensions(const vector<VkExtensionProperties> &extensions)
68 {
69     vector<string> enabledExtensions;
70     bool khrBufferDeviceAddress = false;
71     bool excludeExtension       = false;
72 
73     const char *extensionGroups[] = {
74         "VK_KHR_",
75         "VK_EXT_",
76         "VK_KHX_",
77         "VK_NV_cooperative_matrix",
78         "VK_NV_ray_tracing",
79         "VK_NV_inherited_viewport_scissor",
80         "VK_NV_mesh_shader",
81         "VK_AMD_mixed_attachment_samples",
82         "VK_AMD_buffer_marker",
83         "VK_AMD_shader_explicit_vertex_parameter",
84         "VK_AMD_shader_image_load_store_lod",
85         "VK_AMD_shader_trinary_minmax",
86         "VK_AMD_texture_gather_bias_lod",
87         "VK_AMD_shader_early_and_late_fragment_tests",
88         "VK_ANDROID_external_memory_android_hardware_buffer",
89         "VK_ANDROID_external_format_resolve",
90         "VK_VALVE_mutable_descriptor_type",
91         "VK_NV_shader_subgroup_partitioned",
92         "VK_NV_clip_space_w_scaling",
93         "VK_NV_scissor_exclusive",
94         "VK_NV_shading_rate_image",
95         "VK_ARM_rasterization_order_attachment_access",
96         "VK_GOOGLE_surfaceless_query",
97         "VK_FUCHSIA_",
98         "VK_NV_fragment_coverage_to_color",
99         "VK_NV_framebuffer_mixed_samples",
100         "VK_NV_coverage_reduction_mode",
101         "VK_NV_viewport_swizzle",
102         "VK_NV_representative_fragment_test",
103         "VK_NV_device_generated_commands", // This filter also applies to _compute.
104         "VK_NV_shader_atomic_float16_vector",
105         "VK_MVK_macos_surface",
106         "VK_NV_raw_access_chains",
107         "VK_NV_linear_color_attachment",
108         "VK_NV_cooperative_matrix2",
109     };
110 
111     const char *exclusions[] = {"VK_EXT_device_address_binding_report", "VK_EXT_device_memory_report"};
112 
113     for (size_t extNdx = 0; extNdx < extensions.size(); extNdx++)
114     {
115         if (strcmp(extensions[extNdx].extensionName, "VK_KHR_buffer_device_address") == 0)
116         {
117             khrBufferDeviceAddress = true;
118             break;
119         }
120     }
121 
122     for (size_t extNdx = 0; extNdx < extensions.size(); extNdx++)
123     {
124         const auto &extName = extensions[extNdx].extensionName;
125 
126         excludeExtension = false;
127 
128         // VK_EXT_buffer_device_address is deprecated and must not be enabled if VK_KHR_buffer_device_address is enabled
129         if (khrBufferDeviceAddress && strcmp(extName, "VK_EXT_buffer_device_address") == 0)
130             continue;
131 
132         for (int exclusionsNdx = 0; exclusionsNdx < DE_LENGTH_OF_ARRAY(exclusions); exclusionsNdx++)
133         {
134             if (strcmp(extName, exclusions[exclusionsNdx]) == 0)
135             {
136                 excludeExtension = true;
137                 break;
138             }
139         }
140 
141         if (excludeExtension)
142             continue;
143 
144         for (int extGroupNdx = 0; extGroupNdx < DE_LENGTH_OF_ARRAY(extensionGroups); extGroupNdx++)
145         {
146             if (deStringBeginsWith(extName, extensionGroups[extGroupNdx]))
147                 enabledExtensions.push_back(extName);
148         }
149     }
150 
151     return enabledExtensions;
152 }
153 
addExtensions(const vector<string> & a,const vector<const char * > & b)154 vector<string> addExtensions(const vector<string> &a, const vector<const char *> &b)
155 {
156     vector<string> res(a);
157 
158     for (vector<const char *>::const_iterator bIter = b.begin(); bIter != b.end(); ++bIter)
159     {
160         if (!de::contains(res.begin(), res.end(), string(*bIter)))
161             res.push_back(string(*bIter));
162     }
163 
164     return res;
165 }
166 
addCoreInstanceExtensions(const vector<string> & extensions,uint32_t instanceVersion)167 vector<string> addCoreInstanceExtensions(const vector<string> &extensions, uint32_t instanceVersion)
168 {
169     vector<const char *> coreExtensions;
170     getCoreInstanceExtensions(instanceVersion, coreExtensions);
171     return addExtensions(extensions, coreExtensions);
172 }
173 
addCoreDeviceExtensions(const vector<string> & extensions,uint32_t instanceVersion)174 vector<string> addCoreDeviceExtensions(const vector<string> &extensions, uint32_t instanceVersion)
175 {
176     vector<const char *> coreExtensions;
177     getCoreDeviceExtensions(instanceVersion, coreExtensions);
178     return addExtensions(extensions, coreExtensions);
179 }
180 
getTargetInstanceVersion(const PlatformInterface & vkp)181 uint32_t getTargetInstanceVersion(const PlatformInterface &vkp)
182 {
183     uint32_t version = pack(ApiVersion(0, 1, 0, 0));
184 
185     if (vkp.enumerateInstanceVersion(&version) != VK_SUCCESS)
186         TCU_THROW(InternalError, "Enumerate instance version error");
187 #ifdef CTS_USES_VULKANSC
188     // Temporary workaround for Vulkan loader problem - currently Vulkan loader always returs API variant == 0
189     version = pack(ApiVersion(1, 1, 0, 0));
190 #endif
191     return version;
192 }
193 
determineDeviceVersions(const PlatformInterface & vkp,uint32_t apiVersion,const tcu::CommandLine & cmdLine)194 std::pair<uint32_t, uint32_t> determineDeviceVersions(const PlatformInterface &vkp, uint32_t apiVersion,
195                                                       const tcu::CommandLine &cmdLine)
196 {
197     Move<VkInstance> preinstance = createDefaultInstance(vkp, apiVersion, cmdLine);
198     InstanceDriver preinterface(vkp, preinstance.get());
199 
200     const vector<VkPhysicalDevice> devices = enumeratePhysicalDevices(preinterface, preinstance.get());
201     uint32_t lowestDeviceVersion           = 0xFFFFFFFFu;
202     for (uint32_t deviceNdx = 0u; deviceNdx < devices.size(); ++deviceNdx)
203     {
204         const VkPhysicalDeviceProperties props = getPhysicalDeviceProperties(preinterface, devices[deviceNdx]);
205         if (props.apiVersion < lowestDeviceVersion)
206             lowestDeviceVersion = props.apiVersion;
207     }
208 
209     const vk::VkPhysicalDevice choosenDevice = chooseDevice(preinterface, *preinstance, cmdLine);
210     const VkPhysicalDeviceProperties props   = getPhysicalDeviceProperties(preinterface, choosenDevice);
211     const uint32_t choosenDeviceVersion      = props.apiVersion;
212 
213     return std::make_pair(choosenDeviceVersion, lowestDeviceVersion);
214 }
215 
216 // Remove extensions from a which are found in b.
removeExtensions(const vector<string> & a,const vector<const char * > & b)217 vector<string> removeExtensions(const vector<string> &a, const vector<const char *> &b)
218 {
219     vector<string> res;
220     set<string> removeExts(b.begin(), b.end());
221 
222     for (vector<string>::const_iterator aIter = a.begin(); aIter != a.end(); ++aIter)
223     {
224         if (!de::contains(removeExts, *aIter))
225             res.push_back(*aIter);
226     }
227 
228     return res;
229 }
230 
231 #ifndef CTS_USES_VULKANSC
createInstance(const PlatformInterface & vkp,uint32_t apiVersion,const vector<string> & enabledExtensions,const tcu::CommandLine & cmdLine,DebugReportRecorder * recorder)232 Move<VkInstance> createInstance(const PlatformInterface &vkp, uint32_t apiVersion,
233                                 const vector<string> &enabledExtensions, const tcu::CommandLine &cmdLine,
234                                 DebugReportRecorder *recorder)
235 #else
236 Move<VkInstance> createInstance(const PlatformInterface &vkp, uint32_t apiVersion,
237                                 const vector<string> &enabledExtensions, const tcu::CommandLine &cmdLine)
238 #endif // CTS_USES_VULKANSC
239 {
240 #ifndef CTS_USES_VULKANSC
241     const bool isValidationEnabled = (recorder != nullptr);
242 #else
243     const bool isValidationEnabled = false;
244 #endif // CTS_USES_VULKANSC
245     vector<const char *> enabledLayers;
246 
247     // \note Extensions in core are not explicitly enabled even though
248     //         they are in the extension list advertised to tests.
249     vector<const char *> coreExtensions;
250     getCoreInstanceExtensions(apiVersion, coreExtensions);
251     const auto nonCoreExtensions = removeExtensions(enabledExtensions, coreExtensions);
252 
253     if (isValidationEnabled)
254     {
255         if (!isDebugUtilsSupported(vkp))
256             TCU_THROW(NotSupportedError, "VK_EXT_utils_report is not supported");
257 
258         enabledLayers = vkt::getValidationLayers(vkp);
259         if (enabledLayers.empty())
260             TCU_THROW(NotSupportedError, "No validation layers found");
261     }
262 
263 #ifndef CTS_USES_VULKANSC
264     return createDefaultInstance(vkp, apiVersion, vector<string>(begin(enabledLayers), end(enabledLayers)),
265                                  nonCoreExtensions, cmdLine, recorder);
266 #else
267     return createDefaultInstance(vkp, apiVersion, vector<string>(begin(enabledLayers), end(enabledLayers)),
268                                  nonCoreExtensions, cmdLine);
269 #endif // CTS_USES_VULKANSC
270 }
271 
createDefaultDevice(const PlatformInterface & vkp,VkInstance instance,const InstanceInterface & vki,VkPhysicalDevice physicalDevice,uint32_t universalQueueIndex,uint32_t sparseQueueIndex,int computeQueueIndex,int transferQueueIndex,const VkPhysicalDeviceFeatures2 & enabledFeatures,const vector<const char * > & usedExtensions,const tcu::CommandLine & cmdLine,de::SharedPtr<vk::ResourceInterface> resourceInterface)272 Move<VkDevice> createDefaultDevice(const PlatformInterface &vkp, VkInstance instance, const InstanceInterface &vki,
273                                    VkPhysicalDevice physicalDevice, uint32_t universalQueueIndex,
274                                    uint32_t sparseQueueIndex, int computeQueueIndex, int transferQueueIndex,
275                                    const VkPhysicalDeviceFeatures2 &enabledFeatures,
276                                    const vector<const char *> &usedExtensions, const tcu::CommandLine &cmdLine,
277                                    de::SharedPtr<vk::ResourceInterface> resourceInterface)
278 {
279     VkDeviceQueueCreateInfo queueInfo[4];
280     VkDeviceCreateInfo deviceInfo;
281     vector<const char *> enabledLayers;
282     const float queuePriority = 1.0f;
283     uint32_t numQueues        = 1;
284 
285     deMemset(&queueInfo, 0, sizeof(queueInfo));
286 
287     // Always create the universal queue.
288     queueInfo[0].sType            = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
289     queueInfo[0].pNext            = nullptr;
290     queueInfo[0].flags            = (VkDeviceQueueCreateFlags)0u;
291     queueInfo[0].queueFamilyIndex = universalQueueIndex;
292     queueInfo[0].queueCount       = 1u;
293     queueInfo[0].pQueuePriorities = &queuePriority;
294 
295     // And the optional queues if they differ from the "universal" queue, and are supported.
296     if (enabledFeatures.features.sparseBinding && (universalQueueIndex != sparseQueueIndex))
297     {
298         queueInfo[numQueues].sType            = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
299         queueInfo[numQueues].pNext            = nullptr;
300         queueInfo[numQueues].flags            = (VkDeviceQueueCreateFlags)0u;
301         queueInfo[numQueues].queueFamilyIndex = sparseQueueIndex;
302         queueInfo[numQueues].queueCount       = 1u;
303         queueInfo[numQueues].pQueuePriorities = &queuePriority;
304         numQueues++;
305     }
306     if (computeQueueIndex != -1 && (universalQueueIndex != (uint32_t)computeQueueIndex))
307     {
308         queueInfo[numQueues].sType            = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
309         queueInfo[numQueues].pNext            = nullptr;
310         queueInfo[numQueues].flags            = (VkDeviceQueueCreateFlags)0u;
311         queueInfo[numQueues].queueFamilyIndex = computeQueueIndex;
312         queueInfo[numQueues].queueCount       = 1u;
313         queueInfo[numQueues].pQueuePriorities = &queuePriority;
314         numQueues++;
315     }
316     if (transferQueueIndex != -1 && (universalQueueIndex != (uint32_t)transferQueueIndex))
317     {
318         queueInfo[numQueues].sType            = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
319         queueInfo[numQueues].pNext            = nullptr;
320         queueInfo[numQueues].flags            = (VkDeviceQueueCreateFlags)0u;
321         queueInfo[numQueues].queueFamilyIndex = transferQueueIndex;
322         queueInfo[numQueues].queueCount       = 1u;
323         queueInfo[numQueues].pQueuePriorities = &queuePriority;
324         numQueues++;
325     }
326 
327     if (cmdLine.isValidationEnabled())
328     {
329         enabledLayers = vkt::getValidationLayers(vki, physicalDevice);
330         if (enabledLayers.empty())
331             TCU_THROW(NotSupportedError, "No validation layers found");
332     }
333 
334     deMemset(&deviceInfo, 0, sizeof(deviceInfo));
335     // VK_KHR_get_physical_device_properties2 is used if enabledFeatures.pNext != 0
336     deviceInfo.sType                   = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
337     deviceInfo.pNext                   = enabledFeatures.pNext ? &enabledFeatures : nullptr;
338     deviceInfo.queueCreateInfoCount    = numQueues;
339     deviceInfo.pQueueCreateInfos       = queueInfo;
340     deviceInfo.enabledExtensionCount   = de::sizeU32(usedExtensions);
341     deviceInfo.ppEnabledExtensionNames = de::dataOrNull(usedExtensions);
342     deviceInfo.enabledLayerCount       = de::sizeU32(enabledLayers);
343     deviceInfo.ppEnabledLayerNames     = de::dataOrNull(enabledLayers);
344     deviceInfo.pEnabledFeatures        = enabledFeatures.pNext ? nullptr : &enabledFeatures.features;
345 
346 #ifdef CTS_USES_VULKANSC
347     // devices created for Vulkan SC must have VkDeviceObjectReservationCreateInfo structure defined in VkDeviceCreateInfo::pNext chain
348     VkDeviceObjectReservationCreateInfo dmrCI = resetDeviceObjectReservationCreateInfo();
349     VkPipelineCacheCreateInfo pcCI            = {
350         VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO, // VkStructureType sType;
351         nullptr,                                      // const void* pNext;
352         VK_PIPELINE_CACHE_CREATE_READ_ONLY_BIT |
353             VK_PIPELINE_CACHE_CREATE_USE_APPLICATION_STORAGE_BIT, // VkPipelineCacheCreateFlags flags;
354         0U,                                                       // uintptr_t initialDataSize;
355         nullptr                                                   // const void* pInitialData;
356     };
357 
358     std::vector<VkPipelinePoolSize> poolSizes;
359     if (cmdLine.isSubProcess())
360     {
361         resourceInterface->importPipelineCacheData(vkp, instance, vki, physicalDevice, universalQueueIndex);
362 
363         dmrCI = resourceInterface->getStatMax();
364 
365         if (resourceInterface->getCacheDataSize() > 0)
366         {
367             pcCI.initialDataSize               = resourceInterface->getCacheDataSize();
368             pcCI.pInitialData                  = resourceInterface->getCacheData();
369             dmrCI.pipelineCacheCreateInfoCount = 1;
370             dmrCI.pPipelineCacheCreateInfos    = &pcCI;
371         }
372 
373         poolSizes = resourceInterface->getPipelinePoolSizes();
374         if (!poolSizes.empty())
375         {
376             dmrCI.pipelinePoolSizeCount = uint32_t(poolSizes.size());
377             dmrCI.pPipelinePoolSizes    = poolSizes.data();
378         }
379     }
380 
381     dmrCI.pNext                                     = deviceInfo.pNext;
382     VkPhysicalDeviceVulkanSC10Features sc10Features = createDefaultSC10Features();
383     if (findStructureInChain(dmrCI.pNext, getStructureType<VkPhysicalDeviceVulkanSC10Features>()) == nullptr)
384     {
385         sc10Features.pNext = &dmrCI;
386         deviceInfo.pNext   = &sc10Features;
387     }
388     else
389         deviceInfo.pNext = &dmrCI;
390 
391     vector<VkApplicationParametersEXT> appParams;
392     if (readApplicationParameters(appParams, cmdLine, false))
393     {
394         appParams[appParams.size() - 1].pNext = deviceInfo.pNext;
395         deviceInfo.pNext                      = &appParams[0];
396     }
397 
398     VkFaultCallbackInfo faultCallbackInfo = {
399         VK_STRUCTURE_TYPE_FAULT_CALLBACK_INFO, // VkStructureType sType;
400         nullptr,                               // void* pNext;
401         0U,                                    // uint32_t faultCount;
402         nullptr,                               // VkFaultData* pFaults;
403         Context::faultCallbackFunction         // PFN_vkFaultCallbackFunction pfnFaultCallback;
404     };
405 
406     if (cmdLine.isSubProcess())
407     {
408         // XXX workaround incorrect constness on faultCallbackInfo.pNext.
409         faultCallbackInfo.pNext = const_cast<void *>(deviceInfo.pNext);
410         deviceInfo.pNext        = &faultCallbackInfo;
411     }
412 
413 #else
414     DE_UNREF(resourceInterface);
415 #endif // CTS_USES_VULKANSC
416 
417     return createDevice(vkp, instance, vki, physicalDevice, &deviceInfo);
418 }
419 
420 } // namespace
421 
findQueueFamilyIndexWithCapsNoThrow(const InstanceInterface & vkInstance,VkPhysicalDevice physicalDevice,VkQueueFlags requiredCaps,VkQueueFlags excludedCaps)422 int findQueueFamilyIndexWithCapsNoThrow(const InstanceInterface &vkInstance, VkPhysicalDevice physicalDevice,
423                                         VkQueueFlags requiredCaps, VkQueueFlags excludedCaps)
424 {
425     try
426     {
427         return static_cast<int>(findQueueFamilyIndexWithCaps(vkInstance, physicalDevice, requiredCaps, excludedCaps));
428     }
429     catch (const tcu::NotSupportedError &)
430     {
431         return -1;
432     }
433 }
434 
findQueueFamilyIndexWithCaps(const InstanceInterface & vkInstance,VkPhysicalDevice physicalDevice,VkQueueFlags requiredCaps,VkQueueFlags excludedCaps)435 uint32_t findQueueFamilyIndexWithCaps(const InstanceInterface &vkInstance, VkPhysicalDevice physicalDevice,
436                                       VkQueueFlags requiredCaps, VkQueueFlags excludedCaps)
437 {
438     const vector<VkQueueFamilyProperties> queueProps =
439         getPhysicalDeviceQueueFamilyProperties(vkInstance, physicalDevice);
440 
441     for (size_t queueNdx = 0; queueNdx < queueProps.size(); queueNdx++)
442     {
443         uint32_t queueFlags = queueProps[queueNdx].queueFlags;
444         if ((queueFlags & requiredCaps) == requiredCaps && !(queueFlags & excludedCaps))
445             return (uint32_t)queueNdx;
446     }
447 
448     TCU_THROW(NotSupportedError, "No matching queue found");
449 }
450 
451 class DefaultDevice
452 {
453 public:
454     DefaultDevice(const PlatformInterface &vkPlatform, const tcu::CommandLine &cmdLine,
455                   de::SharedPtr<vk::ResourceInterface> resourceInterface);
456     ~DefaultDevice(void);
457 
getInstance(void) const458     VkInstance getInstance(void) const
459     {
460         return *m_instance;
461     }
getInstanceInterface(void) const462     const InstanceInterface &getInstanceInterface(void) const
463     {
464         return m_instanceInterface;
465     }
getMaximumFrameworkVulkanVersion(void) const466     uint32_t getMaximumFrameworkVulkanVersion(void) const
467     {
468         return m_maximumFrameworkVulkanVersion;
469     }
getAvailableInstanceVersion(void) const470     uint32_t getAvailableInstanceVersion(void) const
471     {
472         return m_availableInstanceVersion;
473     }
getUsedInstanceVersion(void) const474     uint32_t getUsedInstanceVersion(void) const
475     {
476         return m_usedInstanceVersion;
477     }
getInstanceExtensions(void) const478     const vector<string> &getInstanceExtensions(void) const
479     {
480         return m_instanceExtensions;
481     }
482 
getPhysicalDevice(void) const483     VkPhysicalDevice getPhysicalDevice(void) const
484     {
485         return m_physicalDevice;
486     }
getDeviceVersion(void) const487     uint32_t getDeviceVersion(void) const
488     {
489         return m_deviceVersion;
490     }
491 
isDeviceFeatureInitialized(VkStructureType sType) const492     bool isDeviceFeatureInitialized(VkStructureType sType) const
493     {
494         return m_deviceFeatures.isDeviceFeatureInitialized(sType);
495     }
getDeviceFeatures(void) const496     const VkPhysicalDeviceFeatures &getDeviceFeatures(void) const
497     {
498         return m_deviceFeatures.getCoreFeatures2().features;
499     }
getDeviceFeatures2(void) const500     const VkPhysicalDeviceFeatures2 &getDeviceFeatures2(void) const
501     {
502         return m_deviceFeatures.getCoreFeatures2();
503     }
getVulkan11Features(void) const504     const VkPhysicalDeviceVulkan11Features &getVulkan11Features(void) const
505     {
506         return m_deviceFeatures.getVulkan11Features();
507     }
getVulkan12Features(void) const508     const VkPhysicalDeviceVulkan12Features &getVulkan12Features(void) const
509     {
510         return m_deviceFeatures.getVulkan12Features();
511     }
512 #ifndef CTS_USES_VULKANSC
getVulkan13Features(void) const513     const VkPhysicalDeviceVulkan13Features &getVulkan13Features(void) const
514     {
515         return m_deviceFeatures.getVulkan13Features();
516     }
getVulkan14Features(void) const517     const VkPhysicalDeviceVulkan14Features &getVulkan14Features(void) const
518     {
519         return m_deviceFeatures.getVulkan14Features();
520     }
521 #endif // CTS_USES_VULKANSC
522 
523 #include "vkDeviceFeaturesForDefaultDeviceDefs.inl"
524 
isDevicePropertyInitialized(VkStructureType sType) const525     bool isDevicePropertyInitialized(VkStructureType sType) const
526     {
527         return m_deviceProperties.isDevicePropertyInitialized(sType);
528     }
getDeviceProperties(void) const529     const VkPhysicalDeviceProperties &getDeviceProperties(void) const
530     {
531         return m_deviceProperties.getCoreProperties2().properties;
532     }
getDeviceProperties2(void) const533     const VkPhysicalDeviceProperties2 &getDeviceProperties2(void) const
534     {
535         return m_deviceProperties.getCoreProperties2();
536     }
getDeviceVulkan11Properties(void) const537     const VkPhysicalDeviceVulkan11Properties &getDeviceVulkan11Properties(void) const
538     {
539         return m_deviceProperties.getVulkan11Properties();
540     }
getDeviceVulkan12Properties(void) const541     const VkPhysicalDeviceVulkan12Properties &getDeviceVulkan12Properties(void) const
542     {
543         return m_deviceProperties.getVulkan12Properties();
544     }
545 #ifndef CTS_USES_VULKANSC
getDeviceVulkan13Properties(void) const546     const VkPhysicalDeviceVulkan13Properties &getDeviceVulkan13Properties(void) const
547     {
548         return m_deviceProperties.getVulkan13Properties();
549     }
getDeviceVulkan14Properties(void) const550     const VkPhysicalDeviceVulkan14Properties &getDeviceVulkan14Properties(void) const
551     {
552         return m_deviceProperties.getVulkan14Properties();
553     }
554 #endif // CTS_USES_VULKANSC
555 #ifdef CTS_USES_VULKANSC
getDeviceVulkanSC10Properties(void) const556     const VkPhysicalDeviceVulkanSC10Properties &getDeviceVulkanSC10Properties(void) const
557     {
558         return m_deviceProperties.getVulkanSC10Properties();
559     }
560 #endif // CTS_USES_VULKANSC
561 
562 #include "vkDevicePropertiesForDefaultDeviceDefs.inl"
563 
getDevice(void) const564     VkDevice getDevice(void) const
565     {
566         return *m_device;
567     }
getDeviceInterface(void) const568     const DeviceInterface &getDeviceInterface(void) const
569     {
570         return *m_deviceInterface;
571     }
getDeviceExtensions(void) const572     const vector<string> &getDeviceExtensions(void) const
573     {
574         return m_deviceExtensions;
575     }
getDeviceCreationExtensions(void) const576     const vector<const char *> &getDeviceCreationExtensions(void) const
577     {
578         return m_creationExtensions;
579     }
getUsedApiVersion(void) const580     uint32_t getUsedApiVersion(void) const
581     {
582         return m_usedApiVersion;
583     }
getUniversalQueueFamilyIndex(void) const584     uint32_t getUniversalQueueFamilyIndex(void) const
585     {
586         return m_universalQueueFamilyIndex;
587     }
588     VkQueue getUniversalQueue(void) const;
getSparseQueueFamilyIndex(void) const589     uint32_t getSparseQueueFamilyIndex(void) const
590     {
591         return m_sparseQueueFamilyIndex;
592     }
593     VkQueue getSparseQueue(void) const;
getTransferQueueFamilyIndex(void) const594     int getTransferQueueFamilyIndex(void) const
595     {
596         return m_transferQueueFamilyIndex;
597     }
598     VkQueue getTransferQueue(void) const;
getComputeQueueFamilyIndex(void) const599     int getComputeQueueFamilyIndex(void) const
600     {
601         return m_computeQueueFamilyIndex;
602     }
603     VkQueue getComputeQueue(void) const;
604 #ifndef CTS_USES_VULKANSC
hasDebugReportRecorder(void) const605     bool hasDebugReportRecorder(void) const
606     {
607         return m_debugReportRecorder.get() != nullptr;
608     }
getDebugReportRecorder(void) const609     vk::DebugReportRecorder &getDebugReportRecorder(void) const
610     {
611         return *m_debugReportRecorder.get();
612     }
613 #endif // CTS_USES_VULKANSC
614 
615 private:
616 #ifndef CTS_USES_VULKANSC
617     using DebugReportRecorderPtr = de::UniquePtr<vk::DebugReportRecorder>;
618     using DebugReportCallbackPtr = vk::Move<VkDebugUtilsMessengerEXT>;
619 #endif // CTS_USES_VULKANSC
620 
621     const uint32_t m_maximumFrameworkVulkanVersion;
622     const uint32_t m_availableInstanceVersion;
623     const uint32_t m_usedInstanceVersion;
624 
625     const std::pair<uint32_t, uint32_t> m_deviceVersions;
626     const uint32_t m_usedApiVersion;
627 
628 #ifndef CTS_USES_VULKANSC
629     const DebugReportRecorderPtr m_debugReportRecorder;
630 #endif // CTS_USES_VULKANSC
631     const vector<string> m_instanceExtensions;
632     const Unique<VkInstance> m_instance;
633 #ifndef CTS_USES_VULKANSC
634     const InstanceDriver m_instanceInterface;
635     const DebugReportCallbackPtr m_debugReportCallback;
636 #else
637     const InstanceDriverSC m_instanceInterface;
638 #endif // CTS_USES_VULKANSC
639     const VkPhysicalDevice m_physicalDevice;
640     const uint32_t m_deviceVersion;
641 
642     const vector<string> m_deviceExtensions;
643     const DeviceFeatures m_deviceFeatures;
644 
645     const uint32_t m_universalQueueFamilyIndex;
646     const uint32_t m_sparseQueueFamilyIndex;
647 
648     // Optional exclusive queues
649     const int m_computeQueueFamilyIndex;
650     const int m_transferQueueFamilyIndex;
651 
652     const DeviceProperties m_deviceProperties;
653     const vector<const char *> m_creationExtensions;
654 
655     const Unique<VkDevice> m_device;
656     const de::MovePtr<DeviceDriver> m_deviceInterface;
657 };
658 
659 namespace
660 {
661 
sanitizeApiVersion(uint32_t v)662 uint32_t sanitizeApiVersion(uint32_t v)
663 {
664     return VK_MAKE_API_VERSION(VK_API_VERSION_VARIANT(v), VK_API_VERSION_MAJOR(v), VK_API_VERSION_MINOR(v), 0);
665 }
666 
667 #ifndef CTS_USES_VULKANSC
createDebugReportRecorder(const vk::PlatformInterface & vkp,bool printValidationErrors)668 de::MovePtr<vk::DebugReportRecorder> createDebugReportRecorder(const vk::PlatformInterface &vkp,
669                                                                bool printValidationErrors)
670 {
671     if (isDebugUtilsSupported(vkp))
672         return de::MovePtr<vk::DebugReportRecorder>(new vk::DebugReportRecorder(printValidationErrors));
673     else
674         TCU_THROW(NotSupportedError, "VK_EXT_debug_utils is not supported");
675 }
676 #endif // CTS_USES_VULKANSC
677 
678 // Returns list of non-core extensions. Note the pointers in the result vector come from the extensions vector passed as an argument.
removeCoreExtensions(const uint32_t apiVersion,const vector<string> & extensions)679 vector<const char *> removeCoreExtensions(const uint32_t apiVersion, const vector<string> &extensions)
680 {
681     // Make vector of char ptrs.
682     vector<const char *> extensionPtrs;
683     extensionPtrs.reserve(extensions.size());
684     std::transform(begin(extensions), end(extensions), std::back_inserter(extensionPtrs),
685                    [](const string &s) { return s.c_str(); });
686 
687     // Obtain the core extension list.
688     vector<const char *> coreExtensions;
689     getCoreDeviceExtensions(apiVersion, coreExtensions);
690 
691     // Remove any extension found in the core extension list.
692     const auto isNonCoreExtension = [&coreExtensions](const char *extName)
693     {
694         const auto isSameString = [&extName](const char *otherExtName)
695         { return (std::strcmp(otherExtName, extName) == 0); };
696         return std::find_if(begin(coreExtensions), end(coreExtensions), isSameString) == end(coreExtensions);
697     };
698 
699     vector<const char *> filteredExtensions;
700     std::copy_if(begin(extensionPtrs), end(extensionPtrs), std::back_inserter(filteredExtensions), isNonCoreExtension);
701     return filteredExtensions;
702 }
703 
704 } // namespace
705 
DefaultDevice(const PlatformInterface & vkPlatform,const tcu::CommandLine & cmdLine,de::SharedPtr<vk::ResourceInterface> resourceInterface)706 DefaultDevice::DefaultDevice(const PlatformInterface &vkPlatform, const tcu::CommandLine &cmdLine,
707                              de::SharedPtr<vk::ResourceInterface> resourceInterface)
708 #ifndef CTS_USES_VULKANSC
709     : m_maximumFrameworkVulkanVersion(VK_API_MAX_FRAMEWORK_VERSION)
710 #else
711     : m_maximumFrameworkVulkanVersion(VKSC_API_MAX_FRAMEWORK_VERSION)
712 #endif // CTS_USES_VULKANSC
713     , m_availableInstanceVersion(getTargetInstanceVersion(vkPlatform))
714     , m_usedInstanceVersion(
715           sanitizeApiVersion(minVulkanAPIVersion(m_availableInstanceVersion, m_maximumFrameworkVulkanVersion)))
716     , m_deviceVersions(determineDeviceVersions(vkPlatform, m_usedInstanceVersion, cmdLine))
717     , m_usedApiVersion(sanitizeApiVersion(minVulkanAPIVersion(m_usedInstanceVersion, m_deviceVersions.first)))
718 
719 #ifndef CTS_USES_VULKANSC
720     , m_debugReportRecorder(cmdLine.isValidationEnabled() ?
721                                 createDebugReportRecorder(vkPlatform, cmdLine.printValidationErrors()) :
722                                 de::MovePtr<vk::DebugReportRecorder>())
723 #endif // CTS_USES_VULKANSC
724     , m_instanceExtensions(addCoreInstanceExtensions(
725           filterExtensions(enumerateInstanceExtensionProperties(vkPlatform, nullptr)), m_usedApiVersion))
726 #ifndef CTS_USES_VULKANSC
727     , m_instance(
728           createInstance(vkPlatform, m_usedApiVersion, m_instanceExtensions, cmdLine, m_debugReportRecorder.get()))
729 #else
730     , m_instance(createInstance(vkPlatform, m_usedApiVersion, m_instanceExtensions, cmdLine))
731 #endif // CTS_USES_VULKANSC
732 
733 #ifndef CTS_USES_VULKANSC
734     , m_instanceInterface(vkPlatform, *m_instance)
735 
736     , m_debugReportCallback(cmdLine.isValidationEnabled() ?
737                                 m_debugReportRecorder->createCallback(m_instanceInterface, m_instance.get()) :
738                                 DebugReportCallbackPtr())
739 #else
740     , m_instanceInterface(vkPlatform, *m_instance, cmdLine, resourceInterface)
741 #endif // CTS_USES_VULKANSC
742     , m_physicalDevice(chooseDevice(m_instanceInterface, *m_instance, cmdLine))
743     , m_deviceVersion(getPhysicalDeviceProperties(m_instanceInterface, m_physicalDevice).apiVersion)
744 
745     , m_deviceExtensions(addCoreDeviceExtensions(
746           filterExtensions(enumerateDeviceExtensionProperties(m_instanceInterface, m_physicalDevice, nullptr)),
747           m_usedApiVersion))
748     , m_deviceFeatures(m_instanceInterface, m_usedApiVersion, m_physicalDevice, m_instanceExtensions,
749                        m_deviceExtensions)
750     , m_universalQueueFamilyIndex(findQueueFamilyIndexWithCaps(
751           m_instanceInterface, m_physicalDevice,
752           cmdLine.isComputeOnly() ? VK_QUEUE_COMPUTE_BIT : VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT))
753 #ifndef CTS_USES_VULKANSC
754     , m_sparseQueueFamilyIndex(
755           m_deviceFeatures.getCoreFeatures2().features.sparseBinding ?
756               findQueueFamilyIndexWithCaps(m_instanceInterface, m_physicalDevice, VK_QUEUE_SPARSE_BINDING_BIT) :
757               0)
758 #else
759     , m_sparseQueueFamilyIndex(0)
760 #endif // CTS_USES_VULKANSC
761     , m_computeQueueFamilyIndex(findQueueFamilyIndexWithCapsNoThrow(m_instanceInterface, m_physicalDevice,
762                                                                     VK_QUEUE_COMPUTE_BIT, VK_QUEUE_GRAPHICS_BIT))
763     , m_transferQueueFamilyIndex(findQueueFamilyIndexWithCapsNoThrow(
764           m_instanceInterface, m_physicalDevice, VK_QUEUE_TRANSFER_BIT, VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT))
765     , m_deviceProperties(m_instanceInterface, m_usedApiVersion, m_physicalDevice, m_instanceExtensions,
766                          m_deviceExtensions)
767     // When the default device is created, we remove the core extensions from the extension list, but those core extensions are
768     // still reported as part of Context::getDeviceExtensions(). If we need the list of extensions actually used when creating the
769     // default device, we can use Context::getDeviceCreationExtensions().
770     , m_creationExtensions(removeCoreExtensions(m_usedApiVersion, m_deviceExtensions))
771     , m_device(createDefaultDevice(vkPlatform, *m_instance, m_instanceInterface, m_physicalDevice,
772                                    m_universalQueueFamilyIndex, m_sparseQueueFamilyIndex, m_computeQueueFamilyIndex,
773                                    m_transferQueueFamilyIndex, m_deviceFeatures.getCoreFeatures2(),
774                                    m_creationExtensions, cmdLine, resourceInterface))
775 #ifndef CTS_USES_VULKANSC
776     , m_deviceInterface(
777           de::MovePtr<DeviceDriver>(new DeviceDriver(vkPlatform, *m_instance, *m_device, m_usedApiVersion, cmdLine)))
778 #else
779     , m_deviceInterface(de::MovePtr<DeviceDriverSC>(
780           new DeviceDriverSC(vkPlatform, *m_instance, *m_device, cmdLine, resourceInterface,
781                              getDeviceVulkanSC10Properties(), getDeviceProperties(), m_usedApiVersion)))
782 #endif // CTS_USES_VULKANSC
783 {
784 #ifndef CTS_USES_VULKANSC
785     DE_UNREF(resourceInterface);
786 #endif
787     DE_ASSERT(m_deviceVersions.first == m_deviceVersion);
788 }
789 
~DefaultDevice(void)790 DefaultDevice::~DefaultDevice(void)
791 {
792 }
793 
getUniversalQueue(void) const794 VkQueue DefaultDevice::getUniversalQueue(void) const
795 {
796     return getDeviceQueue(*m_deviceInterface, *m_device, m_universalQueueFamilyIndex, 0);
797 }
798 
getSparseQueue(void) const799 VkQueue DefaultDevice::getSparseQueue(void) const
800 {
801     if (!m_deviceFeatures.getCoreFeatures2().features.sparseBinding)
802         TCU_THROW(NotSupportedError, "Sparse binding not supported.");
803 
804     return getDeviceQueue(*m_deviceInterface, *m_device, m_sparseQueueFamilyIndex, 0);
805 }
806 
getComputeQueue(void) const807 VkQueue DefaultDevice::getComputeQueue(void) const
808 {
809     if (m_computeQueueFamilyIndex == -1)
810         TCU_THROW(NotSupportedError, "Exclusive compute queue not supported.");
811 
812     return getDeviceQueue(*m_deviceInterface, *m_device, m_computeQueueFamilyIndex, 0);
813 }
814 
getTransferQueue(void) const815 VkQueue DefaultDevice::getTransferQueue(void) const
816 {
817     if (m_transferQueueFamilyIndex == -1)
818         TCU_THROW(NotSupportedError, "Exclusive transfer queue not supported.");
819 
820     return getDeviceQueue(*m_deviceInterface, *m_device, m_transferQueueFamilyIndex, 0);
821 }
822 
823 namespace
824 {
825 // Allocator utilities
826 
createAllocator(DefaultDevice * device)827 vk::Allocator *createAllocator(DefaultDevice *device)
828 {
829     const auto &vki             = device->getInstanceInterface();
830     const auto physicalDevice   = device->getPhysicalDevice();
831     const auto memoryProperties = vk::getPhysicalDeviceMemoryProperties(vki, physicalDevice);
832 
833     // \todo [2015-07-24 jarkko] support allocator selection/configuration from command line (or compile time)
834     return new SimpleAllocator(device->getDeviceInterface(), device->getDevice(), memoryProperties);
835 }
836 
837 } // namespace
838 
839 // Context
840 
Context(tcu::TestContext & testCtx,const vk::PlatformInterface & platformInterface,vk::BinaryCollection & progCollection,de::SharedPtr<vk::ResourceInterface> resourceInterface)841 Context::Context(tcu::TestContext &testCtx, const vk::PlatformInterface &platformInterface,
842                  vk::BinaryCollection &progCollection, de::SharedPtr<vk::ResourceInterface> resourceInterface)
843     : m_testCtx(testCtx)
844     , m_platformInterface(platformInterface)
845     , m_progCollection(progCollection)
846     , m_resourceInterface(resourceInterface)
847     , m_device(new DefaultDevice(m_platformInterface, testCtx.getCommandLine(), resourceInterface))
848     , m_allocator(createAllocator(m_device.get()))
849     , m_resultSetOnValidation(false)
850 {
851 }
852 
~Context(void)853 Context::~Context(void)
854 {
855 }
856 
getMaximumFrameworkVulkanVersion(void) const857 uint32_t Context::getMaximumFrameworkVulkanVersion(void) const
858 {
859     return m_device->getMaximumFrameworkVulkanVersion();
860 }
getAvailableInstanceVersion(void) const861 uint32_t Context::getAvailableInstanceVersion(void) const
862 {
863     return m_device->getAvailableInstanceVersion();
864 }
getInstanceExtensions(void) const865 const vector<string> &Context::getInstanceExtensions(void) const
866 {
867     return m_device->getInstanceExtensions();
868 }
getInstance(void) const869 vk::VkInstance Context::getInstance(void) const
870 {
871     return m_device->getInstance();
872 }
getInstanceInterface(void) const873 const vk::InstanceInterface &Context::getInstanceInterface(void) const
874 {
875     return m_device->getInstanceInterface();
876 }
getPhysicalDevice(void) const877 vk::VkPhysicalDevice Context::getPhysicalDevice(void) const
878 {
879     return m_device->getPhysicalDevice();
880 }
getDeviceVersion(void) const881 uint32_t Context::getDeviceVersion(void) const
882 {
883     return m_device->getDeviceVersion();
884 }
getDeviceFeatures(void) const885 const vk::VkPhysicalDeviceFeatures &Context::getDeviceFeatures(void) const
886 {
887     return m_device->getDeviceFeatures();
888 }
getDeviceFeatures2(void) const889 const vk::VkPhysicalDeviceFeatures2 &Context::getDeviceFeatures2(void) const
890 {
891     return m_device->getDeviceFeatures2();
892 }
getDeviceVulkan11Features(void) const893 const vk::VkPhysicalDeviceVulkan11Features &Context::getDeviceVulkan11Features(void) const
894 {
895     return m_device->getVulkan11Features();
896 }
getDeviceVulkan12Features(void) const897 const vk::VkPhysicalDeviceVulkan12Features &Context::getDeviceVulkan12Features(void) const
898 {
899     return m_device->getVulkan12Features();
900 }
901 #ifndef CTS_USES_VULKANSC
getDeviceVulkan13Features(void) const902 const vk::VkPhysicalDeviceVulkan13Features &Context::getDeviceVulkan13Features(void) const
903 {
904     return m_device->getVulkan13Features();
905 }
getDeviceVulkan14Features(void) const906 const vk::VkPhysicalDeviceVulkan14Features &Context::getDeviceVulkan14Features(void) const
907 {
908     return m_device->getVulkan14Features();
909 }
910 #endif // CTS_USES_VULKANSC
911 #ifdef CTS_USES_VULKANSC
getDeviceVulkanSC10Features(void) const912 const vk::VkPhysicalDeviceVulkanSC10Features &Context::getDeviceVulkanSC10Features(void) const
913 {
914     return m_device->getVulkanSC10Features();
915 }
916 #endif // CTS_USES_VULKANSC
917 
isDeviceFunctionalitySupported(const std::string & extension) const918 bool Context::isDeviceFunctionalitySupported(const std::string &extension) const
919 {
920     // If extension was promoted to core then check using the core mechanism. This is required so that
921     // all core implementations have the functionality tested, even if they don't support the extension.
922     // (It also means that core-optional extensions will not be reported as supported unless the
923     // features are really supported if the CTS code adds all core extensions to the extension list).
924     uint32_t apiVersion = getUsedApiVersion();
925     if (isCoreDeviceExtension(apiVersion, extension))
926     {
927         if (apiVersion < VK_MAKE_API_VERSION(0, 1, 2, 0))
928         {
929             // Check feature bits in extension-specific structures.
930             if (extension == "VK_KHR_multiview")
931                 return !!m_device->getMultiviewFeatures().multiview;
932             if (extension == "VK_KHR_variable_pointers")
933                 return !!m_device->getVariablePointersFeatures().variablePointersStorageBuffer;
934             if (extension == "VK_KHR_sampler_ycbcr_conversion")
935                 return !!m_device->getSamplerYcbcrConversionFeatures().samplerYcbcrConversion;
936             if (extension == "VK_KHR_shader_draw_parameters")
937                 return !!m_device->getShaderDrawParametersFeatures().shaderDrawParameters;
938         }
939         else
940         {
941             // Check feature bits using the new Vulkan 1.2 structures.
942             const auto &vk11Features = m_device->getVulkan11Features();
943             if (extension == "VK_KHR_multiview")
944                 return !!vk11Features.multiview;
945             if (extension == "VK_KHR_variable_pointers")
946                 return !!vk11Features.variablePointersStorageBuffer;
947             if (extension == "VK_KHR_sampler_ycbcr_conversion")
948                 return !!vk11Features.samplerYcbcrConversion;
949             if (extension == "VK_KHR_shader_draw_parameters")
950                 return !!vk11Features.shaderDrawParameters;
951 
952             const auto &vk12Features = m_device->getVulkan12Features();
953             if (extension == "VK_KHR_timeline_semaphore")
954                 return !!vk12Features.timelineSemaphore;
955             if (extension == "VK_KHR_buffer_device_address")
956                 return !!vk12Features.bufferDeviceAddress;
957             if (extension == "VK_EXT_descriptor_indexing")
958                 return !!vk12Features.descriptorIndexing;
959             if (extension == "VK_KHR_draw_indirect_count")
960                 return !!vk12Features.drawIndirectCount;
961             if (extension == "VK_KHR_sampler_mirror_clamp_to_edge")
962                 return !!vk12Features.samplerMirrorClampToEdge;
963             if (extension == "VK_EXT_sampler_filter_minmax")
964                 return !!vk12Features.samplerFilterMinmax;
965             if (extension == "VK_EXT_shader_viewport_index_layer")
966                 return !!vk12Features.shaderOutputViewportIndex && !!vk12Features.shaderOutputLayer;
967 
968 #ifndef CTS_USES_VULKANSC
969             const auto &vk13Features = m_device->getVulkan13Features();
970             if (extension == "VK_EXT_inline_uniform_block")
971                 return !!vk13Features.inlineUniformBlock;
972             if (extension == "VK_EXT_pipeline_creation_cache_control")
973                 return !!vk13Features.pipelineCreationCacheControl;
974             if (extension == "VK_EXT_private_data")
975                 return !!vk13Features.privateData;
976             if (extension == "VK_EXT_shader_demote_to_helper_invocation")
977                 return !!vk13Features.shaderDemoteToHelperInvocation;
978             if (extension == "VK_KHR_shader_terminate_invocation")
979                 return !!vk13Features.shaderTerminateInvocation;
980             if (extension == "VK_EXT_subgroup_size_control")
981                 return !!vk13Features.subgroupSizeControl;
982             if (extension == "VK_KHR_synchronization2")
983                 return !!vk13Features.synchronization2;
984             if (extension == "VK_EXT_texture_compression_astc_hdr")
985                 return !!vk13Features.textureCompressionASTC_HDR;
986             if (extension == "VK_KHR_zero_initialize_workgroup_memory")
987                 return !!vk13Features.shaderZeroInitializeWorkgroupMemory;
988             if (extension == "VK_KHR_dynamic_rendering")
989                 return !!vk13Features.dynamicRendering;
990             if (extension == "VK_KHR_shader_integer_dot_product")
991                 return !!vk13Features.shaderIntegerDotProduct;
992             if (extension == "VK_KHR_maintenance4")
993                 return !!vk13Features.maintenance4;
994 
995             const auto &vk14Features = m_device->getVulkan14Features();
996             if (extension == "VK_KHR_dynamic_rendering_local_read")
997                 return !!vk14Features.dynamicRenderingLocalRead;
998             if (extension == "VK_KHR_global_priority")
999                 return !!vk14Features.globalPriorityQuery;
1000             if (extension == "VK_KHR_index_type_uint8")
1001                 return !!vk14Features.indexTypeUint8;
1002             if (extension == "VK_KHR_maintenance5")
1003                 return !!vk14Features.maintenance5;
1004             if (extension == "VK_KHR_maintenance6")
1005                 return !!vk14Features.maintenance6;
1006             if (extension == "VK_KHR_shader_expect_assume")
1007                 return !!vk14Features.shaderExpectAssume;
1008             if (extension == "VK_KHR_shader_float_controls2")
1009                 return !!vk14Features.shaderFloatControls2;
1010             if (extension == "VK_EXT_host_image_copy")
1011                 return !!vk14Features.hostImageCopy;
1012             if (extension == "VK_EXT_pipeline_protected_access")
1013                 return !!vk14Features.pipelineProtectedAccess;
1014             if (extension == "VK_EXT_pipeline_robustness")
1015                 return !!vk14Features.pipelineRobustness;
1016             if (extension == "VK_KHR_push_descriptor")
1017                 return !!vk14Features.pushDescriptor;
1018 #endif // CTS_USES_VULKANSC
1019 
1020 #ifdef CTS_USES_VULKANSC
1021             const auto &vk12Properties = m_device->getDeviceVulkan12Properties();
1022             if (extension == "VK_KHR_depth_stencil_resolve")
1023                 return (vk12Properties.supportedDepthResolveModes != VK_RESOLVE_MODE_NONE) &&
1024                        (vk12Properties.supportedStencilResolveModes != VK_RESOLVE_MODE_NONE);
1025 #endif // CTS_USES_VULKANSC
1026         }
1027 
1028         // No feature flags to check.
1029         return true;
1030     }
1031 
1032     // If this is not a core extension then just return whether the implementation says it's supported.
1033     const auto &extensions = getDeviceExtensions();
1034     return de::contains(extensions.begin(), extensions.end(), extension);
1035 }
1036 
isInstanceFunctionalitySupported(const std::string & extension) const1037 bool Context::isInstanceFunctionalitySupported(const std::string &extension) const
1038 {
1039     // NOTE: current implementation uses isInstanceExtensionSupported but
1040     // this will change when some instance extensions will be promoted to the
1041     // core; don't use isInstanceExtensionSupported directly, use this method instead
1042     return isInstanceExtensionSupported(getUsedApiVersion(), getInstanceExtensions(), extension);
1043 }
1044 
1045 #include "vkDeviceFeaturesForContextDefs.inl"
1046 
getDeviceProperties(void) const1047 const vk::VkPhysicalDeviceProperties &Context::getDeviceProperties(void) const
1048 {
1049     return m_device->getDeviceProperties();
1050 }
getDeviceProperties2(void) const1051 const vk::VkPhysicalDeviceProperties2 &Context::getDeviceProperties2(void) const
1052 {
1053     return m_device->getDeviceProperties2();
1054 }
getDeviceVulkan11Properties(void) const1055 const vk::VkPhysicalDeviceVulkan11Properties &Context::getDeviceVulkan11Properties(void) const
1056 {
1057     return m_device->getDeviceVulkan11Properties();
1058 }
getDeviceVulkan12Properties(void) const1059 const vk::VkPhysicalDeviceVulkan12Properties &Context::getDeviceVulkan12Properties(void) const
1060 {
1061     return m_device->getDeviceVulkan12Properties();
1062 }
1063 #ifndef CTS_USES_VULKANSC
getDeviceVulkan13Properties(void) const1064 const vk::VkPhysicalDeviceVulkan13Properties &Context::getDeviceVulkan13Properties(void) const
1065 {
1066     return m_device->getDeviceVulkan13Properties();
1067 }
getDeviceVulkan14Properties(void) const1068 const vk::VkPhysicalDeviceVulkan14Properties &Context::getDeviceVulkan14Properties(void) const
1069 {
1070     return m_device->getDeviceVulkan14Properties();
1071 }
1072 #endif // CTS_USES_VULKANSC
1073 #ifdef CTS_USES_VULKANSC
getDeviceVulkanSC10Properties(void) const1074 const vk::VkPhysicalDeviceVulkanSC10Properties &Context::getDeviceVulkanSC10Properties(void) const
1075 {
1076     return m_device->getDeviceVulkanSC10Properties();
1077 }
1078 #endif // CTS_USES_VULKANSC
1079 
1080 #include "vkDevicePropertiesForContextDefs.inl"
1081 
getDeviceExtensions(void) const1082 const vector<string> &Context::getDeviceExtensions(void) const
1083 {
1084     return m_device->getDeviceExtensions();
1085 }
getDeviceCreationExtensions(void) const1086 const vector<const char *> &Context::getDeviceCreationExtensions(void) const
1087 {
1088     return m_device->getDeviceCreationExtensions();
1089 }
getDevice(void) const1090 vk::VkDevice Context::getDevice(void) const
1091 {
1092     return m_device->getDevice();
1093 }
getDeviceInterface(void) const1094 const vk::DeviceInterface &Context::getDeviceInterface(void) const
1095 {
1096     return m_device->getDeviceInterface();
1097 }
getUniversalQueueFamilyIndex(void) const1098 uint32_t Context::getUniversalQueueFamilyIndex(void) const
1099 {
1100     return m_device->getUniversalQueueFamilyIndex();
1101 }
getUniversalQueue(void) const1102 vk::VkQueue Context::getUniversalQueue(void) const
1103 {
1104     return m_device->getUniversalQueue();
1105 }
getComputeQueueFamilyIndex(void) const1106 int Context::getComputeQueueFamilyIndex(void) const
1107 {
1108     return m_device->getComputeQueueFamilyIndex();
1109 }
getComputeQueue(void) const1110 vk::VkQueue Context::getComputeQueue(void) const
1111 {
1112     return m_device->getComputeQueue();
1113 }
getTransferQueueFamilyIndex(void) const1114 int Context::getTransferQueueFamilyIndex(void) const
1115 {
1116     return m_device->getTransferQueueFamilyIndex();
1117 }
getTransferQueue(void) const1118 vk::VkQueue Context::getTransferQueue(void) const
1119 {
1120     return m_device->getTransferQueue();
1121 }
getSparseQueueFamilyIndex(void) const1122 uint32_t Context::getSparseQueueFamilyIndex(void) const
1123 {
1124     return m_device->getSparseQueueFamilyIndex();
1125 }
getSparseQueue(void) const1126 vk::VkQueue Context::getSparseQueue(void) const
1127 {
1128     return m_device->getSparseQueue();
1129 }
getResourceInterface(void) const1130 de::SharedPtr<vk::ResourceInterface> Context::getResourceInterface(void) const
1131 {
1132     return m_resourceInterface;
1133 }
getDefaultAllocator(void) const1134 vk::Allocator &Context::getDefaultAllocator(void) const
1135 {
1136     return *m_allocator;
1137 }
getUsedApiVersion(void) const1138 uint32_t Context::getUsedApiVersion(void) const
1139 {
1140     return m_device->getUsedApiVersion();
1141 }
contextSupports(const uint32_t variantNum,const uint32_t majorNum,const uint32_t minorNum,const uint32_t patchNum) const1142 bool Context::contextSupports(const uint32_t variantNum, const uint32_t majorNum, const uint32_t minorNum,
1143                               const uint32_t patchNum) const
1144 {
1145     return isApiVersionSupported(m_device->getUsedApiVersion(),
1146                                  VK_MAKE_API_VERSION(variantNum, majorNum, minorNum, patchNum));
1147 }
contextSupports(const ApiVersion version) const1148 bool Context::contextSupports(const ApiVersion version) const
1149 {
1150     return isApiVersionSupported(m_device->getUsedApiVersion(), pack(version));
1151 }
contextSupports(const uint32_t requiredApiVersionBits) const1152 bool Context::contextSupports(const uint32_t requiredApiVersionBits) const
1153 {
1154     return isApiVersionSupported(m_device->getUsedApiVersion(), requiredApiVersionBits);
1155 }
isDeviceFeatureInitialized(vk::VkStructureType sType) const1156 bool Context::isDeviceFeatureInitialized(vk::VkStructureType sType) const
1157 {
1158     return m_device->isDeviceFeatureInitialized(sType);
1159 }
isDevicePropertyInitialized(vk::VkStructureType sType) const1160 bool Context::isDevicePropertyInitialized(vk::VkStructureType sType) const
1161 {
1162     return m_device->isDevicePropertyInitialized(sType);
1163 }
1164 
requireDeviceFunctionality(const std::string & required) const1165 bool Context::requireDeviceFunctionality(const std::string &required) const
1166 {
1167     if (!isDeviceFunctionalitySupported(required))
1168         TCU_THROW(NotSupportedError, required + " is not supported");
1169 
1170     return true;
1171 }
1172 
requireInstanceFunctionality(const std::string & required) const1173 bool Context::requireInstanceFunctionality(const std::string &required) const
1174 {
1175     if (!isInstanceFunctionalitySupported(required))
1176         TCU_THROW(NotSupportedError, required + " is not supported");
1177 
1178     return true;
1179 }
1180 
1181 struct DeviceCoreFeaturesTable
1182 {
1183     const char *featureName;
1184     const uint32_t featureArrayIndex;
1185     const uint32_t featureArrayOffset;
1186 };
1187 
1188 #define DEVICE_CORE_FEATURE_OFFSET(FEATURE_FIELD_NAME) offsetof(VkPhysicalDeviceFeatures, FEATURE_FIELD_NAME)
1189 #define DEVICE_CORE_FEATURE_ENTRY(BITNAME, FIELDNAME)              \
1190     {                                                              \
1191         #FIELDNAME, BITNAME, DEVICE_CORE_FEATURE_OFFSET(FIELDNAME) \
1192     }
1193 
1194 const DeviceCoreFeaturesTable deviceCoreFeaturesTable[] = {
1195     DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_ROBUST_BUFFER_ACCESS, robustBufferAccess),
1196     DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_FULL_DRAW_INDEX_UINT32, fullDrawIndexUint32),
1197     DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_IMAGE_CUBE_ARRAY, imageCubeArray),
1198     DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_INDEPENDENT_BLEND, independentBlend),
1199     DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_GEOMETRY_SHADER, geometryShader),
1200     DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_TESSELLATION_SHADER, tessellationShader),
1201     DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SAMPLE_RATE_SHADING, sampleRateShading),
1202     DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_DUAL_SRC_BLEND, dualSrcBlend),
1203     DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_LOGIC_OP, logicOp),
1204     DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_MULTI_DRAW_INDIRECT, multiDrawIndirect),
1205     DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_DRAW_INDIRECT_FIRST_INSTANCE, drawIndirectFirstInstance),
1206     DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_DEPTH_CLAMP, depthClamp),
1207     DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_DEPTH_BIAS_CLAMP, depthBiasClamp),
1208     DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_FILL_MODE_NON_SOLID, fillModeNonSolid),
1209     DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_DEPTH_BOUNDS, depthBounds),
1210     DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_WIDE_LINES, wideLines),
1211     DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_LARGE_POINTS, largePoints),
1212     DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_ALPHA_TO_ONE, alphaToOne),
1213     DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_MULTI_VIEWPORT, multiViewport),
1214     DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SAMPLER_ANISOTROPY, samplerAnisotropy),
1215     DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_TEXTURE_COMPRESSION_ETC2, textureCompressionETC2),
1216     DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_TEXTURE_COMPRESSION_ASTC_LDR, textureCompressionASTC_LDR),
1217     DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_TEXTURE_COMPRESSION_BC, textureCompressionBC),
1218     DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_OCCLUSION_QUERY_PRECISE, occlusionQueryPrecise),
1219     DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_PIPELINE_STATISTICS_QUERY, pipelineStatisticsQuery),
1220     DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_VERTEX_PIPELINE_STORES_AND_ATOMICS, vertexPipelineStoresAndAtomics),
1221     DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_FRAGMENT_STORES_AND_ATOMICS, fragmentStoresAndAtomics),
1222     DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_TESSELLATION_AND_GEOMETRY_POINT_SIZE,
1223                               shaderTessellationAndGeometryPointSize),
1224     DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_IMAGE_GATHER_EXTENDED, shaderImageGatherExtended),
1225     DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_STORAGE_IMAGE_EXTENDED_FORMATS,
1226                               shaderStorageImageExtendedFormats),
1227     DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_STORAGE_IMAGE_MULTISAMPLE, shaderStorageImageMultisample),
1228     DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_STORAGE_IMAGE_READ_WITHOUT_FORMAT,
1229                               shaderStorageImageReadWithoutFormat),
1230     DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_STORAGE_IMAGE_WRITE_WITHOUT_FORMAT,
1231                               shaderStorageImageWriteWithoutFormat),
1232     DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_UNIFORM_BUFFER_ARRAY_DYNAMIC_INDEXING,
1233                               shaderUniformBufferArrayDynamicIndexing),
1234     DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_SAMPLED_IMAGE_ARRAY_DYNAMIC_INDEXING,
1235                               shaderSampledImageArrayDynamicIndexing),
1236     DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_STORAGE_BUFFER_ARRAY_DYNAMIC_INDEXING,
1237                               shaderStorageBufferArrayDynamicIndexing),
1238     DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_STORAGE_IMAGE_ARRAY_DYNAMIC_INDEXING,
1239                               shaderStorageImageArrayDynamicIndexing),
1240     DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_CLIP_DISTANCE, shaderClipDistance),
1241     DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_CULL_DISTANCE, shaderCullDistance),
1242     DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_FLOAT64, shaderFloat64),
1243     DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_INT64, shaderInt64),
1244     DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_INT16, shaderInt16),
1245     DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_RESOURCE_RESIDENCY, shaderResourceResidency),
1246     DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_RESOURCE_MIN_LOD, shaderResourceMinLod),
1247     DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SPARSE_BINDING, sparseBinding),
1248     DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SPARSE_RESIDENCY_BUFFER, sparseResidencyBuffer),
1249     DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SPARSE_RESIDENCY_IMAGE2D, sparseResidencyImage2D),
1250     DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SPARSE_RESIDENCY_IMAGE3D, sparseResidencyImage3D),
1251     DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SPARSE_RESIDENCY2_SAMPLES, sparseResidency2Samples),
1252     DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SPARSE_RESIDENCY4_SAMPLES, sparseResidency4Samples),
1253     DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SPARSE_RESIDENCY8_SAMPLES, sparseResidency8Samples),
1254     DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SPARSE_RESIDENCY16_SAMPLES, sparseResidency16Samples),
1255     DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SPARSE_RESIDENCY_ALIASED, sparseResidencyAliased),
1256     DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_VARIABLE_MULTISAMPLE_RATE, variableMultisampleRate),
1257     DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_INHERITED_QUERIES, inheritedQueries),
1258 };
1259 
requireDeviceCoreFeature(const DeviceCoreFeature requiredFeature)1260 bool Context::requireDeviceCoreFeature(const DeviceCoreFeature requiredFeature)
1261 {
1262     const vk::VkPhysicalDeviceFeatures &featuresAvailable = getDeviceFeatures();
1263     const vk::VkBool32 *featuresAvailableArray            = (vk::VkBool32 *)(&featuresAvailable);
1264     const uint32_t requiredFeatureIndex                   = static_cast<uint32_t>(requiredFeature);
1265 
1266     DE_ASSERT(requiredFeatureIndex * sizeof(vk::VkBool32) < sizeof(featuresAvailable));
1267     DE_ASSERT(deviceCoreFeaturesTable[requiredFeatureIndex].featureArrayIndex * sizeof(vk::VkBool32) ==
1268               deviceCoreFeaturesTable[requiredFeatureIndex].featureArrayOffset);
1269 
1270     if (featuresAvailableArray[requiredFeatureIndex] == false)
1271         TCU_THROW(NotSupportedError, "Requested core feature is not supported: " +
1272                                          std::string(deviceCoreFeaturesTable[requiredFeatureIndex].featureName));
1273 
1274     return true;
1275 }
1276 
1277 #ifndef CTS_USES_VULKANSC
1278 
isSpirvCompatibleFormat(VkFormat format)1279 static bool isSpirvCompatibleFormat(VkFormat format)
1280 {
1281     switch (format)
1282     {
1283     case VK_FORMAT_R32G32B32A32_SFLOAT:
1284     case VK_FORMAT_R32G32_SFLOAT:
1285     case VK_FORMAT_R32_SFLOAT:
1286     case VK_FORMAT_R16G16B16A16_SFLOAT:
1287     case VK_FORMAT_R16G16_SFLOAT:
1288     case VK_FORMAT_R16_SFLOAT:
1289     case VK_FORMAT_R16G16B16A16_UNORM:
1290     case VK_FORMAT_R16G16_UNORM:
1291     case VK_FORMAT_R16_UNORM:
1292     case VK_FORMAT_R16G16B16A16_SNORM:
1293     case VK_FORMAT_R16G16_SNORM:
1294     case VK_FORMAT_R16_SNORM:
1295     case VK_FORMAT_A2B10G10R10_UNORM_PACK32:
1296     case VK_FORMAT_B10G11R11_UFLOAT_PACK32:
1297     case VK_FORMAT_R8G8B8A8_UNORM:
1298     case VK_FORMAT_R8G8_UNORM:
1299     case VK_FORMAT_R8_UNORM:
1300     case VK_FORMAT_R8G8B8A8_SNORM:
1301     case VK_FORMAT_R8G8_SNORM:
1302     case VK_FORMAT_R8_SNORM:
1303     case VK_FORMAT_R32G32B32A32_SINT:
1304     case VK_FORMAT_R32G32_SINT:
1305     case VK_FORMAT_R32_SINT:
1306     case VK_FORMAT_R16G16B16A16_SINT:
1307     case VK_FORMAT_R16G16_SINT:
1308     case VK_FORMAT_R16_SINT:
1309     case VK_FORMAT_R8G8B8A8_SINT:
1310     case VK_FORMAT_R8G8_SINT:
1311     case VK_FORMAT_R8_SINT:
1312     case VK_FORMAT_R32G32B32A32_UINT:
1313     case VK_FORMAT_R32G32_UINT:
1314     case VK_FORMAT_R32_UINT:
1315     case VK_FORMAT_R16G16B16A16_UINT:
1316     case VK_FORMAT_R16G16_UINT:
1317     case VK_FORMAT_R16_UINT:
1318     case VK_FORMAT_A2B10G10R10_UINT_PACK32:
1319     case VK_FORMAT_R8G8B8A8_UINT:
1320     case VK_FORMAT_R8G8_UINT:
1321     case VK_FORMAT_R8_UINT:
1322     case VK_FORMAT_R64_SINT:
1323     case VK_FORMAT_R64_UINT:
1324         // These formats can be explicitly expressed in SPIR-V.
1325         return true;
1326     default:
1327         return false;
1328     }
1329 }
1330 
isExtendedStorageFormat(VkFormat format)1331 static bool isExtendedStorageFormat(VkFormat format)
1332 {
1333     switch (format)
1334     {
1335     case VK_FORMAT_R8G8B8A8_UNORM:
1336     case VK_FORMAT_R8G8B8A8_SNORM:
1337     case VK_FORMAT_R8G8B8A8_UINT:
1338     case VK_FORMAT_R8G8B8A8_SINT:
1339     case VK_FORMAT_R32_UINT:
1340     case VK_FORMAT_R32_SINT:
1341     case VK_FORMAT_R32_SFLOAT:
1342     case VK_FORMAT_R32G32_UINT:
1343     case VK_FORMAT_R32G32_SINT:
1344     case VK_FORMAT_R32G32_SFLOAT:
1345     case VK_FORMAT_R32G32B32A32_UINT:
1346     case VK_FORMAT_R32G32B32A32_SINT:
1347     case VK_FORMAT_R32G32B32A32_SFLOAT:
1348     case VK_FORMAT_R16G16B16A16_UINT:
1349     case VK_FORMAT_R16G16B16A16_SINT:
1350     case VK_FORMAT_R16G16B16A16_SFLOAT:
1351     case VK_FORMAT_R16G16_SFLOAT:
1352     case VK_FORMAT_B10G11R11_UFLOAT_PACK32:
1353     case VK_FORMAT_R16_SFLOAT:
1354     case VK_FORMAT_R16G16B16A16_UNORM:
1355     case VK_FORMAT_A2B10G10R10_UNORM_PACK32:
1356     case VK_FORMAT_R16G16_UNORM:
1357     case VK_FORMAT_R8G8_UNORM:
1358     case VK_FORMAT_R16_UNORM:
1359     case VK_FORMAT_R8_UNORM:
1360     case VK_FORMAT_R16G16B16A16_SNORM:
1361     case VK_FORMAT_R16G16_SNORM:
1362     case VK_FORMAT_R8G8_SNORM:
1363     case VK_FORMAT_R16_SNORM:
1364     case VK_FORMAT_R8_SNORM:
1365     case VK_FORMAT_R16G16_SINT:
1366     case VK_FORMAT_R8G8_SINT:
1367     case VK_FORMAT_R16_SINT:
1368     case VK_FORMAT_R8_SINT:
1369     case VK_FORMAT_A2B10G10R10_UINT_PACK32:
1370     case VK_FORMAT_R16G16_UINT:
1371     case VK_FORMAT_R8G8_UINT:
1372     case VK_FORMAT_R16_UINT:
1373     case VK_FORMAT_R8_UINT:
1374         return true;
1375     default:
1376         return false;
1377     }
1378 }
1379 
isDepthFormat(VkFormat format)1380 static bool isDepthFormat(VkFormat format)
1381 {
1382     switch (format)
1383     {
1384     case VK_FORMAT_D16_UNORM:
1385     case VK_FORMAT_X8_D24_UNORM_PACK32:
1386     case VK_FORMAT_D32_SFLOAT:
1387     case VK_FORMAT_D16_UNORM_S8_UINT:
1388     case VK_FORMAT_D24_UNORM_S8_UINT:
1389     case VK_FORMAT_D32_SFLOAT_S8_UINT:
1390         return true;
1391     default:
1392         return false;
1393     }
1394 }
1395 
getRequiredFormatProperties(const vk::VkFormat & format) const1396 vk::VkFormatProperties3 Context::getRequiredFormatProperties(const vk::VkFormat &format) const
1397 {
1398     vk::VkFormatProperties3 p;
1399     p.sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_3;
1400     p.pNext = nullptr;
1401 
1402     vk::VkFormatProperties properties;
1403     getInstanceInterface().getPhysicalDeviceFormatProperties(getPhysicalDevice(), format, &properties);
1404     p.linearTilingFeatures  = properties.linearTilingFeatures;
1405     p.optimalTilingFeatures = properties.optimalTilingFeatures;
1406     p.bufferFeatures        = properties.bufferFeatures;
1407 
1408     const vk::VkPhysicalDeviceFeatures &featuresAvailable = getDeviceFeatures();
1409     if (isExtendedStorageFormat(format) && featuresAvailable.shaderStorageImageReadWithoutFormat)
1410     {
1411         if (p.linearTilingFeatures & VK_FORMAT_FEATURE_2_STORAGE_IMAGE_BIT_KHR)
1412             p.linearTilingFeatures |= VK_FORMAT_FEATURE_2_STORAGE_READ_WITHOUT_FORMAT_BIT_KHR;
1413         if (p.optimalTilingFeatures & VK_FORMAT_FEATURE_2_STORAGE_IMAGE_BIT_KHR)
1414             p.optimalTilingFeatures |= VK_FORMAT_FEATURE_2_STORAGE_READ_WITHOUT_FORMAT_BIT_KHR;
1415     }
1416     if (isExtendedStorageFormat(format) && featuresAvailable.shaderStorageImageWriteWithoutFormat)
1417     {
1418         if (p.linearTilingFeatures & VK_FORMAT_FEATURE_2_STORAGE_IMAGE_BIT_KHR)
1419             p.linearTilingFeatures |= VK_FORMAT_FEATURE_2_STORAGE_WRITE_WITHOUT_FORMAT_BIT_KHR;
1420         if (p.optimalTilingFeatures & VK_FORMAT_FEATURE_2_STORAGE_IMAGE_BIT_KHR)
1421             p.optimalTilingFeatures |= VK_FORMAT_FEATURE_2_STORAGE_WRITE_WITHOUT_FORMAT_BIT_KHR;
1422     }
1423     // If an implementation exposes storage image/buffer feature on formats not in the SPIR-V compatibility table,
1424     // the implementation must at least expose one of the WITHOUT_FORMAT (either READ or WRITE) storage features.
1425     if (!isSpirvCompatibleFormat(format))
1426     {
1427         if ((p.linearTilingFeatures & VK_FORMAT_FEATURE_2_STORAGE_READ_WITHOUT_FORMAT_BIT_KHR) ||
1428             (p.linearTilingFeatures & VK_FORMAT_FEATURE_2_STORAGE_WRITE_WITHOUT_FORMAT_BIT_KHR))
1429         {
1430             p.linearTilingFeatures |= VK_FORMAT_FEATURE_2_STORAGE_IMAGE_BIT_KHR;
1431         }
1432         if ((p.optimalTilingFeatures & VK_FORMAT_FEATURE_2_STORAGE_READ_WITHOUT_FORMAT_BIT_KHR) ||
1433             (p.optimalTilingFeatures & VK_FORMAT_FEATURE_2_STORAGE_WRITE_WITHOUT_FORMAT_BIT_KHR))
1434         {
1435             p.optimalTilingFeatures |= VK_FORMAT_FEATURE_2_STORAGE_IMAGE_BIT_KHR;
1436         }
1437         if ((p.bufferFeatures & VK_FORMAT_FEATURE_2_STORAGE_READ_WITHOUT_FORMAT_BIT_KHR) ||
1438             (p.bufferFeatures & VK_FORMAT_FEATURE_2_STORAGE_WRITE_WITHOUT_FORMAT_BIT_KHR))
1439         {
1440             p.bufferFeatures |= VK_FORMAT_FEATURE_2_STORAGE_TEXEL_BUFFER_BIT_KHR;
1441         }
1442     }
1443     if (isDepthFormat(format) && (p.linearTilingFeatures & (VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_BIT_KHR)))
1444         p.linearTilingFeatures |= VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_DEPTH_COMPARISON_BIT_KHR;
1445     if (isDepthFormat(format) && (p.optimalTilingFeatures & (VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_BIT_KHR)))
1446         p.optimalTilingFeatures |= VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_DEPTH_COMPARISON_BIT_KHR;
1447 
1448     return p;
1449 }
1450 
getFormatProperties(const vk::VkFormat & format) const1451 vk::VkFormatProperties3 Context::getFormatProperties(const vk::VkFormat &format) const
1452 {
1453     if (isDeviceFunctionalitySupported("VK_KHR_format_feature_flags2"))
1454     {
1455         vk::VkFormatProperties3 p;
1456         p.sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_3;
1457         p.pNext = nullptr;
1458 
1459         vk::VkFormatProperties2 properties;
1460         properties.sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2;
1461         properties.pNext = &p;
1462 
1463         getInstanceInterface().getPhysicalDeviceFormatProperties2(getPhysicalDevice(), format, &properties);
1464         return p;
1465     }
1466     else
1467         return Context::getRequiredFormatProperties(format);
1468 }
1469 
1470 #endif // CTS_USES_VULKANSC
1471 
getInstanceProcAddr()1472 void *Context::getInstanceProcAddr()
1473 {
1474     return (void *)m_platformInterface.getGetInstanceProcAddr();
1475 }
1476 
isBufferDeviceAddressSupported(void) const1477 bool Context::isBufferDeviceAddressSupported(void) const
1478 {
1479     return isDeviceFunctionalitySupported("VK_KHR_buffer_device_address") ||
1480            isDeviceFunctionalitySupported("VK_EXT_buffer_device_address");
1481 }
1482 
1483 #ifndef CTS_USES_VULKANSC
1484 
hasDebugReportRecorder() const1485 bool Context::hasDebugReportRecorder() const
1486 {
1487     return m_device->hasDebugReportRecorder();
1488 }
1489 
getDebugReportRecorder() const1490 vk::DebugReportRecorder &Context::getDebugReportRecorder() const
1491 {
1492     return m_device->getDebugReportRecorder();
1493 }
1494 
1495 #endif // CTS_USES_VULKANSC
1496 
resetCommandPoolForVKSC(const VkDevice device,const VkCommandPool commandPool)1497 void Context::resetCommandPoolForVKSC(const VkDevice device, const VkCommandPool commandPool)
1498 {
1499 #ifdef CTS_USES_VULKANSC
1500     if (getDeviceVulkanSC10Properties().commandPoolResetCommandBuffer == VK_FALSE)
1501     {
1502         const DeviceInterface &vk = getDeviceInterface();
1503         VK_CHECK(vk.resetCommandPool(device, commandPool, 0u));
1504     }
1505 #else
1506     DE_UNREF(device);
1507     DE_UNREF(commandPool);
1508 #endif
1509 }
1510 
getContextCommonData() const1511 ContextCommonData Context::getContextCommonData() const
1512 {
1513     return ContextCommonData{
1514         getPlatformInterface(), getInstanceInterface(),
1515         getDeviceInterface(),   getInstance(),
1516         getPhysicalDevice(),    getDevice(),
1517         getDefaultAllocator(),  getUniversalQueueFamilyIndex(),
1518         getUniversalQueue(),
1519     };
1520 }
1521 
1522 #ifdef CTS_USES_VULKANSC
1523 std::vector<VkFaultData> Context::m_faultData;
1524 std::mutex Context::m_faultDataMutex;
1525 
faultCallbackFunction(VkBool32 unrecordedFaults,uint32_t faultCount,const VkFaultData * pFaults)1526 void Context::faultCallbackFunction(VkBool32 unrecordedFaults, uint32_t faultCount, const VkFaultData *pFaults)
1527 {
1528     DE_UNREF(unrecordedFaults);
1529     std::lock_guard<std::mutex> lock(m_faultDataMutex);
1530 
1531     // Append new faults to the vector
1532     for (uint32_t i = 0; i < faultCount; ++i)
1533     {
1534         VkFaultData faultData = pFaults[i];
1535         faultData.pNext       = nullptr;
1536 
1537         m_faultData.push_back(faultData);
1538     }
1539 }
1540 #endif // CTS_USES_VULKANSC
1541 
1542 // TestCase
1543 
initPrograms(SourceCollections &) const1544 void TestCase::initPrograms(SourceCollections &) const
1545 {
1546 }
1547 
checkSupport(Context &) const1548 void TestCase::checkSupport(Context &) const
1549 {
1550 }
1551 
delayedInit(void)1552 void TestCase::delayedInit(void)
1553 {
1554 }
1555 
1556 #ifndef CTS_USES_VULKANSC
1557 
collectAndReportDebugMessages(vk::DebugReportRecorder & debugReportRecorder,Context & context)1558 void collectAndReportDebugMessages(vk::DebugReportRecorder &debugReportRecorder, Context &context)
1559 {
1560     using DebugMessages = vk::DebugReportRecorder::MessageList;
1561 
1562     const DebugMessages &messages = debugReportRecorder.getMessages();
1563     tcu::TestLog &log             = context.getTestContext().getLog();
1564 
1565     if (messages.size() > 0)
1566     {
1567         const tcu::ScopedLogSection section(log, "DebugMessages", "Debug Messages");
1568         int numErrors = 0;
1569 
1570         for (const auto &msg : messages)
1571         {
1572             if (msg.shouldBeLogged())
1573                 log << tcu::TestLog::Message << msg << tcu::TestLog::EndMessage;
1574 
1575             if (msg.isError())
1576                 numErrors += 1;
1577         }
1578 
1579         debugReportRecorder.clearMessages();
1580 
1581         if (numErrors > 0)
1582         {
1583             string errorMsg = de::toString(numErrors) + " API usage errors found";
1584             context.resultSetOnValidation(true);
1585             context.getTestContext().setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, errorMsg.c_str());
1586         }
1587     }
1588 }
1589 
1590 #endif // CTS_USES_VULKANSC
1591 
1592 } // namespace vkt
1593