xref: /aosp_15_r20/external/deqp/external/vulkancts/modules/vulkan/vktTestCase.cpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
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_MVK_macos_surface",
104     };
105 
106     const char *exclusions[] = {"VK_EXT_device_address_binding_report", "VK_EXT_device_memory_report"};
107 
108     for (size_t extNdx = 0; extNdx < extensions.size(); extNdx++)
109     {
110         if (deStringEqual(extensions[extNdx].extensionName, "VK_KHR_buffer_device_address"))
111         {
112             khrBufferDeviceAddress = true;
113             break;
114         }
115     }
116 
117     for (size_t extNdx = 0; extNdx < extensions.size(); extNdx++)
118     {
119         const auto &extName = extensions[extNdx].extensionName;
120 
121         excludeExtension = false;
122 
123         // VK_EXT_buffer_device_address is deprecated and must not be enabled if VK_KHR_buffer_device_address is enabled
124         if (khrBufferDeviceAddress && deStringEqual(extName, "VK_EXT_buffer_device_address"))
125             continue;
126 
127         for (int exclusionsNdx = 0; exclusionsNdx < DE_LENGTH_OF_ARRAY(exclusions); exclusionsNdx++)
128         {
129             if (deStringEqual(extName, exclusions[exclusionsNdx]))
130             {
131                 excludeExtension = true;
132                 break;
133             }
134         }
135 
136         if (excludeExtension)
137             continue;
138 
139         for (int extGroupNdx = 0; extGroupNdx < DE_LENGTH_OF_ARRAY(extensionGroups); extGroupNdx++)
140         {
141             if (deStringBeginsWith(extName, extensionGroups[extGroupNdx]))
142                 enabledExtensions.push_back(extName);
143         }
144     }
145 
146     return enabledExtensions;
147 }
148 
addExtensions(const vector<string> & a,const vector<const char * > & b)149 vector<string> addExtensions(const vector<string> &a, const vector<const char *> &b)
150 {
151     vector<string> res(a);
152 
153     for (vector<const char *>::const_iterator bIter = b.begin(); bIter != b.end(); ++bIter)
154     {
155         if (!de::contains(res.begin(), res.end(), string(*bIter)))
156             res.push_back(string(*bIter));
157     }
158 
159     return res;
160 }
161 
addCoreInstanceExtensions(const vector<string> & extensions,uint32_t instanceVersion)162 vector<string> addCoreInstanceExtensions(const vector<string> &extensions, uint32_t instanceVersion)
163 {
164     vector<const char *> coreExtensions;
165     getCoreInstanceExtensions(instanceVersion, coreExtensions);
166     return addExtensions(extensions, coreExtensions);
167 }
168 
addCoreDeviceExtensions(const vector<string> & extensions,uint32_t instanceVersion)169 vector<string> addCoreDeviceExtensions(const vector<string> &extensions, uint32_t instanceVersion)
170 {
171     vector<const char *> coreExtensions;
172     getCoreDeviceExtensions(instanceVersion, coreExtensions);
173     return addExtensions(extensions, coreExtensions);
174 }
175 
getTargetInstanceVersion(const PlatformInterface & vkp)176 uint32_t getTargetInstanceVersion(const PlatformInterface &vkp)
177 {
178     uint32_t version = pack(ApiVersion(0, 1, 0, 0));
179 
180     if (vkp.enumerateInstanceVersion(&version) != VK_SUCCESS)
181         TCU_THROW(InternalError, "Enumerate instance version error");
182 #ifdef CTS_USES_VULKANSC
183     // Temporary workaround for Vulkan loader problem - currently Vulkan loader always returs API variant == 0
184     version = pack(ApiVersion(1, 1, 0, 0));
185 #endif
186     return version;
187 }
188 
determineDeviceVersions(const PlatformInterface & vkp,uint32_t apiVersion,const tcu::CommandLine & cmdLine)189 std::pair<uint32_t, uint32_t> determineDeviceVersions(const PlatformInterface &vkp, uint32_t apiVersion,
190                                                       const tcu::CommandLine &cmdLine)
191 {
192     Move<VkInstance> preinstance = createDefaultInstance(vkp, apiVersion, cmdLine);
193     InstanceDriver preinterface(vkp, preinstance.get());
194 
195     const vector<VkPhysicalDevice> devices = enumeratePhysicalDevices(preinterface, preinstance.get());
196     uint32_t lowestDeviceVersion           = 0xFFFFFFFFu;
197     for (uint32_t deviceNdx = 0u; deviceNdx < devices.size(); ++deviceNdx)
198     {
199         const VkPhysicalDeviceProperties props = getPhysicalDeviceProperties(preinterface, devices[deviceNdx]);
200         if (props.apiVersion < lowestDeviceVersion)
201             lowestDeviceVersion = props.apiVersion;
202     }
203 
204     const vk::VkPhysicalDevice choosenDevice = chooseDevice(preinterface, *preinstance, cmdLine);
205     const VkPhysicalDeviceProperties props   = getPhysicalDeviceProperties(preinterface, choosenDevice);
206     const uint32_t choosenDeviceVersion      = props.apiVersion;
207 
208     return std::make_pair(choosenDeviceVersion, lowestDeviceVersion);
209 }
210 
211 // Remove extensions from a which are found in b.
removeExtensions(const vector<string> & a,const vector<const char * > & b)212 vector<string> removeExtensions(const vector<string> &a, const vector<const char *> &b)
213 {
214     vector<string> res;
215     set<string> removeExts(b.begin(), b.end());
216 
217     for (vector<string>::const_iterator aIter = a.begin(); aIter != a.end(); ++aIter)
218     {
219         if (!de::contains(removeExts, *aIter))
220             res.push_back(*aIter);
221     }
222 
223     return res;
224 }
225 
226 #ifndef CTS_USES_VULKANSC
createInstance(const PlatformInterface & vkp,uint32_t apiVersion,const vector<string> & enabledExtensions,const tcu::CommandLine & cmdLine,DebugReportRecorder * recorder)227 Move<VkInstance> createInstance(const PlatformInterface &vkp, uint32_t apiVersion,
228                                 const vector<string> &enabledExtensions, const tcu::CommandLine &cmdLine,
229                                 DebugReportRecorder *recorder)
230 #else
231 Move<VkInstance> createInstance(const PlatformInterface &vkp, uint32_t apiVersion,
232                                 const vector<string> &enabledExtensions, const tcu::CommandLine &cmdLine)
233 #endif // CTS_USES_VULKANSC
234 {
235 #ifndef CTS_USES_VULKANSC
236     const bool isValidationEnabled = (recorder != nullptr);
237 #else
238     const bool isValidationEnabled = false;
239 #endif // CTS_USES_VULKANSC
240     vector<const char *> enabledLayers;
241 
242     // \note Extensions in core are not explicitly enabled even though
243     //         they are in the extension list advertised to tests.
244     vector<const char *> coreExtensions;
245     getCoreInstanceExtensions(apiVersion, coreExtensions);
246     const auto nonCoreExtensions = removeExtensions(enabledExtensions, coreExtensions);
247 
248     if (isValidationEnabled)
249     {
250         if (!isDebugReportSupported(vkp))
251             TCU_THROW(NotSupportedError, "VK_EXT_debug_report is not supported");
252 
253         enabledLayers = vkt::getValidationLayers(vkp);
254         if (enabledLayers.empty())
255             TCU_THROW(NotSupportedError, "No validation layers found");
256     }
257 
258 #ifndef CTS_USES_VULKANSC
259     return createDefaultInstance(vkp, apiVersion, vector<string>(begin(enabledLayers), end(enabledLayers)),
260                                  nonCoreExtensions, cmdLine, recorder);
261 #else
262     return createDefaultInstance(vkp, apiVersion, vector<string>(begin(enabledLayers), end(enabledLayers)),
263                                  nonCoreExtensions, cmdLine);
264 #endif // CTS_USES_VULKANSC
265 }
266 
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)267 Move<VkDevice> createDefaultDevice(const PlatformInterface &vkp, VkInstance instance, const InstanceInterface &vki,
268                                    VkPhysicalDevice physicalDevice, uint32_t universalQueueIndex,
269                                    uint32_t sparseQueueIndex, int computeQueueIndex, int transferQueueIndex,
270                                    const VkPhysicalDeviceFeatures2 &enabledFeatures,
271                                    const vector<const char *> &usedExtensions, const tcu::CommandLine &cmdLine,
272                                    de::SharedPtr<vk::ResourceInterface> resourceInterface)
273 {
274     VkDeviceQueueCreateInfo queueInfo[4];
275     VkDeviceCreateInfo deviceInfo;
276     vector<const char *> enabledLayers;
277     const float queuePriority = 1.0f;
278     uint32_t numQueues        = 1;
279 
280     deMemset(&queueInfo, 0, sizeof(queueInfo));
281 
282     // Always create the universal queue.
283     queueInfo[0].sType            = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
284     queueInfo[0].pNext            = DE_NULL;
285     queueInfo[0].flags            = (VkDeviceQueueCreateFlags)0u;
286     queueInfo[0].queueFamilyIndex = universalQueueIndex;
287     queueInfo[0].queueCount       = 1u;
288     queueInfo[0].pQueuePriorities = &queuePriority;
289 
290     // And the optional queues if they differ from the "universal" queue, and are supported.
291     if (enabledFeatures.features.sparseBinding && (universalQueueIndex != sparseQueueIndex))
292     {
293         queueInfo[numQueues].sType            = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
294         queueInfo[numQueues].pNext            = DE_NULL;
295         queueInfo[numQueues].flags            = (VkDeviceQueueCreateFlags)0u;
296         queueInfo[numQueues].queueFamilyIndex = sparseQueueIndex;
297         queueInfo[numQueues].queueCount       = 1u;
298         queueInfo[numQueues].pQueuePriorities = &queuePriority;
299         numQueues++;
300     }
301     if (computeQueueIndex != -1 && (universalQueueIndex != (uint32_t)computeQueueIndex))
302     {
303         queueInfo[numQueues].sType            = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
304         queueInfo[numQueues].pNext            = DE_NULL;
305         queueInfo[numQueues].flags            = (VkDeviceQueueCreateFlags)0u;
306         queueInfo[numQueues].queueFamilyIndex = computeQueueIndex;
307         queueInfo[numQueues].queueCount       = 1u;
308         queueInfo[numQueues].pQueuePriorities = &queuePriority;
309         numQueues++;
310     }
311     if (transferQueueIndex != -1 && (universalQueueIndex != (uint32_t)transferQueueIndex))
312     {
313         queueInfo[numQueues].sType            = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
314         queueInfo[numQueues].pNext            = DE_NULL;
315         queueInfo[numQueues].flags            = (VkDeviceQueueCreateFlags)0u;
316         queueInfo[numQueues].queueFamilyIndex = transferQueueIndex;
317         queueInfo[numQueues].queueCount       = 1u;
318         queueInfo[numQueues].pQueuePriorities = &queuePriority;
319         numQueues++;
320     }
321 
322     if (cmdLine.isValidationEnabled())
323     {
324         enabledLayers = vkt::getValidationLayers(vki, physicalDevice);
325         if (enabledLayers.empty())
326             TCU_THROW(NotSupportedError, "No validation layers found");
327     }
328 
329     deMemset(&deviceInfo, 0, sizeof(deviceInfo));
330     // VK_KHR_get_physical_device_properties2 is used if enabledFeatures.pNext != 0
331     deviceInfo.sType                   = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
332     deviceInfo.pNext                   = enabledFeatures.pNext ? &enabledFeatures : nullptr;
333     deviceInfo.queueCreateInfoCount    = numQueues;
334     deviceInfo.pQueueCreateInfos       = queueInfo;
335     deviceInfo.enabledExtensionCount   = de::sizeU32(usedExtensions);
336     deviceInfo.ppEnabledExtensionNames = de::dataOrNull(usedExtensions);
337     deviceInfo.enabledLayerCount       = de::sizeU32(enabledLayers);
338     deviceInfo.ppEnabledLayerNames     = de::dataOrNull(enabledLayers);
339     deviceInfo.pEnabledFeatures        = enabledFeatures.pNext ? nullptr : &enabledFeatures.features;
340 
341 #ifdef CTS_USES_VULKANSC
342     // devices created for Vulkan SC must have VkDeviceObjectReservationCreateInfo structure defined in VkDeviceCreateInfo::pNext chain
343     VkDeviceObjectReservationCreateInfo dmrCI = resetDeviceObjectReservationCreateInfo();
344     VkPipelineCacheCreateInfo pcCI            = {
345         VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO, // VkStructureType sType;
346         DE_NULL,                                      // const void* pNext;
347         VK_PIPELINE_CACHE_CREATE_READ_ONLY_BIT |
348             VK_PIPELINE_CACHE_CREATE_USE_APPLICATION_STORAGE_BIT, // VkPipelineCacheCreateFlags flags;
349         0U,                                                       // uintptr_t initialDataSize;
350         DE_NULL                                                   // const void* pInitialData;
351     };
352 
353     std::vector<VkPipelinePoolSize> poolSizes;
354     if (cmdLine.isSubProcess())
355     {
356         resourceInterface->importPipelineCacheData(vkp, instance, vki, physicalDevice, universalQueueIndex);
357 
358         dmrCI = resourceInterface->getStatMax();
359 
360         if (resourceInterface->getCacheDataSize() > 0)
361         {
362             pcCI.initialDataSize               = resourceInterface->getCacheDataSize();
363             pcCI.pInitialData                  = resourceInterface->getCacheData();
364             dmrCI.pipelineCacheCreateInfoCount = 1;
365             dmrCI.pPipelineCacheCreateInfos    = &pcCI;
366         }
367 
368         poolSizes = resourceInterface->getPipelinePoolSizes();
369         if (!poolSizes.empty())
370         {
371             dmrCI.pipelinePoolSizeCount = uint32_t(poolSizes.size());
372             dmrCI.pPipelinePoolSizes    = poolSizes.data();
373         }
374     }
375 
376     dmrCI.pNext                                     = deviceInfo.pNext;
377     VkPhysicalDeviceVulkanSC10Features sc10Features = createDefaultSC10Features();
378     if (findStructureInChain(dmrCI.pNext, getStructureType<VkPhysicalDeviceVulkanSC10Features>()) == nullptr)
379     {
380         sc10Features.pNext = &dmrCI;
381         deviceInfo.pNext   = &sc10Features;
382     }
383     else
384         deviceInfo.pNext = &dmrCI;
385 
386     vector<VkApplicationParametersEXT> appParams;
387     if (readApplicationParameters(appParams, cmdLine, false))
388     {
389         appParams[appParams.size() - 1].pNext = deviceInfo.pNext;
390         deviceInfo.pNext                      = &appParams[0];
391     }
392 
393     VkFaultCallbackInfo faultCallbackInfo = {
394         VK_STRUCTURE_TYPE_FAULT_CALLBACK_INFO, // VkStructureType sType;
395         DE_NULL,                               // void* pNext;
396         0U,                                    // uint32_t faultCount;
397         nullptr,                               // VkFaultData* pFaults;
398         Context::faultCallbackFunction         // PFN_vkFaultCallbackFunction pfnFaultCallback;
399     };
400 
401     if (cmdLine.isSubProcess())
402     {
403         // XXX workaround incorrect constness on faultCallbackInfo.pNext.
404         faultCallbackInfo.pNext = const_cast<void *>(deviceInfo.pNext);
405         deviceInfo.pNext        = &faultCallbackInfo;
406     }
407 
408 #else
409     DE_UNREF(resourceInterface);
410 #endif // CTS_USES_VULKANSC
411 
412     return createDevice(vkp, instance, vki, physicalDevice, &deviceInfo);
413 }
414 
415 } // namespace
416 
findQueueFamilyIndexWithCapsNoThrow(const InstanceInterface & vkInstance,VkPhysicalDevice physicalDevice,VkQueueFlags requiredCaps,VkQueueFlags excludedCaps)417 int findQueueFamilyIndexWithCapsNoThrow(const InstanceInterface &vkInstance, VkPhysicalDevice physicalDevice,
418                                         VkQueueFlags requiredCaps, VkQueueFlags excludedCaps)
419 {
420     try
421     {
422         return static_cast<int>(findQueueFamilyIndexWithCaps(vkInstance, physicalDevice, requiredCaps, excludedCaps));
423     }
424     catch (const tcu::NotSupportedError &)
425     {
426         return -1;
427     }
428 }
429 
findQueueFamilyIndexWithCaps(const InstanceInterface & vkInstance,VkPhysicalDevice physicalDevice,VkQueueFlags requiredCaps,VkQueueFlags excludedCaps)430 uint32_t findQueueFamilyIndexWithCaps(const InstanceInterface &vkInstance, VkPhysicalDevice physicalDevice,
431                                       VkQueueFlags requiredCaps, VkQueueFlags excludedCaps)
432 {
433     const vector<VkQueueFamilyProperties> queueProps =
434         getPhysicalDeviceQueueFamilyProperties(vkInstance, physicalDevice);
435 
436     for (size_t queueNdx = 0; queueNdx < queueProps.size(); queueNdx++)
437     {
438         uint32_t queueFlags = queueProps[queueNdx].queueFlags;
439         if ((queueFlags & requiredCaps) == requiredCaps && !(queueFlags & excludedCaps))
440             return (uint32_t)queueNdx;
441     }
442 
443     TCU_THROW(NotSupportedError, "No matching queue found");
444 }
445 
446 class DefaultDevice
447 {
448 public:
449     DefaultDevice(const PlatformInterface &vkPlatform, const tcu::CommandLine &cmdLine,
450                   de::SharedPtr<vk::ResourceInterface> resourceInterface);
451     ~DefaultDevice(void);
452 
getInstance(void) const453     VkInstance getInstance(void) const
454     {
455         return *m_instance;
456     }
getInstanceInterface(void) const457     const InstanceInterface &getInstanceInterface(void) const
458     {
459         return m_instanceInterface;
460     }
getMaximumFrameworkVulkanVersion(void) const461     uint32_t getMaximumFrameworkVulkanVersion(void) const
462     {
463         return m_maximumFrameworkVulkanVersion;
464     }
getAvailableInstanceVersion(void) const465     uint32_t getAvailableInstanceVersion(void) const
466     {
467         return m_availableInstanceVersion;
468     }
getUsedInstanceVersion(void) const469     uint32_t getUsedInstanceVersion(void) const
470     {
471         return m_usedInstanceVersion;
472     }
getInstanceExtensions(void) const473     const vector<string> &getInstanceExtensions(void) const
474     {
475         return m_instanceExtensions;
476     }
477 
getPhysicalDevice(void) const478     VkPhysicalDevice getPhysicalDevice(void) const
479     {
480         return m_physicalDevice;
481     }
getDeviceVersion(void) const482     uint32_t getDeviceVersion(void) const
483     {
484         return m_deviceVersion;
485     }
486 
isDeviceFeatureInitialized(VkStructureType sType) const487     bool isDeviceFeatureInitialized(VkStructureType sType) const
488     {
489         return m_deviceFeatures.isDeviceFeatureInitialized(sType);
490     }
getDeviceFeatures(void) const491     const VkPhysicalDeviceFeatures &getDeviceFeatures(void) const
492     {
493         return m_deviceFeatures.getCoreFeatures2().features;
494     }
getDeviceFeatures2(void) const495     const VkPhysicalDeviceFeatures2 &getDeviceFeatures2(void) const
496     {
497         return m_deviceFeatures.getCoreFeatures2();
498     }
getVulkan11Features(void) const499     const VkPhysicalDeviceVulkan11Features &getVulkan11Features(void) const
500     {
501         return m_deviceFeatures.getVulkan11Features();
502     }
getVulkan12Features(void) const503     const VkPhysicalDeviceVulkan12Features &getVulkan12Features(void) const
504     {
505         return m_deviceFeatures.getVulkan12Features();
506     }
507 #ifndef CTS_USES_VULKANSC
getVulkan13Features(void) const508     const VkPhysicalDeviceVulkan13Features &getVulkan13Features(void) const
509     {
510         return m_deviceFeatures.getVulkan13Features();
511     }
512 #endif // CTS_USES_VULKANSC
513 
514 #include "vkDeviceFeaturesForDefaultDeviceDefs.inl"
515 
isDevicePropertyInitialized(VkStructureType sType) const516     bool isDevicePropertyInitialized(VkStructureType sType) const
517     {
518         return m_deviceProperties.isDevicePropertyInitialized(sType);
519     }
getDeviceProperties(void) const520     const VkPhysicalDeviceProperties &getDeviceProperties(void) const
521     {
522         return m_deviceProperties.getCoreProperties2().properties;
523     }
getDeviceProperties2(void) const524     const VkPhysicalDeviceProperties2 &getDeviceProperties2(void) const
525     {
526         return m_deviceProperties.getCoreProperties2();
527     }
getDeviceVulkan11Properties(void) const528     const VkPhysicalDeviceVulkan11Properties &getDeviceVulkan11Properties(void) const
529     {
530         return m_deviceProperties.getVulkan11Properties();
531     }
getDeviceVulkan12Properties(void) const532     const VkPhysicalDeviceVulkan12Properties &getDeviceVulkan12Properties(void) const
533     {
534         return m_deviceProperties.getVulkan12Properties();
535     }
536 #ifndef CTS_USES_VULKANSC
getDeviceVulkan13Properties(void) const537     const VkPhysicalDeviceVulkan13Properties &getDeviceVulkan13Properties(void) const
538     {
539         return m_deviceProperties.getVulkan13Properties();
540     }
541 #endif // CTS_USES_VULKANSC
542 #ifdef CTS_USES_VULKANSC
getDeviceVulkanSC10Properties(void) const543     const VkPhysicalDeviceVulkanSC10Properties &getDeviceVulkanSC10Properties(void) const
544     {
545         return m_deviceProperties.getVulkanSC10Properties();
546     }
547 #endif // CTS_USES_VULKANSC
548 
549 #include "vkDevicePropertiesForDefaultDeviceDefs.inl"
550 
getDevice(void) const551     VkDevice getDevice(void) const
552     {
553         return *m_device;
554     }
getDeviceInterface(void) const555     const DeviceInterface &getDeviceInterface(void) const
556     {
557         return *m_deviceInterface;
558     }
getDeviceExtensions(void) const559     const vector<string> &getDeviceExtensions(void) const
560     {
561         return m_deviceExtensions;
562     }
getDeviceCreationExtensions(void) const563     const vector<const char *> &getDeviceCreationExtensions(void) const
564     {
565         return m_creationExtensions;
566     }
getUsedApiVersion(void) const567     uint32_t getUsedApiVersion(void) const
568     {
569         return m_usedApiVersion;
570     }
getUniversalQueueFamilyIndex(void) const571     uint32_t getUniversalQueueFamilyIndex(void) const
572     {
573         return m_universalQueueFamilyIndex;
574     }
575     VkQueue getUniversalQueue(void) const;
getSparseQueueFamilyIndex(void) const576     uint32_t getSparseQueueFamilyIndex(void) const
577     {
578         return m_sparseQueueFamilyIndex;
579     }
580     VkQueue getSparseQueue(void) const;
getTransferQueueFamilyIndex(void) const581     int getTransferQueueFamilyIndex(void) const
582     {
583         return m_transferQueueFamilyIndex;
584     }
585     VkQueue getTransferQueue(void) const;
getComputeQueueFamilyIndex(void) const586     int getComputeQueueFamilyIndex(void) const
587     {
588         return m_computeQueueFamilyIndex;
589     }
590     VkQueue getComputeQueue(void) const;
591 #ifndef CTS_USES_VULKANSC
hasDebugReportRecorder(void) const592     bool hasDebugReportRecorder(void) const
593     {
594         return m_debugReportRecorder.get() != nullptr;
595     }
getDebugReportRecorder(void) const596     vk::DebugReportRecorder &getDebugReportRecorder(void) const
597     {
598         return *m_debugReportRecorder.get();
599     }
600 #endif // CTS_USES_VULKANSC
601 
602 private:
603 #ifndef CTS_USES_VULKANSC
604     using DebugReportRecorderPtr = de::UniquePtr<vk::DebugReportRecorder>;
605     using DebugReportCallbackPtr = vk::Move<VkDebugReportCallbackEXT>;
606 #endif // CTS_USES_VULKANSC
607 
608     const uint32_t m_maximumFrameworkVulkanVersion;
609     const uint32_t m_availableInstanceVersion;
610     const uint32_t m_usedInstanceVersion;
611 
612     const std::pair<uint32_t, uint32_t> m_deviceVersions;
613     const uint32_t m_usedApiVersion;
614 
615 #ifndef CTS_USES_VULKANSC
616     const DebugReportRecorderPtr m_debugReportRecorder;
617 #endif // CTS_USES_VULKANSC
618     const vector<string> m_instanceExtensions;
619     const Unique<VkInstance> m_instance;
620 #ifndef CTS_USES_VULKANSC
621     const InstanceDriver m_instanceInterface;
622     const DebugReportCallbackPtr m_debugReportCallback;
623 #else
624     const InstanceDriverSC m_instanceInterface;
625 #endif // CTS_USES_VULKANSC
626     const VkPhysicalDevice m_physicalDevice;
627     const uint32_t m_deviceVersion;
628 
629     const vector<string> m_deviceExtensions;
630     const DeviceFeatures m_deviceFeatures;
631 
632     const uint32_t m_universalQueueFamilyIndex;
633     const uint32_t m_sparseQueueFamilyIndex;
634 
635     // Optional exclusive queues
636     const int m_computeQueueFamilyIndex;
637     const int m_transferQueueFamilyIndex;
638 
639     const DeviceProperties m_deviceProperties;
640     const vector<const char *> m_creationExtensions;
641 
642     const Unique<VkDevice> m_device;
643     const de::MovePtr<DeviceDriver> m_deviceInterface;
644 };
645 
646 namespace
647 {
648 
sanitizeApiVersion(uint32_t v)649 uint32_t sanitizeApiVersion(uint32_t v)
650 {
651     return VK_MAKE_API_VERSION(VK_API_VERSION_VARIANT(v), VK_API_VERSION_MAJOR(v), VK_API_VERSION_MINOR(v), 0);
652 }
653 
654 #ifndef CTS_USES_VULKANSC
createDebugReportRecorder(const vk::PlatformInterface & vkp,bool printValidationErrors)655 de::MovePtr<vk::DebugReportRecorder> createDebugReportRecorder(const vk::PlatformInterface &vkp,
656                                                                bool printValidationErrors)
657 {
658     if (isDebugReportSupported(vkp))
659         return de::MovePtr<vk::DebugReportRecorder>(new vk::DebugReportRecorder(printValidationErrors));
660     else
661         TCU_THROW(NotSupportedError, "VK_EXT_debug_report is not supported");
662 }
663 #endif // CTS_USES_VULKANSC
664 
665 // 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)666 vector<const char *> removeCoreExtensions(const uint32_t apiVersion, const vector<string> &extensions)
667 {
668     // Make vector of char ptrs.
669     vector<const char *> extensionPtrs;
670     extensionPtrs.reserve(extensions.size());
671     std::transform(begin(extensions), end(extensions), std::back_inserter(extensionPtrs),
672                    [](const string &s) { return s.c_str(); });
673 
674     // Obtain the core extension list.
675     vector<const char *> coreExtensions;
676     getCoreDeviceExtensions(apiVersion, coreExtensions);
677 
678     // Remove any extension found in the core extension list.
679     const auto isNonCoreExtension = [&coreExtensions](const char *extName)
680     {
681         const auto isSameString = [&extName](const char *otherExtName)
682         { return (std::strcmp(otherExtName, extName) == 0); };
683         return std::find_if(begin(coreExtensions), end(coreExtensions), isSameString) == end(coreExtensions);
684     };
685 
686     vector<const char *> filteredExtensions;
687     std::copy_if(begin(extensionPtrs), end(extensionPtrs), std::back_inserter(filteredExtensions), isNonCoreExtension);
688     return filteredExtensions;
689 }
690 
691 } // namespace
692 
DefaultDevice(const PlatformInterface & vkPlatform,const tcu::CommandLine & cmdLine,de::SharedPtr<vk::ResourceInterface> resourceInterface)693 DefaultDevice::DefaultDevice(const PlatformInterface &vkPlatform, const tcu::CommandLine &cmdLine,
694                              de::SharedPtr<vk::ResourceInterface> resourceInterface)
695 #ifndef CTS_USES_VULKANSC
696     : m_maximumFrameworkVulkanVersion(VK_API_MAX_FRAMEWORK_VERSION)
697 #else
698     : m_maximumFrameworkVulkanVersion(VKSC_API_MAX_FRAMEWORK_VERSION)
699 #endif // CTS_USES_VULKANSC
700     , m_availableInstanceVersion(getTargetInstanceVersion(vkPlatform))
701     , m_usedInstanceVersion(
702           sanitizeApiVersion(minVulkanAPIVersion(m_availableInstanceVersion, m_maximumFrameworkVulkanVersion)))
703     , m_deviceVersions(determineDeviceVersions(vkPlatform, m_usedInstanceVersion, cmdLine))
704     , m_usedApiVersion(sanitizeApiVersion(minVulkanAPIVersion(m_usedInstanceVersion, m_deviceVersions.first)))
705 
706 #ifndef CTS_USES_VULKANSC
707     , m_debugReportRecorder(cmdLine.isValidationEnabled() ?
708                                 createDebugReportRecorder(vkPlatform, cmdLine.printValidationErrors()) :
709                                 de::MovePtr<vk::DebugReportRecorder>())
710 #endif // CTS_USES_VULKANSC
711     , m_instanceExtensions(addCoreInstanceExtensions(
712           filterExtensions(enumerateInstanceExtensionProperties(vkPlatform, DE_NULL)), m_usedApiVersion))
713 #ifndef CTS_USES_VULKANSC
714     , m_instance(
715           createInstance(vkPlatform, m_usedApiVersion, m_instanceExtensions, cmdLine, m_debugReportRecorder.get()))
716 #else
717     , m_instance(createInstance(vkPlatform, m_usedApiVersion, m_instanceExtensions, cmdLine))
718 #endif // CTS_USES_VULKANSC
719 
720 #ifndef CTS_USES_VULKANSC
721     , m_instanceInterface(vkPlatform, *m_instance)
722 
723     , m_debugReportCallback(cmdLine.isValidationEnabled() ?
724                                 m_debugReportRecorder->createCallback(m_instanceInterface, m_instance.get()) :
725                                 DebugReportCallbackPtr())
726 #else
727     , m_instanceInterface(vkPlatform, *m_instance, cmdLine, resourceInterface)
728 #endif // CTS_USES_VULKANSC
729     , m_physicalDevice(chooseDevice(m_instanceInterface, *m_instance, cmdLine))
730     , m_deviceVersion(getPhysicalDeviceProperties(m_instanceInterface, m_physicalDevice).apiVersion)
731 
732     , m_deviceExtensions(addCoreDeviceExtensions(
733           filterExtensions(enumerateDeviceExtensionProperties(m_instanceInterface, m_physicalDevice, DE_NULL)),
734           m_usedApiVersion))
735     , m_deviceFeatures(m_instanceInterface, m_usedApiVersion, m_physicalDevice, m_instanceExtensions,
736                        m_deviceExtensions)
737     , m_universalQueueFamilyIndex(findQueueFamilyIndexWithCaps(
738           m_instanceInterface, m_physicalDevice,
739           cmdLine.isComputeOnly() ? VK_QUEUE_COMPUTE_BIT : VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT))
740 #ifndef CTS_USES_VULKANSC
741     , m_sparseQueueFamilyIndex(
742           m_deviceFeatures.getCoreFeatures2().features.sparseBinding ?
743               findQueueFamilyIndexWithCaps(m_instanceInterface, m_physicalDevice, VK_QUEUE_SPARSE_BINDING_BIT) :
744               0)
745 #else
746     , m_sparseQueueFamilyIndex(0)
747 #endif // CTS_USES_VULKANSC
748     , m_computeQueueFamilyIndex(findQueueFamilyIndexWithCapsNoThrow(m_instanceInterface, m_physicalDevice,
749                                                                     VK_QUEUE_COMPUTE_BIT, VK_QUEUE_GRAPHICS_BIT))
750     , m_transferQueueFamilyIndex(findQueueFamilyIndexWithCapsNoThrow(
751           m_instanceInterface, m_physicalDevice, VK_QUEUE_TRANSFER_BIT, VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT))
752     , m_deviceProperties(m_instanceInterface, m_usedApiVersion, m_physicalDevice, m_instanceExtensions,
753                          m_deviceExtensions)
754     // When the default device is created, we remove the core extensions from the extension list, but those core extensions are
755     // still reported as part of Context::getDeviceExtensions(). If we need the list of extensions actually used when creating the
756     // default device, we can use Context::getDeviceCreationExtensions().
757     , m_creationExtensions(removeCoreExtensions(m_usedApiVersion, m_deviceExtensions))
758     , m_device(createDefaultDevice(vkPlatform, *m_instance, m_instanceInterface, m_physicalDevice,
759                                    m_universalQueueFamilyIndex, m_sparseQueueFamilyIndex, m_computeQueueFamilyIndex,
760                                    m_transferQueueFamilyIndex, m_deviceFeatures.getCoreFeatures2(),
761                                    m_creationExtensions, cmdLine, resourceInterface))
762 #ifndef CTS_USES_VULKANSC
763     , m_deviceInterface(
764           de::MovePtr<DeviceDriver>(new DeviceDriver(vkPlatform, *m_instance, *m_device, m_usedApiVersion, cmdLine)))
765 #else
766     , m_deviceInterface(de::MovePtr<DeviceDriverSC>(
767           new DeviceDriverSC(vkPlatform, *m_instance, *m_device, cmdLine, resourceInterface,
768                              getDeviceVulkanSC10Properties(), getDeviceProperties(), m_usedApiVersion)))
769 #endif // CTS_USES_VULKANSC
770 {
771 #ifndef CTS_USES_VULKANSC
772     DE_UNREF(resourceInterface);
773 #endif
774     DE_ASSERT(m_deviceVersions.first == m_deviceVersion);
775 }
776 
~DefaultDevice(void)777 DefaultDevice::~DefaultDevice(void)
778 {
779 }
780 
getUniversalQueue(void) const781 VkQueue DefaultDevice::getUniversalQueue(void) const
782 {
783     return getDeviceQueue(*m_deviceInterface, *m_device, m_universalQueueFamilyIndex, 0);
784 }
785 
getSparseQueue(void) const786 VkQueue DefaultDevice::getSparseQueue(void) const
787 {
788     if (!m_deviceFeatures.getCoreFeatures2().features.sparseBinding)
789         TCU_THROW(NotSupportedError, "Sparse binding not supported.");
790 
791     return getDeviceQueue(*m_deviceInterface, *m_device, m_sparseQueueFamilyIndex, 0);
792 }
793 
getComputeQueue(void) const794 VkQueue DefaultDevice::getComputeQueue(void) const
795 {
796     if (m_computeQueueFamilyIndex == -1)
797         TCU_THROW(NotSupportedError, "Exclusive compute queue not supported.");
798 
799     return getDeviceQueue(*m_deviceInterface, *m_device, m_computeQueueFamilyIndex, 0);
800 }
801 
getTransferQueue(void) const802 VkQueue DefaultDevice::getTransferQueue(void) const
803 {
804     if (m_transferQueueFamilyIndex == -1)
805         TCU_THROW(NotSupportedError, "Exclusive transfer queue not supported.");
806 
807     return getDeviceQueue(*m_deviceInterface, *m_device, m_transferQueueFamilyIndex, 0);
808 }
809 
810 namespace
811 {
812 // Allocator utilities
813 
createAllocator(DefaultDevice * device)814 vk::Allocator *createAllocator(DefaultDevice *device)
815 {
816     const auto &vki             = device->getInstanceInterface();
817     const auto physicalDevice   = device->getPhysicalDevice();
818     const auto memoryProperties = vk::getPhysicalDeviceMemoryProperties(vki, physicalDevice);
819 
820     // \todo [2015-07-24 jarkko] support allocator selection/configuration from command line (or compile time)
821     return new SimpleAllocator(device->getDeviceInterface(), device->getDevice(), memoryProperties);
822 }
823 
824 } // namespace
825 
826 // Context
827 
Context(tcu::TestContext & testCtx,const vk::PlatformInterface & platformInterface,vk::BinaryCollection & progCollection,de::SharedPtr<vk::ResourceInterface> resourceInterface)828 Context::Context(tcu::TestContext &testCtx, const vk::PlatformInterface &platformInterface,
829                  vk::BinaryCollection &progCollection, de::SharedPtr<vk::ResourceInterface> resourceInterface)
830     : m_testCtx(testCtx)
831     , m_platformInterface(platformInterface)
832     , m_progCollection(progCollection)
833     , m_resourceInterface(resourceInterface)
834     , m_device(new DefaultDevice(m_platformInterface, testCtx.getCommandLine(), resourceInterface))
835     , m_allocator(createAllocator(m_device.get()))
836     , m_resultSetOnValidation(false)
837 {
838 }
839 
~Context(void)840 Context::~Context(void)
841 {
842 }
843 
getMaximumFrameworkVulkanVersion(void) const844 uint32_t Context::getMaximumFrameworkVulkanVersion(void) const
845 {
846     return m_device->getMaximumFrameworkVulkanVersion();
847 }
getAvailableInstanceVersion(void) const848 uint32_t Context::getAvailableInstanceVersion(void) const
849 {
850     return m_device->getAvailableInstanceVersion();
851 }
getInstanceExtensions(void) const852 const vector<string> &Context::getInstanceExtensions(void) const
853 {
854     return m_device->getInstanceExtensions();
855 }
getInstance(void) const856 vk::VkInstance Context::getInstance(void) const
857 {
858     return m_device->getInstance();
859 }
getInstanceInterface(void) const860 const vk::InstanceInterface &Context::getInstanceInterface(void) const
861 {
862     return m_device->getInstanceInterface();
863 }
getPhysicalDevice(void) const864 vk::VkPhysicalDevice Context::getPhysicalDevice(void) const
865 {
866     return m_device->getPhysicalDevice();
867 }
getDeviceVersion(void) const868 uint32_t Context::getDeviceVersion(void) const
869 {
870     return m_device->getDeviceVersion();
871 }
getDeviceFeatures(void) const872 const vk::VkPhysicalDeviceFeatures &Context::getDeviceFeatures(void) const
873 {
874     return m_device->getDeviceFeatures();
875 }
getDeviceFeatures2(void) const876 const vk::VkPhysicalDeviceFeatures2 &Context::getDeviceFeatures2(void) const
877 {
878     return m_device->getDeviceFeatures2();
879 }
getDeviceVulkan11Features(void) const880 const vk::VkPhysicalDeviceVulkan11Features &Context::getDeviceVulkan11Features(void) const
881 {
882     return m_device->getVulkan11Features();
883 }
getDeviceVulkan12Features(void) const884 const vk::VkPhysicalDeviceVulkan12Features &Context::getDeviceVulkan12Features(void) const
885 {
886     return m_device->getVulkan12Features();
887 }
888 #ifndef CTS_USES_VULKANSC
getDeviceVulkan13Features(void) const889 const vk::VkPhysicalDeviceVulkan13Features &Context::getDeviceVulkan13Features(void) const
890 {
891     return m_device->getVulkan13Features();
892 }
893 #endif // CTS_USES_VULKANSC
894 #ifdef CTS_USES_VULKANSC
getDeviceVulkanSC10Features(void) const895 const vk::VkPhysicalDeviceVulkanSC10Features &Context::getDeviceVulkanSC10Features(void) const
896 {
897     return m_device->getVulkanSC10Features();
898 }
899 #endif // CTS_USES_VULKANSC
900 
isDeviceFunctionalitySupported(const std::string & extension) const901 bool Context::isDeviceFunctionalitySupported(const std::string &extension) const
902 {
903     // If extension was promoted to core then check using the core mechanism. This is required so that
904     // all core implementations have the functionality tested, even if they don't support the extension.
905     // (It also means that core-optional extensions will not be reported as supported unless the
906     // features are really supported if the CTS code adds all core extensions to the extension list).
907     uint32_t apiVersion = getUsedApiVersion();
908     if (isCoreDeviceExtension(apiVersion, extension))
909     {
910         if (apiVersion < VK_MAKE_API_VERSION(0, 1, 2, 0))
911         {
912             // Check feature bits in extension-specific structures.
913             if (extension == "VK_KHR_multiview")
914                 return !!m_device->getMultiviewFeatures().multiview;
915             if (extension == "VK_KHR_variable_pointers")
916                 return !!m_device->getVariablePointersFeatures().variablePointersStorageBuffer;
917             if (extension == "VK_KHR_sampler_ycbcr_conversion")
918                 return !!m_device->getSamplerYcbcrConversionFeatures().samplerYcbcrConversion;
919             if (extension == "VK_KHR_shader_draw_parameters")
920                 return !!m_device->getShaderDrawParametersFeatures().shaderDrawParameters;
921         }
922         else
923         {
924             // Check feature bits using the new Vulkan 1.2 structures.
925             const auto &vk11Features = m_device->getVulkan11Features();
926             if (extension == "VK_KHR_multiview")
927                 return !!vk11Features.multiview;
928             if (extension == "VK_KHR_variable_pointers")
929                 return !!vk11Features.variablePointersStorageBuffer;
930             if (extension == "VK_KHR_sampler_ycbcr_conversion")
931                 return !!vk11Features.samplerYcbcrConversion;
932             if (extension == "VK_KHR_shader_draw_parameters")
933                 return !!vk11Features.shaderDrawParameters;
934 
935             const auto &vk12Features = m_device->getVulkan12Features();
936             if (extension == "VK_KHR_timeline_semaphore")
937                 return !!vk12Features.timelineSemaphore;
938             if (extension == "VK_KHR_buffer_device_address")
939                 return !!vk12Features.bufferDeviceAddress;
940             if (extension == "VK_EXT_descriptor_indexing")
941                 return !!vk12Features.descriptorIndexing;
942             if (extension == "VK_KHR_draw_indirect_count")
943                 return !!vk12Features.drawIndirectCount;
944             if (extension == "VK_KHR_sampler_mirror_clamp_to_edge")
945                 return !!vk12Features.samplerMirrorClampToEdge;
946             if (extension == "VK_EXT_sampler_filter_minmax")
947                 return !!vk12Features.samplerFilterMinmax;
948             if (extension == "VK_EXT_shader_viewport_index_layer")
949                 return !!vk12Features.shaderOutputViewportIndex && !!vk12Features.shaderOutputLayer;
950 
951 #ifndef CTS_USES_VULKANSC
952             const auto &vk13Features = m_device->getVulkan13Features();
953             if (extension == "VK_EXT_inline_uniform_block")
954                 return !!vk13Features.inlineUniformBlock;
955             if (extension == "VK_EXT_pipeline_creation_cache_control")
956                 return !!vk13Features.pipelineCreationCacheControl;
957             if (extension == "VK_EXT_private_data")
958                 return !!vk13Features.privateData;
959             if (extension == "VK_EXT_shader_demote_to_helper_invocation")
960                 return !!vk13Features.shaderDemoteToHelperInvocation;
961             if (extension == "VK_KHR_shader_terminate_invocation")
962                 return !!vk13Features.shaderTerminateInvocation;
963             if (extension == "VK_EXT_subgroup_size_control")
964                 return !!vk13Features.subgroupSizeControl;
965             if (extension == "VK_KHR_synchronization2")
966                 return !!vk13Features.synchronization2;
967             if (extension == "VK_EXT_texture_compression_astc_hdr")
968                 return !!vk13Features.textureCompressionASTC_HDR;
969             if (extension == "VK_KHR_zero_initialize_workgroup_memory")
970                 return !!vk13Features.shaderZeroInitializeWorkgroupMemory;
971             if (extension == "VK_KHR_dynamic_rendering")
972                 return !!vk13Features.dynamicRendering;
973             if (extension == "VK_KHR_shader_integer_dot_product")
974                 return !!vk13Features.shaderIntegerDotProduct;
975             if (extension == "VK_KHR_maintenance4")
976                 return !!vk13Features.maintenance4;
977 #endif // CTS_USES_VULKANSC
978 
979 #ifdef CTS_USES_VULKANSC
980             const auto &vk12Properties = m_device->getDeviceVulkan12Properties();
981             if (extension == "VK_KHR_depth_stencil_resolve")
982                 return (vk12Properties.supportedDepthResolveModes != VK_RESOLVE_MODE_NONE) &&
983                        (vk12Properties.supportedStencilResolveModes != VK_RESOLVE_MODE_NONE);
984 #endif // CTS_USES_VULKANSC
985         }
986 
987         // No feature flags to check.
988         return true;
989     }
990 
991     // If this is not a core extension then just return whether the implementation says it's supported.
992     const auto &extensions = getDeviceExtensions();
993     return de::contains(extensions.begin(), extensions.end(), extension);
994 }
995 
isInstanceFunctionalitySupported(const std::string & extension) const996 bool Context::isInstanceFunctionalitySupported(const std::string &extension) const
997 {
998     // NOTE: current implementation uses isInstanceExtensionSupported but
999     // this will change when some instance extensions will be promoted to the
1000     // core; don't use isInstanceExtensionSupported directly, use this method instead
1001     return isInstanceExtensionSupported(getUsedApiVersion(), getInstanceExtensions(), extension);
1002 }
1003 
1004 #include "vkDeviceFeaturesForContextDefs.inl"
1005 
getDeviceProperties(void) const1006 const vk::VkPhysicalDeviceProperties &Context::getDeviceProperties(void) const
1007 {
1008     return m_device->getDeviceProperties();
1009 }
getDeviceProperties2(void) const1010 const vk::VkPhysicalDeviceProperties2 &Context::getDeviceProperties2(void) const
1011 {
1012     return m_device->getDeviceProperties2();
1013 }
getDeviceVulkan11Properties(void) const1014 const vk::VkPhysicalDeviceVulkan11Properties &Context::getDeviceVulkan11Properties(void) const
1015 {
1016     return m_device->getDeviceVulkan11Properties();
1017 }
getDeviceVulkan12Properties(void) const1018 const vk::VkPhysicalDeviceVulkan12Properties &Context::getDeviceVulkan12Properties(void) const
1019 {
1020     return m_device->getDeviceVulkan12Properties();
1021 }
1022 #ifndef CTS_USES_VULKANSC
getDeviceVulkan13Properties(void) const1023 const vk::VkPhysicalDeviceVulkan13Properties &Context::getDeviceVulkan13Properties(void) const
1024 {
1025     return m_device->getDeviceVulkan13Properties();
1026 }
1027 #endif // CTS_USES_VULKANSC
1028 #ifdef CTS_USES_VULKANSC
getDeviceVulkanSC10Properties(void) const1029 const vk::VkPhysicalDeviceVulkanSC10Properties &Context::getDeviceVulkanSC10Properties(void) const
1030 {
1031     return m_device->getDeviceVulkanSC10Properties();
1032 }
1033 #endif // CTS_USES_VULKANSC
1034 
1035 #include "vkDevicePropertiesForContextDefs.inl"
1036 
getDeviceExtensions(void) const1037 const vector<string> &Context::getDeviceExtensions(void) const
1038 {
1039     return m_device->getDeviceExtensions();
1040 }
getDeviceCreationExtensions(void) const1041 const vector<const char *> &Context::getDeviceCreationExtensions(void) const
1042 {
1043     return m_device->getDeviceCreationExtensions();
1044 }
getDevice(void) const1045 vk::VkDevice Context::getDevice(void) const
1046 {
1047     return m_device->getDevice();
1048 }
getDeviceInterface(void) const1049 const vk::DeviceInterface &Context::getDeviceInterface(void) const
1050 {
1051     return m_device->getDeviceInterface();
1052 }
getUniversalQueueFamilyIndex(void) const1053 uint32_t Context::getUniversalQueueFamilyIndex(void) const
1054 {
1055     return m_device->getUniversalQueueFamilyIndex();
1056 }
getUniversalQueue(void) const1057 vk::VkQueue Context::getUniversalQueue(void) const
1058 {
1059     return m_device->getUniversalQueue();
1060 }
getComputeQueueFamilyIndex(void) const1061 int Context::getComputeQueueFamilyIndex(void) const
1062 {
1063     return m_device->getComputeQueueFamilyIndex();
1064 }
getComputeQueue(void) const1065 vk::VkQueue Context::getComputeQueue(void) const
1066 {
1067     return m_device->getComputeQueue();
1068 }
getTransferQueueFamilyIndex(void) const1069 int Context::getTransferQueueFamilyIndex(void) const
1070 {
1071     return m_device->getTransferQueueFamilyIndex();
1072 }
getTransferQueue(void) const1073 vk::VkQueue Context::getTransferQueue(void) const
1074 {
1075     return m_device->getTransferQueue();
1076 }
getSparseQueueFamilyIndex(void) const1077 uint32_t Context::getSparseQueueFamilyIndex(void) const
1078 {
1079     return m_device->getSparseQueueFamilyIndex();
1080 }
getSparseQueue(void) const1081 vk::VkQueue Context::getSparseQueue(void) const
1082 {
1083     return m_device->getSparseQueue();
1084 }
getResourceInterface(void) const1085 de::SharedPtr<vk::ResourceInterface> Context::getResourceInterface(void) const
1086 {
1087     return m_resourceInterface;
1088 }
getDefaultAllocator(void) const1089 vk::Allocator &Context::getDefaultAllocator(void) const
1090 {
1091     return *m_allocator;
1092 }
getUsedApiVersion(void) const1093 uint32_t Context::getUsedApiVersion(void) const
1094 {
1095     return m_device->getUsedApiVersion();
1096 }
contextSupports(const uint32_t variantNum,const uint32_t majorNum,const uint32_t minorNum,const uint32_t patchNum) const1097 bool Context::contextSupports(const uint32_t variantNum, const uint32_t majorNum, const uint32_t minorNum,
1098                               const uint32_t patchNum) const
1099 {
1100     return isApiVersionSupported(m_device->getUsedApiVersion(),
1101                                  VK_MAKE_API_VERSION(variantNum, majorNum, minorNum, patchNum));
1102 }
contextSupports(const ApiVersion version) const1103 bool Context::contextSupports(const ApiVersion version) const
1104 {
1105     return isApiVersionSupported(m_device->getUsedApiVersion(), pack(version));
1106 }
contextSupports(const uint32_t requiredApiVersionBits) const1107 bool Context::contextSupports(const uint32_t requiredApiVersionBits) const
1108 {
1109     return isApiVersionSupported(m_device->getUsedApiVersion(), requiredApiVersionBits);
1110 }
isDeviceFeatureInitialized(vk::VkStructureType sType) const1111 bool Context::isDeviceFeatureInitialized(vk::VkStructureType sType) const
1112 {
1113     return m_device->isDeviceFeatureInitialized(sType);
1114 }
isDevicePropertyInitialized(vk::VkStructureType sType) const1115 bool Context::isDevicePropertyInitialized(vk::VkStructureType sType) const
1116 {
1117     return m_device->isDevicePropertyInitialized(sType);
1118 }
1119 
requireDeviceFunctionality(const std::string & required) const1120 bool Context::requireDeviceFunctionality(const std::string &required) const
1121 {
1122     if (!isDeviceFunctionalitySupported(required))
1123         TCU_THROW(NotSupportedError, required + " is not supported");
1124 
1125     return true;
1126 }
1127 
requireInstanceFunctionality(const std::string & required) const1128 bool Context::requireInstanceFunctionality(const std::string &required) const
1129 {
1130     if (!isInstanceFunctionalitySupported(required))
1131         TCU_THROW(NotSupportedError, required + " is not supported");
1132 
1133     return true;
1134 }
1135 
1136 struct DeviceCoreFeaturesTable
1137 {
1138     const char *featureName;
1139     const uint32_t featureArrayIndex;
1140     const uint32_t featureArrayOffset;
1141 };
1142 
1143 #define DEVICE_CORE_FEATURE_OFFSET(FEATURE_FIELD_NAME) offsetof(VkPhysicalDeviceFeatures, FEATURE_FIELD_NAME)
1144 #define DEVICE_CORE_FEATURE_ENTRY(BITNAME, FIELDNAME)              \
1145     {                                                              \
1146         #FIELDNAME, BITNAME, DEVICE_CORE_FEATURE_OFFSET(FIELDNAME) \
1147     }
1148 
1149 const DeviceCoreFeaturesTable deviceCoreFeaturesTable[] = {
1150     DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_ROBUST_BUFFER_ACCESS, robustBufferAccess),
1151     DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_FULL_DRAW_INDEX_UINT32, fullDrawIndexUint32),
1152     DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_IMAGE_CUBE_ARRAY, imageCubeArray),
1153     DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_INDEPENDENT_BLEND, independentBlend),
1154     DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_GEOMETRY_SHADER, geometryShader),
1155     DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_TESSELLATION_SHADER, tessellationShader),
1156     DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SAMPLE_RATE_SHADING, sampleRateShading),
1157     DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_DUAL_SRC_BLEND, dualSrcBlend),
1158     DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_LOGIC_OP, logicOp),
1159     DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_MULTI_DRAW_INDIRECT, multiDrawIndirect),
1160     DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_DRAW_INDIRECT_FIRST_INSTANCE, drawIndirectFirstInstance),
1161     DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_DEPTH_CLAMP, depthClamp),
1162     DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_DEPTH_BIAS_CLAMP, depthBiasClamp),
1163     DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_FILL_MODE_NON_SOLID, fillModeNonSolid),
1164     DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_DEPTH_BOUNDS, depthBounds),
1165     DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_WIDE_LINES, wideLines),
1166     DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_LARGE_POINTS, largePoints),
1167     DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_ALPHA_TO_ONE, alphaToOne),
1168     DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_MULTI_VIEWPORT, multiViewport),
1169     DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SAMPLER_ANISOTROPY, samplerAnisotropy),
1170     DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_TEXTURE_COMPRESSION_ETC2, textureCompressionETC2),
1171     DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_TEXTURE_COMPRESSION_ASTC_LDR, textureCompressionASTC_LDR),
1172     DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_TEXTURE_COMPRESSION_BC, textureCompressionBC),
1173     DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_OCCLUSION_QUERY_PRECISE, occlusionQueryPrecise),
1174     DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_PIPELINE_STATISTICS_QUERY, pipelineStatisticsQuery),
1175     DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_VERTEX_PIPELINE_STORES_AND_ATOMICS, vertexPipelineStoresAndAtomics),
1176     DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_FRAGMENT_STORES_AND_ATOMICS, fragmentStoresAndAtomics),
1177     DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_TESSELLATION_AND_GEOMETRY_POINT_SIZE,
1178                               shaderTessellationAndGeometryPointSize),
1179     DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_IMAGE_GATHER_EXTENDED, shaderImageGatherExtended),
1180     DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_STORAGE_IMAGE_EXTENDED_FORMATS,
1181                               shaderStorageImageExtendedFormats),
1182     DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_STORAGE_IMAGE_MULTISAMPLE, shaderStorageImageMultisample),
1183     DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_STORAGE_IMAGE_READ_WITHOUT_FORMAT,
1184                               shaderStorageImageReadWithoutFormat),
1185     DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_STORAGE_IMAGE_WRITE_WITHOUT_FORMAT,
1186                               shaderStorageImageWriteWithoutFormat),
1187     DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_UNIFORM_BUFFER_ARRAY_DYNAMIC_INDEXING,
1188                               shaderUniformBufferArrayDynamicIndexing),
1189     DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_SAMPLED_IMAGE_ARRAY_DYNAMIC_INDEXING,
1190                               shaderSampledImageArrayDynamicIndexing),
1191     DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_STORAGE_BUFFER_ARRAY_DYNAMIC_INDEXING,
1192                               shaderStorageBufferArrayDynamicIndexing),
1193     DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_STORAGE_IMAGE_ARRAY_DYNAMIC_INDEXING,
1194                               shaderStorageImageArrayDynamicIndexing),
1195     DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_CLIP_DISTANCE, shaderClipDistance),
1196     DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_CULL_DISTANCE, shaderCullDistance),
1197     DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_FLOAT64, shaderFloat64),
1198     DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_INT64, shaderInt64),
1199     DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_INT16, shaderInt16),
1200     DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_RESOURCE_RESIDENCY, shaderResourceResidency),
1201     DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_RESOURCE_MIN_LOD, shaderResourceMinLod),
1202     DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SPARSE_BINDING, sparseBinding),
1203     DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SPARSE_RESIDENCY_BUFFER, sparseResidencyBuffer),
1204     DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SPARSE_RESIDENCY_IMAGE2D, sparseResidencyImage2D),
1205     DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SPARSE_RESIDENCY_IMAGE3D, sparseResidencyImage3D),
1206     DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SPARSE_RESIDENCY2_SAMPLES, sparseResidency2Samples),
1207     DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SPARSE_RESIDENCY4_SAMPLES, sparseResidency4Samples),
1208     DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SPARSE_RESIDENCY8_SAMPLES, sparseResidency8Samples),
1209     DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SPARSE_RESIDENCY16_SAMPLES, sparseResidency16Samples),
1210     DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SPARSE_RESIDENCY_ALIASED, sparseResidencyAliased),
1211     DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_VARIABLE_MULTISAMPLE_RATE, variableMultisampleRate),
1212     DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_INHERITED_QUERIES, inheritedQueries),
1213 };
1214 
requireDeviceCoreFeature(const DeviceCoreFeature requiredFeature)1215 bool Context::requireDeviceCoreFeature(const DeviceCoreFeature requiredFeature)
1216 {
1217     const vk::VkPhysicalDeviceFeatures &featuresAvailable = getDeviceFeatures();
1218     const vk::VkBool32 *featuresAvailableArray            = (vk::VkBool32 *)(&featuresAvailable);
1219     const uint32_t requiredFeatureIndex                   = static_cast<uint32_t>(requiredFeature);
1220 
1221     DE_ASSERT(requiredFeatureIndex * sizeof(vk::VkBool32) < sizeof(featuresAvailable));
1222     DE_ASSERT(deviceCoreFeaturesTable[requiredFeatureIndex].featureArrayIndex * sizeof(vk::VkBool32) ==
1223               deviceCoreFeaturesTable[requiredFeatureIndex].featureArrayOffset);
1224 
1225     if (featuresAvailableArray[requiredFeatureIndex] == false)
1226         TCU_THROW(NotSupportedError, "Requested core feature is not supported: " +
1227                                          std::string(deviceCoreFeaturesTable[requiredFeatureIndex].featureName));
1228 
1229     return true;
1230 }
1231 
1232 #ifndef CTS_USES_VULKANSC
1233 
isSpirvCompatibleFormat(VkFormat format)1234 static bool isSpirvCompatibleFormat(VkFormat format)
1235 {
1236     switch (format)
1237     {
1238     case VK_FORMAT_R32G32B32A32_SFLOAT:
1239     case VK_FORMAT_R32G32_SFLOAT:
1240     case VK_FORMAT_R32_SFLOAT:
1241     case VK_FORMAT_R16G16B16A16_SFLOAT:
1242     case VK_FORMAT_R16G16_SFLOAT:
1243     case VK_FORMAT_R16_SFLOAT:
1244     case VK_FORMAT_R16G16B16A16_UNORM:
1245     case VK_FORMAT_R16G16_UNORM:
1246     case VK_FORMAT_R16_UNORM:
1247     case VK_FORMAT_R16G16B16A16_SNORM:
1248     case VK_FORMAT_R16G16_SNORM:
1249     case VK_FORMAT_R16_SNORM:
1250     case VK_FORMAT_A2B10G10R10_UNORM_PACK32:
1251     case VK_FORMAT_B10G11R11_UFLOAT_PACK32:
1252     case VK_FORMAT_R8G8B8A8_UNORM:
1253     case VK_FORMAT_R8G8_UNORM:
1254     case VK_FORMAT_R8_UNORM:
1255     case VK_FORMAT_R8G8B8A8_SNORM:
1256     case VK_FORMAT_R8G8_SNORM:
1257     case VK_FORMAT_R8_SNORM:
1258     case VK_FORMAT_R32G32B32A32_SINT:
1259     case VK_FORMAT_R32G32_SINT:
1260     case VK_FORMAT_R32_SINT:
1261     case VK_FORMAT_R16G16B16A16_SINT:
1262     case VK_FORMAT_R16G16_SINT:
1263     case VK_FORMAT_R16_SINT:
1264     case VK_FORMAT_R8G8B8A8_SINT:
1265     case VK_FORMAT_R8G8_SINT:
1266     case VK_FORMAT_R8_SINT:
1267     case VK_FORMAT_R32G32B32A32_UINT:
1268     case VK_FORMAT_R32G32_UINT:
1269     case VK_FORMAT_R32_UINT:
1270     case VK_FORMAT_R16G16B16A16_UINT:
1271     case VK_FORMAT_R16G16_UINT:
1272     case VK_FORMAT_R16_UINT:
1273     case VK_FORMAT_A2B10G10R10_UINT_PACK32:
1274     case VK_FORMAT_R8G8B8A8_UINT:
1275     case VK_FORMAT_R8G8_UINT:
1276     case VK_FORMAT_R8_UINT:
1277     case VK_FORMAT_R64_SINT:
1278     case VK_FORMAT_R64_UINT:
1279         // These formats can be explicitly expressed in SPIR-V.
1280         return true;
1281     default:
1282         return false;
1283     }
1284 }
1285 
isExtendedStorageFormat(VkFormat format)1286 static bool isExtendedStorageFormat(VkFormat format)
1287 {
1288     switch (format)
1289     {
1290     case VK_FORMAT_R8G8B8A8_UNORM:
1291     case VK_FORMAT_R8G8B8A8_SNORM:
1292     case VK_FORMAT_R8G8B8A8_UINT:
1293     case VK_FORMAT_R8G8B8A8_SINT:
1294     case VK_FORMAT_R32_UINT:
1295     case VK_FORMAT_R32_SINT:
1296     case VK_FORMAT_R32_SFLOAT:
1297     case VK_FORMAT_R32G32_UINT:
1298     case VK_FORMAT_R32G32_SINT:
1299     case VK_FORMAT_R32G32_SFLOAT:
1300     case VK_FORMAT_R32G32B32A32_UINT:
1301     case VK_FORMAT_R32G32B32A32_SINT:
1302     case VK_FORMAT_R32G32B32A32_SFLOAT:
1303     case VK_FORMAT_R16G16B16A16_UINT:
1304     case VK_FORMAT_R16G16B16A16_SINT:
1305     case VK_FORMAT_R16G16B16A16_SFLOAT:
1306     case VK_FORMAT_R16G16_SFLOAT:
1307     case VK_FORMAT_B10G11R11_UFLOAT_PACK32:
1308     case VK_FORMAT_R16_SFLOAT:
1309     case VK_FORMAT_R16G16B16A16_UNORM:
1310     case VK_FORMAT_A2B10G10R10_UNORM_PACK32:
1311     case VK_FORMAT_R16G16_UNORM:
1312     case VK_FORMAT_R8G8_UNORM:
1313     case VK_FORMAT_R16_UNORM:
1314     case VK_FORMAT_R8_UNORM:
1315     case VK_FORMAT_R16G16B16A16_SNORM:
1316     case VK_FORMAT_R16G16_SNORM:
1317     case VK_FORMAT_R8G8_SNORM:
1318     case VK_FORMAT_R16_SNORM:
1319     case VK_FORMAT_R8_SNORM:
1320     case VK_FORMAT_R16G16_SINT:
1321     case VK_FORMAT_R8G8_SINT:
1322     case VK_FORMAT_R16_SINT:
1323     case VK_FORMAT_R8_SINT:
1324     case VK_FORMAT_A2B10G10R10_UINT_PACK32:
1325     case VK_FORMAT_R16G16_UINT:
1326     case VK_FORMAT_R8G8_UINT:
1327     case VK_FORMAT_R16_UINT:
1328     case VK_FORMAT_R8_UINT:
1329         return true;
1330     default:
1331         return false;
1332     }
1333 }
1334 
isDepthFormat(VkFormat format)1335 static bool isDepthFormat(VkFormat format)
1336 {
1337     switch (format)
1338     {
1339     case VK_FORMAT_D16_UNORM:
1340     case VK_FORMAT_X8_D24_UNORM_PACK32:
1341     case VK_FORMAT_D32_SFLOAT:
1342     case VK_FORMAT_D16_UNORM_S8_UINT:
1343     case VK_FORMAT_D24_UNORM_S8_UINT:
1344     case VK_FORMAT_D32_SFLOAT_S8_UINT:
1345         return true;
1346     default:
1347         return false;
1348     }
1349 }
1350 
getRequiredFormatProperties(const vk::VkFormat & format) const1351 vk::VkFormatProperties3 Context::getRequiredFormatProperties(const vk::VkFormat &format) const
1352 {
1353     vk::VkFormatProperties3 p;
1354     p.sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_3;
1355     p.pNext = DE_NULL;
1356 
1357     vk::VkFormatProperties properties;
1358     getInstanceInterface().getPhysicalDeviceFormatProperties(getPhysicalDevice(), format, &properties);
1359     p.linearTilingFeatures  = properties.linearTilingFeatures;
1360     p.optimalTilingFeatures = properties.optimalTilingFeatures;
1361     p.bufferFeatures        = properties.bufferFeatures;
1362 
1363     const vk::VkPhysicalDeviceFeatures &featuresAvailable = getDeviceFeatures();
1364     if (isExtendedStorageFormat(format) && featuresAvailable.shaderStorageImageReadWithoutFormat)
1365     {
1366         if (p.linearTilingFeatures & VK_FORMAT_FEATURE_2_STORAGE_IMAGE_BIT_KHR)
1367             p.linearTilingFeatures |= VK_FORMAT_FEATURE_2_STORAGE_READ_WITHOUT_FORMAT_BIT_KHR;
1368         if (p.optimalTilingFeatures & VK_FORMAT_FEATURE_2_STORAGE_IMAGE_BIT_KHR)
1369             p.optimalTilingFeatures |= VK_FORMAT_FEATURE_2_STORAGE_READ_WITHOUT_FORMAT_BIT_KHR;
1370     }
1371     if (isExtendedStorageFormat(format) && featuresAvailable.shaderStorageImageWriteWithoutFormat)
1372     {
1373         if (p.linearTilingFeatures & VK_FORMAT_FEATURE_2_STORAGE_IMAGE_BIT_KHR)
1374             p.linearTilingFeatures |= VK_FORMAT_FEATURE_2_STORAGE_WRITE_WITHOUT_FORMAT_BIT_KHR;
1375         if (p.optimalTilingFeatures & VK_FORMAT_FEATURE_2_STORAGE_IMAGE_BIT_KHR)
1376             p.optimalTilingFeatures |= VK_FORMAT_FEATURE_2_STORAGE_WRITE_WITHOUT_FORMAT_BIT_KHR;
1377     }
1378     // If an implementation exposes storage image/buffer feature on formats not in the SPIR-V compatibility table,
1379     // the implementation must at least expose one of the WITHOUT_FORMAT (either READ or WRITE) storage features.
1380     if (!isSpirvCompatibleFormat(format))
1381     {
1382         if ((p.linearTilingFeatures & VK_FORMAT_FEATURE_2_STORAGE_READ_WITHOUT_FORMAT_BIT_KHR) ||
1383             (p.linearTilingFeatures & VK_FORMAT_FEATURE_2_STORAGE_WRITE_WITHOUT_FORMAT_BIT_KHR))
1384         {
1385             p.linearTilingFeatures |= VK_FORMAT_FEATURE_2_STORAGE_IMAGE_BIT_KHR;
1386         }
1387         if ((p.optimalTilingFeatures & VK_FORMAT_FEATURE_2_STORAGE_READ_WITHOUT_FORMAT_BIT_KHR) ||
1388             (p.optimalTilingFeatures & VK_FORMAT_FEATURE_2_STORAGE_WRITE_WITHOUT_FORMAT_BIT_KHR))
1389         {
1390             p.optimalTilingFeatures |= VK_FORMAT_FEATURE_2_STORAGE_IMAGE_BIT_KHR;
1391         }
1392         if ((p.bufferFeatures & VK_FORMAT_FEATURE_2_STORAGE_READ_WITHOUT_FORMAT_BIT_KHR) ||
1393             (p.bufferFeatures & VK_FORMAT_FEATURE_2_STORAGE_WRITE_WITHOUT_FORMAT_BIT_KHR))
1394         {
1395             p.bufferFeatures |= VK_FORMAT_FEATURE_2_STORAGE_TEXEL_BUFFER_BIT_KHR;
1396         }
1397     }
1398     if (isDepthFormat(format) && (p.linearTilingFeatures & (VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_BIT_KHR)))
1399         p.linearTilingFeatures |= VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_DEPTH_COMPARISON_BIT_KHR;
1400     if (isDepthFormat(format) && (p.optimalTilingFeatures & (VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_BIT_KHR)))
1401         p.optimalTilingFeatures |= VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_DEPTH_COMPARISON_BIT_KHR;
1402 
1403     return p;
1404 }
1405 
getFormatProperties(const vk::VkFormat & format) const1406 vk::VkFormatProperties3 Context::getFormatProperties(const vk::VkFormat &format) const
1407 {
1408     if (isDeviceFunctionalitySupported("VK_KHR_format_feature_flags2"))
1409     {
1410         vk::VkFormatProperties3 p;
1411         p.sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_3;
1412         p.pNext = DE_NULL;
1413 
1414         vk::VkFormatProperties2 properties;
1415         properties.sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2;
1416         properties.pNext = &p;
1417 
1418         getInstanceInterface().getPhysicalDeviceFormatProperties2(getPhysicalDevice(), format, &properties);
1419         return p;
1420     }
1421     else
1422         return Context::getRequiredFormatProperties(format);
1423 }
1424 
1425 #endif // CTS_USES_VULKANSC
1426 
getInstanceProcAddr()1427 void *Context::getInstanceProcAddr()
1428 {
1429     return (void *)m_platformInterface.getGetInstanceProcAddr();
1430 }
1431 
isBufferDeviceAddressSupported(void) const1432 bool Context::isBufferDeviceAddressSupported(void) const
1433 {
1434     return isDeviceFunctionalitySupported("VK_KHR_buffer_device_address") ||
1435            isDeviceFunctionalitySupported("VK_EXT_buffer_device_address");
1436 }
1437 
1438 #ifndef CTS_USES_VULKANSC
1439 
hasDebugReportRecorder() const1440 bool Context::hasDebugReportRecorder() const
1441 {
1442     return m_device->hasDebugReportRecorder();
1443 }
1444 
getDebugReportRecorder() const1445 vk::DebugReportRecorder &Context::getDebugReportRecorder() const
1446 {
1447     return m_device->getDebugReportRecorder();
1448 }
1449 
1450 #endif // CTS_USES_VULKANSC
1451 
resetCommandPoolForVKSC(const VkDevice device,const VkCommandPool commandPool)1452 void Context::resetCommandPoolForVKSC(const VkDevice device, const VkCommandPool commandPool)
1453 {
1454 #ifdef CTS_USES_VULKANSC
1455     if (getDeviceVulkanSC10Properties().commandPoolResetCommandBuffer == VK_FALSE)
1456     {
1457         const DeviceInterface &vk = getDeviceInterface();
1458         VK_CHECK(vk.resetCommandPool(device, commandPool, 0u));
1459     }
1460 #else
1461     DE_UNREF(device);
1462     DE_UNREF(commandPool);
1463 #endif
1464 }
1465 
getContextCommonData()1466 ContextCommonData Context::getContextCommonData()
1467 {
1468     return ContextCommonData{getInstanceInterface(), getDevice(),           getDeviceInterface(),
1469                              getPhysicalDevice(),    getDefaultAllocator(), getUniversalQueueFamilyIndex(),
1470                              getUniversalQueue()};
1471 }
1472 
1473 #ifdef CTS_USES_VULKANSC
1474 std::vector<VkFaultData> Context::m_faultData;
1475 std::mutex Context::m_faultDataMutex;
1476 
faultCallbackFunction(VkBool32 unrecordedFaults,uint32_t faultCount,const VkFaultData * pFaults)1477 void Context::faultCallbackFunction(VkBool32 unrecordedFaults, uint32_t faultCount, const VkFaultData *pFaults)
1478 {
1479     DE_UNREF(unrecordedFaults);
1480     std::lock_guard<std::mutex> lock(m_faultDataMutex);
1481 
1482     // Append new faults to the vector
1483     for (uint32_t i = 0; i < faultCount; ++i)
1484     {
1485         VkFaultData faultData = pFaults[i];
1486         faultData.pNext       = DE_NULL;
1487 
1488         m_faultData.push_back(faultData);
1489     }
1490 }
1491 #endif // CTS_USES_VULKANSC
1492 
1493 // TestCase
1494 
initPrograms(SourceCollections &) const1495 void TestCase::initPrograms(SourceCollections &) const
1496 {
1497 }
1498 
checkSupport(Context &) const1499 void TestCase::checkSupport(Context &) const
1500 {
1501 }
1502 
delayedInit(void)1503 void TestCase::delayedInit(void)
1504 {
1505 }
1506 
1507 #ifndef CTS_USES_VULKANSC
1508 
collectAndReportDebugMessages(vk::DebugReportRecorder & debugReportRecorder,Context & context)1509 void collectAndReportDebugMessages(vk::DebugReportRecorder &debugReportRecorder, Context &context)
1510 {
1511     using DebugMessages = vk::DebugReportRecorder::MessageList;
1512 
1513     const DebugMessages &messages = debugReportRecorder.getMessages();
1514     tcu::TestLog &log             = context.getTestContext().getLog();
1515 
1516     if (messages.size() > 0)
1517     {
1518         const tcu::ScopedLogSection section(log, "DebugMessages", "Debug Messages");
1519         int numErrors = 0;
1520 
1521         for (const auto &msg : messages)
1522         {
1523             if (msg.shouldBeLogged())
1524                 log << tcu::TestLog::Message << msg << tcu::TestLog::EndMessage;
1525 
1526             if (msg.isError())
1527                 numErrors += 1;
1528         }
1529 
1530         debugReportRecorder.clearMessages();
1531 
1532         if (numErrors > 0)
1533         {
1534             string errorMsg = de::toString(numErrors) + " API usage errors found";
1535             context.resultSetOnValidation(true);
1536             context.getTestContext().setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, errorMsg.c_str());
1537         }
1538     }
1539 }
1540 
1541 #endif // CTS_USES_VULKANSC
1542 
1543 } // namespace vkt
1544