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