xref: /aosp_15_r20/external/deqp/external/vulkancts/framework/vulkan/vkQueryUtil.cpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
1 /*-------------------------------------------------------------------------
2  * Vulkan CTS Framework
3  * --------------------
4  *
5  * Copyright (c) 2015 Google Inc.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  *//*!
20  * \file
21  * \brief Vulkan query utilities.
22  *//*--------------------------------------------------------------------*/
23 
24 #include "vkQueryUtil.hpp"
25 #include "vkApiVersion.hpp"
26 
27 #include "deMemory.h"
28 #include "deString.h"
29 #include "deSTLUtil.hpp"
30 
31 #include <vector>
32 #include <sstream>
33 #include <memory>
34 #include <map>
35 
36 namespace vk
37 {
38 
39 using std::vector;
40 
41 namespace
42 {
43 
44 #include "vkSupportedExtensions.inl"
45 
46 }
47 
getCoreInstanceExtensions(uint32_t apiVersion,vector<const char * > & dst)48 void getCoreInstanceExtensions(uint32_t apiVersion, vector<const char *> &dst)
49 {
50     getCoreInstanceExtensionsImpl(apiVersion, dst);
51 }
52 
getCoreDeviceExtensions(uint32_t apiVersion,vector<const char * > & dst)53 void getCoreDeviceExtensions(uint32_t apiVersion, vector<const char *> &dst)
54 {
55     getCoreDeviceExtensionsImpl(apiVersion, dst);
56 }
57 
isCoreInstanceExtension(const uint32_t apiVersion,const std::string & extension)58 bool isCoreInstanceExtension(const uint32_t apiVersion, const std::string &extension)
59 {
60     vector<const char *> coreExtensions;
61     getCoreInstanceExtensions(apiVersion, coreExtensions);
62     if (de::contains(coreExtensions.begin(), coreExtensions.end(), extension))
63         return true;
64 
65     return false;
66 }
67 
isCoreDeviceExtension(const uint32_t apiVersion,const std::string & extension)68 bool isCoreDeviceExtension(const uint32_t apiVersion, const std::string &extension)
69 {
70     vector<const char *> coreExtensions;
71     getCoreDeviceExtensions(apiVersion, coreExtensions);
72     if (de::contains(coreExtensions.begin(), coreExtensions.end(), extension))
73         return true;
74 
75     return false;
76 }
77 
enumeratePhysicalDevices(const InstanceInterface & vk,VkInstance instance)78 vector<VkPhysicalDevice> enumeratePhysicalDevices(const InstanceInterface &vk, VkInstance instance)
79 {
80     uint32_t numDevices = 0;
81     vector<VkPhysicalDevice> devices;
82 
83     VK_CHECK(vk.enumeratePhysicalDevices(instance, &numDevices, DE_NULL));
84 
85     if (numDevices > 0)
86     {
87         devices.resize(numDevices);
88         VK_CHECK(vk.enumeratePhysicalDevices(instance, &numDevices, &devices[0]));
89 
90         if ((size_t)numDevices != devices.size())
91             TCU_FAIL("Returned device count changed between queries");
92     }
93 
94     return devices;
95 }
96 
enumeratePhysicalDeviceGroups(const InstanceInterface & vk,VkInstance instance)97 vector<VkPhysicalDeviceGroupProperties> enumeratePhysicalDeviceGroups(const InstanceInterface &vk, VkInstance instance)
98 {
99     uint32_t numDeviceGroups = 0;
100     vector<VkPhysicalDeviceGroupProperties> properties;
101 
102     VK_CHECK(vk.enumeratePhysicalDeviceGroups(instance, &numDeviceGroups, DE_NULL));
103 
104     if (numDeviceGroups > 0)
105     {
106         properties.resize(numDeviceGroups, initVulkanStructure());
107         VK_CHECK(vk.enumeratePhysicalDeviceGroups(instance, &numDeviceGroups, &properties[0]));
108 
109         if ((size_t)numDeviceGroups != properties.size())
110             TCU_FAIL("Returned device group count changed between queries");
111     }
112     return properties;
113 }
114 
getPhysicalDeviceQueueFamilyProperties(const InstanceInterface & vk,VkPhysicalDevice physicalDevice)115 vector<VkQueueFamilyProperties> getPhysicalDeviceQueueFamilyProperties(const InstanceInterface &vk,
116                                                                        VkPhysicalDevice physicalDevice)
117 {
118     uint32_t numQueues = 0;
119     vector<VkQueueFamilyProperties> properties;
120 
121     vk.getPhysicalDeviceQueueFamilyProperties(physicalDevice, &numQueues, DE_NULL);
122 
123     if (numQueues > 0)
124     {
125         properties.resize(numQueues);
126         vk.getPhysicalDeviceQueueFamilyProperties(physicalDevice, &numQueues, &properties[0]);
127 
128         if ((size_t)numQueues != properties.size())
129             TCU_FAIL("Returned queue family count changes between queries");
130     }
131 
132     return properties;
133 }
134 
getPhysicalDeviceFeatures(const InstanceInterface & vk,VkPhysicalDevice physicalDevice)135 VkPhysicalDeviceFeatures getPhysicalDeviceFeatures(const InstanceInterface &vk, VkPhysicalDevice physicalDevice)
136 {
137     VkPhysicalDeviceFeatures features;
138 
139     deMemset(&features, 0, sizeof(features));
140 
141     vk.getPhysicalDeviceFeatures(physicalDevice, &features);
142     return features;
143 }
144 
getPhysicalDeviceFeatures2(const InstanceInterface & vk,VkPhysicalDevice physicalDevice)145 VkPhysicalDeviceFeatures2 getPhysicalDeviceFeatures2(const InstanceInterface &vk, VkPhysicalDevice physicalDevice)
146 {
147     VkPhysicalDeviceFeatures2 features;
148 
149     deMemset(&features, 0, sizeof(features));
150     features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
151 
152     vk.getPhysicalDeviceFeatures2(physicalDevice, &features);
153     return features;
154 }
155 
getPhysicalDeviceVulkan11Features(const InstanceInterface & vk,VkPhysicalDevice physicalDevice)156 VkPhysicalDeviceVulkan11Features getPhysicalDeviceVulkan11Features(const InstanceInterface &vk,
157                                                                    VkPhysicalDevice physicalDevice)
158 {
159     VkPhysicalDeviceFeatures2 features;
160     VkPhysicalDeviceVulkan11Features vulkan_11_features;
161 
162     deMemset(&features, 0, sizeof(features));
163     features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
164 
165     deMemset(&vulkan_11_features, 0, sizeof(vulkan_11_features));
166     vulkan_11_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES;
167 
168     features.pNext = &vulkan_11_features;
169 
170     vk.getPhysicalDeviceFeatures2(physicalDevice, &features);
171     return vulkan_11_features;
172 }
173 
getPhysicalDeviceVulkan12Features(const InstanceInterface & vk,VkPhysicalDevice physicalDevice)174 VkPhysicalDeviceVulkan12Features getPhysicalDeviceVulkan12Features(const InstanceInterface &vk,
175                                                                    VkPhysicalDevice physicalDevice)
176 {
177     VkPhysicalDeviceFeatures2 features;
178     VkPhysicalDeviceVulkan12Features vulkan_12_features;
179 
180     deMemset(&features, 0, sizeof(features));
181     features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
182 
183     deMemset(&vulkan_12_features, 0, sizeof(vulkan_12_features));
184     vulkan_12_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES;
185 
186     features.pNext = &vulkan_12_features;
187 
188     vk.getPhysicalDeviceFeatures2(physicalDevice, &features);
189     return vulkan_12_features;
190 }
191 
getPhysicalDeviceVulkan11Properties(const InstanceInterface & vk,VkPhysicalDevice physicalDevice)192 VkPhysicalDeviceVulkan11Properties getPhysicalDeviceVulkan11Properties(const InstanceInterface &vk,
193                                                                        VkPhysicalDevice physicalDevice)
194 {
195     VkPhysicalDeviceVulkan11Properties vulkan11properties = initVulkanStructure();
196     VkPhysicalDeviceProperties2 properties                = initVulkanStructure(&vulkan11properties);
197 
198     vk.getPhysicalDeviceProperties2(physicalDevice, &properties);
199 
200     return vulkan11properties;
201 }
202 
getPhysicalDeviceVulkan12Properties(const InstanceInterface & vk,VkPhysicalDevice physicalDevice)203 VkPhysicalDeviceVulkan12Properties getPhysicalDeviceVulkan12Properties(const InstanceInterface &vk,
204                                                                        VkPhysicalDevice physicalDevice)
205 {
206     VkPhysicalDeviceVulkan12Properties vulkan12properties = initVulkanStructure();
207     VkPhysicalDeviceProperties2 properties                = initVulkanStructure(&vulkan12properties);
208 
209     vk.getPhysicalDeviceProperties2(physicalDevice, &properties);
210 
211     return vulkan12properties;
212 }
213 
214 #ifdef CTS_USES_VULKANSC
getPhysicalDeviceVulkanSC10Features(const InstanceInterface & vk,VkPhysicalDevice physicalDevice)215 VkPhysicalDeviceVulkanSC10Features getPhysicalDeviceVulkanSC10Features(const InstanceInterface &vk,
216                                                                        VkPhysicalDevice physicalDevice)
217 {
218     VkPhysicalDeviceFeatures2 features;
219     VkPhysicalDeviceVulkanSC10Features vulkanSC10Features;
220 
221     deMemset(&features, 0, sizeof(features));
222     features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
223 
224     deMemset(&vulkanSC10Features, 0, sizeof(vulkanSC10Features));
225     vulkanSC10Features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_SC_1_0_FEATURES;
226 
227     features.pNext = &vulkanSC10Features;
228 
229     vk.getPhysicalDeviceFeatures2(physicalDevice, &features);
230     return vulkanSC10Features;
231 }
232 
getPhysicalDeviceVulkanSC10Properties(const InstanceInterface & vk,VkPhysicalDevice physicalDevice)233 VkPhysicalDeviceVulkanSC10Properties getPhysicalDeviceVulkanSC10Properties(const InstanceInterface &vk,
234                                                                            VkPhysicalDevice physicalDevice)
235 {
236     VkPhysicalDeviceVulkanSC10Properties vulkanSC10properties = initVulkanStructure();
237     VkPhysicalDeviceProperties2 properties                    = initVulkanStructure(&vulkanSC10properties);
238 
239     vk.getPhysicalDeviceProperties2(physicalDevice, &properties);
240 
241     return vulkanSC10properties;
242 }
243 #endif // CTS_USES_VULKANSC
244 
getPhysicalDeviceProperties(const InstanceInterface & vk,VkPhysicalDevice physicalDevice)245 VkPhysicalDeviceProperties getPhysicalDeviceProperties(const InstanceInterface &vk, VkPhysicalDevice physicalDevice)
246 {
247     VkPhysicalDeviceProperties properties;
248 
249     deMemset(&properties, 0, sizeof(properties));
250 
251     vk.getPhysicalDeviceProperties(physicalDevice, &properties);
252     return properties;
253 }
254 
getPhysicalDeviceMemoryProperties(const InstanceInterface & vk,VkPhysicalDevice physicalDevice)255 VkPhysicalDeviceMemoryProperties getPhysicalDeviceMemoryProperties(const InstanceInterface &vk,
256                                                                    VkPhysicalDevice physicalDevice)
257 {
258     VkPhysicalDeviceMemoryProperties properties;
259 
260     deMemset(&properties, 0, sizeof(properties));
261 
262     vk.getPhysicalDeviceMemoryProperties(physicalDevice, &properties);
263 
264     if (properties.memoryTypeCount > VK_MAX_MEMORY_TYPES)
265     {
266         std::ostringstream msg;
267         msg << "Invalid memoryTypeCount in VkPhysicalDeviceMemoryProperties (got " << properties.memoryTypeCount
268             << ", max " << VK_MAX_MEMORY_TYPES << ")";
269         TCU_FAIL(msg.str());
270     }
271 
272     if (properties.memoryHeapCount > VK_MAX_MEMORY_HEAPS)
273     {
274         std::ostringstream msg;
275         msg << "Invalid memoryHeapCount in VkPhysicalDeviceMemoryProperties (got " << properties.memoryHeapCount
276             << ", max " << VK_MAX_MEMORY_HEAPS << ")";
277         TCU_FAIL(msg.str());
278     }
279 
280     return properties;
281 }
282 
getPhysicalDeviceFormatProperties(const InstanceInterface & vk,VkPhysicalDevice physicalDevice,VkFormat format)283 VkFormatProperties getPhysicalDeviceFormatProperties(const InstanceInterface &vk, VkPhysicalDevice physicalDevice,
284                                                      VkFormat format)
285 {
286     VkFormatProperties properties;
287 
288     deMemset(&properties, 0, sizeof(properties));
289 
290     vk.getPhysicalDeviceFormatProperties(physicalDevice, format, &properties);
291     return properties;
292 }
293 
getPhysicalDeviceImageFormatProperties(const InstanceInterface & vk,VkPhysicalDevice physicalDevice,VkFormat format,VkImageType type,VkImageTiling tiling,VkImageUsageFlags usage,VkImageCreateFlags flags)294 VkImageFormatProperties getPhysicalDeviceImageFormatProperties(const InstanceInterface &vk,
295                                                                VkPhysicalDevice physicalDevice, VkFormat format,
296                                                                VkImageType type, VkImageTiling tiling,
297                                                                VkImageUsageFlags usage, VkImageCreateFlags flags)
298 {
299     VkImageFormatProperties properties;
300 
301     deMemset(&properties, 0, sizeof(properties));
302 
303     VK_CHECK(
304         vk.getPhysicalDeviceImageFormatProperties(physicalDevice, format, type, tiling, usage, flags, &properties));
305     return properties;
306 }
307 
308 #ifndef CTS_USES_VULKANSC
getPhysicalDeviceSparseImageFormatProperties(const InstanceInterface & vk,VkPhysicalDevice physicalDevice,VkFormat format,VkImageType type,VkSampleCountFlagBits samples,VkImageUsageFlags usage,VkImageTiling tiling)309 std::vector<VkSparseImageFormatProperties> getPhysicalDeviceSparseImageFormatProperties(
310     const InstanceInterface &vk, VkPhysicalDevice physicalDevice, VkFormat format, VkImageType type,
311     VkSampleCountFlagBits samples, VkImageUsageFlags usage, VkImageTiling tiling)
312 {
313     uint32_t numProp = 0;
314     vector<VkSparseImageFormatProperties> properties;
315 
316     vk.getPhysicalDeviceSparseImageFormatProperties(physicalDevice, format, type, samples, usage, tiling, &numProp,
317                                                     DE_NULL);
318 
319     if (numProp > 0)
320     {
321         properties.resize(numProp);
322         vk.getPhysicalDeviceSparseImageFormatProperties(physicalDevice, format, type, samples, usage, tiling, &numProp,
323                                                         &properties[0]);
324 
325         if ((size_t)numProp != properties.size())
326             TCU_FAIL("Returned sparse image properties count changes between queries");
327     }
328 
329     return properties;
330 }
331 
getImageSparseMemoryRequirements(const DeviceInterface & vk,VkDevice device,VkImage image)332 std::vector<VkSparseImageMemoryRequirements> getImageSparseMemoryRequirements(const DeviceInterface &vk,
333                                                                               VkDevice device, VkImage image)
334 {
335     uint32_t requirementsCount = 0;
336     vector<VkSparseImageMemoryRequirements> requirements;
337 
338     vk.getImageSparseMemoryRequirements(device, image, &requirementsCount, DE_NULL);
339 
340     if (requirementsCount > 0)
341     {
342         requirements.resize(requirementsCount);
343         vk.getImageSparseMemoryRequirements(device, image, &requirementsCount, &requirements[0]);
344 
345         if ((size_t)requirementsCount != requirements.size())
346             TCU_FAIL("Returned sparse image memory requirements count changes between queries");
347     }
348 
349     return requirements;
350 }
351 
getDeviceImageSparseMemoryRequirements(const DeviceInterface & vk,VkDevice device,const VkImageCreateInfo & imageCreateInfo,VkImageAspectFlagBits planeAspect)352 std::vector<vk::VkSparseImageMemoryRequirements> getDeviceImageSparseMemoryRequirements(
353     const DeviceInterface &vk, VkDevice device, const VkImageCreateInfo &imageCreateInfo,
354     VkImageAspectFlagBits planeAspect)
355 {
356     const VkDeviceImageMemoryRequirements info{VK_STRUCTURE_TYPE_DEVICE_IMAGE_MEMORY_REQUIREMENTS, nullptr,
357                                                &imageCreateInfo, planeAspect};
358     std::vector<vk::VkSparseImageMemoryRequirements2> requirements;
359     uint32_t count = 0;
360 
361     vk.getDeviceImageSparseMemoryRequirements(device, &info, &count, DE_NULL);
362 
363     if (count > 0)
364     {
365         requirements.resize(count);
366         for (uint32_t i = 0; i < count; ++i)
367             requirements[i] = vk::initVulkanStructure();
368         vk.getDeviceImageSparseMemoryRequirements(device, &info, &count, requirements.data());
369 
370         if ((size_t)count != requirements.size())
371             TCU_FAIL("Returned sparse image memory requirements count changes between queries");
372     }
373 
374     std::vector<vk::VkSparseImageMemoryRequirements> result(requirements.size());
375     std::transform(requirements.begin(), requirements.end(), result.begin(),
376                    [](const VkSparseImageMemoryRequirements2 &item) { return item.memoryRequirements; });
377 
378     return result;
379 }
380 #endif // CTS_USES_VULKANSC
381 
getBufferMemoryRequirements(const DeviceInterface & vk,VkDevice device,VkBuffer buffer)382 VkMemoryRequirements getBufferMemoryRequirements(const DeviceInterface &vk, VkDevice device, VkBuffer buffer)
383 {
384     VkMemoryRequirements req;
385     vk.getBufferMemoryRequirements(device, buffer, &req);
386     return req;
387 }
388 
getImageMemoryRequirements(const DeviceInterface & vk,VkDevice device,VkImage image)389 VkMemoryRequirements getImageMemoryRequirements(const DeviceInterface &vk, VkDevice device, VkImage image)
390 {
391     VkMemoryRequirements req;
392     vk.getImageMemoryRequirements(device, image, &req);
393     return req;
394 }
395 
getImagePlaneMemoryRequirements(const DeviceInterface & vkd,VkDevice device,VkImage image,VkImageAspectFlagBits planeAspect)396 VkMemoryRequirements getImagePlaneMemoryRequirements(const DeviceInterface &vkd, VkDevice device, VkImage image,
397                                                      VkImageAspectFlagBits planeAspect)
398 {
399     VkImageMemoryRequirementsInfo2 coreInfo;
400     VkImagePlaneMemoryRequirementsInfo planeInfo;
401     VkMemoryRequirements2 reqs;
402 
403     deMemset(&coreInfo, 0, sizeof(coreInfo));
404     deMemset(&planeInfo, 0, sizeof(planeInfo));
405     deMemset(&reqs, 0, sizeof(reqs));
406 
407     coreInfo.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2;
408     coreInfo.pNext = &planeInfo;
409     coreInfo.image = image;
410 
411     planeInfo.sType       = VK_STRUCTURE_TYPE_IMAGE_PLANE_MEMORY_REQUIREMENTS_INFO;
412     planeInfo.planeAspect = planeAspect;
413 
414     reqs.sType = VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2;
415 
416     vkd.getImageMemoryRequirements2(device, &coreInfo, &reqs);
417 
418     return reqs.memoryRequirements;
419 }
420 
enumerateInstanceLayerProperties(const PlatformInterface & vkp)421 vector<VkLayerProperties> enumerateInstanceLayerProperties(const PlatformInterface &vkp)
422 {
423     vector<VkLayerProperties> properties;
424     uint32_t numLayers = 0;
425 
426     VK_CHECK(vkp.enumerateInstanceLayerProperties(&numLayers, DE_NULL));
427 
428     if (numLayers > 0)
429     {
430         properties.resize(numLayers);
431         VK_CHECK(vkp.enumerateInstanceLayerProperties(&numLayers, &properties[0]));
432         TCU_CHECK((size_t)numLayers == properties.size());
433     }
434 
435     return properties;
436 }
437 
enumerateInstanceExtensionProperties(const PlatformInterface & vkp,const char * layerName)438 vector<VkExtensionProperties> enumerateInstanceExtensionProperties(const PlatformInterface &vkp, const char *layerName)
439 {
440     vector<VkExtensionProperties> properties;
441     uint32_t numExtensions = 0;
442 
443     VK_CHECK(vkp.enumerateInstanceExtensionProperties(layerName, &numExtensions, DE_NULL));
444 
445     if (numExtensions > 0)
446     {
447         properties.resize(numExtensions);
448         VK_CHECK(vkp.enumerateInstanceExtensionProperties(layerName, &numExtensions, &properties[0]));
449         TCU_CHECK((size_t)numExtensions == properties.size());
450     }
451 
452     return properties;
453 }
454 
enumerateDeviceLayerProperties(const InstanceInterface & vki,VkPhysicalDevice physicalDevice)455 vector<VkLayerProperties> enumerateDeviceLayerProperties(const InstanceInterface &vki, VkPhysicalDevice physicalDevice)
456 {
457     vector<VkLayerProperties> properties;
458     uint32_t numLayers = 0;
459 
460     VK_CHECK(vki.enumerateDeviceLayerProperties(physicalDevice, &numLayers, DE_NULL));
461 
462     if (numLayers > 0)
463     {
464         properties.resize(numLayers);
465         VK_CHECK(vki.enumerateDeviceLayerProperties(physicalDevice, &numLayers, &properties[0]));
466         TCU_CHECK((size_t)numLayers == properties.size());
467     }
468 
469     return properties;
470 }
471 
enumerateDeviceExtensionProperties(const InstanceInterface & vki,VkPhysicalDevice physicalDevice,const char * layerName)472 vector<VkExtensionProperties> enumerateDeviceExtensionProperties(const InstanceInterface &vki,
473                                                                  VkPhysicalDevice physicalDevice, const char *layerName)
474 {
475     vector<VkExtensionProperties> properties;
476     uint32_t numExtensions = 0;
477 
478     VK_CHECK(vki.enumerateDeviceExtensionProperties(physicalDevice, layerName, &numExtensions, DE_NULL));
479 
480     if (numExtensions > 0)
481     {
482         properties.resize(numExtensions);
483         VK_CHECK(vki.enumerateDeviceExtensionProperties(physicalDevice, layerName, &numExtensions, &properties[0]));
484         TCU_CHECK((size_t)numExtensions == properties.size());
485     }
486 
487     return properties;
488 }
489 
490 namespace
491 {
492 
493 class ExtensionPropertiesCache
494 {
495 protected:
496     typedef std::pair<const InstanceInterface *, VkPhysicalDevice> key_type;
497     typedef std::unique_ptr<std::vector<VkExtensionProperties>> value_type;
498 
499 public:
ExtensionPropertiesCache()500     ExtensionPropertiesCache()
501     {
502     }
503 
get(const InstanceInterface & vki,VkPhysicalDevice dev)504     const std::vector<VkExtensionProperties> *get(const InstanceInterface &vki, VkPhysicalDevice dev)
505     {
506         const key_type key(&vki, dev);
507         const auto itr = m_cache.find(key);
508         if (itr == m_cache.end())
509             return nullptr;
510         return itr->second.get();
511     }
512 
add(const InstanceInterface & vki,VkPhysicalDevice dev,const std::vector<VkExtensionProperties> & vec)513     void add(const InstanceInterface &vki, VkPhysicalDevice dev, const std::vector<VkExtensionProperties> &vec)
514     {
515         const key_type key(&vki, dev);
516         m_cache[key].reset(new std::vector<VkExtensionProperties>(vec));
517     }
518 
519 protected:
520     std::map<key_type, value_type> m_cache;
521 };
522 
523 } // anonymous namespace
524 
525 // Uses a global cache to avoid copying so many results and obtaining extension lists over and over again.
enumerateCachedDeviceExtensionProperties(const InstanceInterface & vki,VkPhysicalDevice physicalDevice)526 const std::vector<VkExtensionProperties> &enumerateCachedDeviceExtensionProperties(const InstanceInterface &vki,
527                                                                                    VkPhysicalDevice physicalDevice)
528 {
529     // Find extension properties in the cache.
530     static ExtensionPropertiesCache m_extensionPropertiesCache;
531     auto supportedExtensions = m_extensionPropertiesCache.get(vki, physicalDevice);
532 
533     if (!supportedExtensions)
534     {
535         const auto enumeratedExtensions = enumerateDeviceExtensionProperties(vki, physicalDevice, nullptr);
536         m_extensionPropertiesCache.add(vki, physicalDevice, enumeratedExtensions);
537         supportedExtensions = m_extensionPropertiesCache.get(vki, physicalDevice);
538     }
539 
540     return *supportedExtensions;
541 }
542 
isShaderStageSupported(const VkPhysicalDeviceFeatures & deviceFeatures,VkShaderStageFlagBits stage)543 bool isShaderStageSupported(const VkPhysicalDeviceFeatures &deviceFeatures, VkShaderStageFlagBits stage)
544 {
545     if (stage == VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT || stage == VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT)
546         return deviceFeatures.tessellationShader == VK_TRUE;
547     else if (stage == VK_SHADER_STAGE_GEOMETRY_BIT)
548         return deviceFeatures.geometryShader == VK_TRUE;
549     else
550         return true;
551 }
552 
isCompatible(const VkExtensionProperties & extensionProperties,const RequiredExtension & required)553 bool isCompatible(const VkExtensionProperties &extensionProperties, const RequiredExtension &required)
554 {
555     if (required.name != extensionProperties.extensionName)
556         return false;
557 
558     if (required.minVersion && required.minVersion.get() > extensionProperties.specVersion)
559         return false;
560 
561     if (required.maxVersion && required.maxVersion.get() < extensionProperties.specVersion)
562         return false;
563 
564     return true;
565 }
566 
isCompatible(const VkLayerProperties & layerProperties,const RequiredLayer & required)567 bool isCompatible(const VkLayerProperties &layerProperties, const RequiredLayer &required)
568 {
569     if (required.name != layerProperties.layerName)
570         return false;
571 
572     if (required.minSpecVersion && required.minSpecVersion.get() > layerProperties.specVersion)
573         return false;
574 
575     if (required.maxSpecVersion && required.maxSpecVersion.get() < layerProperties.specVersion)
576         return false;
577 
578     if (required.minImplVersion && required.minImplVersion.get() > layerProperties.implementationVersion)
579         return false;
580 
581     if (required.maxImplVersion && required.maxImplVersion.get() < layerProperties.implementationVersion)
582         return false;
583 
584     return true;
585 }
586 
isExtensionStructSupported(const std::vector<VkExtensionProperties> & extensions,const RequiredExtension & required)587 bool isExtensionStructSupported(const std::vector<VkExtensionProperties> &extensions, const RequiredExtension &required)
588 {
589     return isExtensionStructSupported(extensions.begin(), extensions.end(), required);
590 }
591 
isExtensionStructSupported(const vector<std::string> & extensionStrings,const std::string & extensionName)592 bool isExtensionStructSupported(const vector<std::string> &extensionStrings, const std::string &extensionName)
593 {
594     return de::contains(extensionStrings.begin(), extensionStrings.end(), extensionName);
595 }
596 
isInstanceExtensionSupported(const uint32_t instanceVersion,const std::vector<std::string> & extensions,const std::string & required)597 bool isInstanceExtensionSupported(const uint32_t instanceVersion, const std::vector<std::string> &extensions,
598                                   const std::string &required)
599 {
600     // NOTE: this function is only needed in few cases during creation of context,
601     // dont use it, call Context::isInstanceFunctionalitySupported instead
602     if (isCoreInstanceExtension(instanceVersion, required))
603         return true;
604     return de::contains(extensions.begin(), extensions.end(), required);
605 }
606 
isLayerSupported(const std::vector<VkLayerProperties> & layers,const RequiredLayer & required)607 bool isLayerSupported(const std::vector<VkLayerProperties> &layers, const RequiredLayer &required)
608 {
609     return isLayerSupported(layers.begin(), layers.end(), required);
610 }
611 
getDeviceQueue(const DeviceInterface & vkd,VkDevice device,uint32_t queueFamilyIndex,uint32_t queueIndex)612 VkQueue getDeviceQueue(const DeviceInterface &vkd, VkDevice device, uint32_t queueFamilyIndex, uint32_t queueIndex)
613 {
614     VkQueue queue;
615 
616     vkd.getDeviceQueue(device, queueFamilyIndex, queueIndex, &queue);
617 
618     return queue;
619 }
620 
getDeviceQueue2(const DeviceInterface & vkd,VkDevice device,const VkDeviceQueueInfo2 * queueInfo)621 VkQueue getDeviceQueue2(const DeviceInterface &vkd, VkDevice device, const VkDeviceQueueInfo2 *queueInfo)
622 {
623     VkQueue queue;
624 
625     vkd.getDeviceQueue2(device, queueInfo, &queue);
626 
627     return queue;
628 }
629 
findStructureInChain(const void * first,VkStructureType type)630 const void *findStructureInChain(const void *first, VkStructureType type)
631 {
632     struct StructureBase
633     {
634         VkStructureType sType;
635         void *pNext;
636     };
637 
638     const StructureBase *cur = reinterpret_cast<const StructureBase *>(first);
639 
640     while (cur)
641     {
642         if (cur->sType == type)
643             break;
644         else
645             cur = reinterpret_cast<const StructureBase *>(cur->pNext);
646     }
647 
648     return cur;
649 }
650 
findStructureInChain(void * first,VkStructureType type)651 void *findStructureInChain(void *first, VkStructureType type)
652 {
653     return const_cast<void *>(findStructureInChain(const_cast<const void *>(first), type));
654 }
655 
appendStructurePtrToVulkanChain(const void ** chainHead,const void * structurePtr)656 void appendStructurePtrToVulkanChain(const void **chainHead, const void *structurePtr)
657 {
658     struct StructureBase
659     {
660         VkStructureType sType;
661         const void *pNext;
662     };
663 
664     while (*chainHead != DE_NULL)
665     {
666         StructureBase *ptr = (StructureBase *)(*chainHead);
667 
668         chainHead = &(ptr->pNext);
669     }
670 
671     (*chainHead) = structurePtr;
672 }
673 
674 // getStructureType<T> implementations
675 #include "vkGetStructureTypeImpl.inl"
676 
677 } // namespace vk
678