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