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
33 namespace vk
34 {
35
36 using std::vector;
37
38 namespace
39 {
40
41 #include "vkSupportedExtensions.inl"
42
43 }
44
getCoreInstanceExtensions(deUint32 apiVersion,vector<const char * > & dst)45 void getCoreInstanceExtensions(deUint32 apiVersion, vector<const char*>& dst)
46 {
47 getCoreInstanceExtensionsImpl(apiVersion, dst);
48 }
49
getCoreDeviceExtensions(deUint32 apiVersion,vector<const char * > & dst)50 void getCoreDeviceExtensions(deUint32 apiVersion, vector<const char*>& dst)
51 {
52 getCoreDeviceExtensionsImpl(apiVersion, dst);
53 }
54
isCoreInstanceExtension(const deUint32 apiVersion,const std::string & extension)55 bool isCoreInstanceExtension(const deUint32 apiVersion, const std::string& extension)
56 {
57 vector<const char*> coreExtensions;
58 getCoreInstanceExtensions(apiVersion, coreExtensions);
59 if (de::contains(coreExtensions.begin(), coreExtensions.end(), extension))
60 return true;
61
62 return false;
63 }
64
isCoreDeviceExtension(const deUint32 apiVersion,const std::string & extension)65 bool isCoreDeviceExtension(const deUint32 apiVersion, const std::string& extension)
66 {
67 vector<const char*> coreExtensions;
68 getCoreDeviceExtensions(apiVersion, coreExtensions);
69 if (de::contains(coreExtensions.begin(), coreExtensions.end(), extension))
70 return true;
71
72 return false;
73 }
74
enumeratePhysicalDevices(const InstanceInterface & vk,VkInstance instance)75 vector<VkPhysicalDevice> enumeratePhysicalDevices (const InstanceInterface& vk, VkInstance instance)
76 {
77 deUint32 numDevices = 0;
78 vector<VkPhysicalDevice> devices;
79
80 VK_CHECK(vk.enumeratePhysicalDevices(instance, &numDevices, DE_NULL));
81
82 if (numDevices > 0)
83 {
84 devices.resize(numDevices);
85 VK_CHECK(vk.enumeratePhysicalDevices(instance, &numDevices, &devices[0]));
86
87 if ((size_t)numDevices != devices.size())
88 TCU_FAIL("Returned device count changed between queries");
89 }
90
91 return devices;
92 }
93
enumeratePhysicalDeviceGroups(const InstanceInterface & vk,VkInstance instance)94 vector<VkPhysicalDeviceGroupProperties> enumeratePhysicalDeviceGroups(const InstanceInterface& vk, VkInstance instance)
95 {
96 deUint32 numDeviceGroups = 0;
97 vector<VkPhysicalDeviceGroupProperties> properties;
98
99 VK_CHECK(vk.enumeratePhysicalDeviceGroups(instance, &numDeviceGroups, DE_NULL));
100
101 if (numDeviceGroups > 0)
102 {
103 properties.resize(numDeviceGroups);
104 for (deUint32 i = 0; i < numDeviceGroups; i++)
105 {
106 properties[i].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GROUP_PROPERTIES_KHR;
107 properties[i].pNext = DE_NULL;
108 }
109 VK_CHECK(vk.enumeratePhysicalDeviceGroups(instance, &numDeviceGroups, &properties[0]));
110
111 if ((size_t)numDeviceGroups != properties.size())
112 TCU_FAIL("Returned device group count changed between queries");
113 }
114 return properties;
115 }
116
getPhysicalDeviceQueueFamilyProperties(const InstanceInterface & vk,VkPhysicalDevice physicalDevice)117 vector<VkQueueFamilyProperties> getPhysicalDeviceQueueFamilyProperties (const InstanceInterface& vk, VkPhysicalDevice physicalDevice)
118 {
119 deUint32 numQueues = 0;
120 vector<VkQueueFamilyProperties> properties;
121
122 vk.getPhysicalDeviceQueueFamilyProperties(physicalDevice, &numQueues, DE_NULL);
123
124 if (numQueues > 0)
125 {
126 properties.resize(numQueues);
127 vk.getPhysicalDeviceQueueFamilyProperties(physicalDevice, &numQueues, &properties[0]);
128
129 if ((size_t)numQueues != properties.size())
130 TCU_FAIL("Returned queue family count changes between queries");
131 }
132
133 return properties;
134 }
135
getPhysicalDeviceFeatures(const InstanceInterface & vk,VkPhysicalDevice physicalDevice)136 VkPhysicalDeviceFeatures getPhysicalDeviceFeatures (const InstanceInterface& vk, VkPhysicalDevice physicalDevice)
137 {
138 VkPhysicalDeviceFeatures features;
139
140 deMemset(&features, 0, sizeof(features));
141
142 vk.getPhysicalDeviceFeatures(physicalDevice, &features);
143 return features;
144 }
145
getPhysicalDeviceFeatures2(const InstanceInterface & vk,VkPhysicalDevice physicalDevice)146 VkPhysicalDeviceFeatures2 getPhysicalDeviceFeatures2 (const InstanceInterface& vk, VkPhysicalDevice physicalDevice)
147 {
148 VkPhysicalDeviceFeatures2 features;
149
150 deMemset(&features, 0, sizeof(features));
151 features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
152
153 vk.getPhysicalDeviceFeatures2(physicalDevice, &features);
154 return features;
155 }
156
getPhysicalDeviceProperties(const InstanceInterface & vk,VkPhysicalDevice physicalDevice)157 VkPhysicalDeviceProperties getPhysicalDeviceProperties (const InstanceInterface& vk, VkPhysicalDevice physicalDevice)
158 {
159 VkPhysicalDeviceProperties properties;
160
161 deMemset(&properties, 0, sizeof(properties));
162
163 vk.getPhysicalDeviceProperties(physicalDevice, &properties);
164 return properties;
165 }
166
getPhysicalDeviceMemoryProperties(const InstanceInterface & vk,VkPhysicalDevice physicalDevice)167 VkPhysicalDeviceMemoryProperties getPhysicalDeviceMemoryProperties (const InstanceInterface& vk, VkPhysicalDevice physicalDevice)
168 {
169 VkPhysicalDeviceMemoryProperties properties;
170
171 deMemset(&properties, 0, sizeof(properties));
172
173 vk.getPhysicalDeviceMemoryProperties(physicalDevice, &properties);
174 return properties;
175 }
176
getPhysicalDeviceFormatProperties(const InstanceInterface & vk,VkPhysicalDevice physicalDevice,VkFormat format)177 VkFormatProperties getPhysicalDeviceFormatProperties (const InstanceInterface& vk, VkPhysicalDevice physicalDevice, VkFormat format)
178 {
179 VkFormatProperties properties;
180
181 deMemset(&properties, 0, sizeof(properties));
182
183 vk.getPhysicalDeviceFormatProperties(physicalDevice, format, &properties);
184 return properties;
185 }
186
getPhysicalDeviceImageFormatProperties(const InstanceInterface & vk,VkPhysicalDevice physicalDevice,VkFormat format,VkImageType type,VkImageTiling tiling,VkImageUsageFlags usage,VkImageCreateFlags flags)187 VkImageFormatProperties getPhysicalDeviceImageFormatProperties (const InstanceInterface& vk, VkPhysicalDevice physicalDevice, VkFormat format, VkImageType type, VkImageTiling tiling, VkImageUsageFlags usage, VkImageCreateFlags flags)
188 {
189 VkImageFormatProperties properties;
190
191 deMemset(&properties, 0, sizeof(properties));
192
193 VK_CHECK(vk.getPhysicalDeviceImageFormatProperties(physicalDevice, format, type, tiling, usage, flags, &properties));
194 return properties;
195 }
196
getPhysicalDeviceSparseImageFormatProperties(const InstanceInterface & vk,VkPhysicalDevice physicalDevice,VkFormat format,VkImageType type,VkSampleCountFlagBits samples,VkImageUsageFlags usage,VkImageTiling tiling)197 std::vector<VkSparseImageFormatProperties> getPhysicalDeviceSparseImageFormatProperties(const InstanceInterface& vk, VkPhysicalDevice physicalDevice, VkFormat format, VkImageType type, VkSampleCountFlagBits samples, VkImageUsageFlags usage, VkImageTiling tiling)
198 {
199 deUint32 numProp = 0;
200 vector<VkSparseImageFormatProperties> properties;
201
202 vk.getPhysicalDeviceSparseImageFormatProperties(physicalDevice, format, type, samples, usage, tiling, &numProp, DE_NULL);
203
204 if (numProp > 0)
205 {
206 properties.resize(numProp);
207 vk.getPhysicalDeviceSparseImageFormatProperties(physicalDevice, format, type, samples, usage, tiling, &numProp, &properties[0]);
208
209 if ((size_t)numProp != properties.size())
210 TCU_FAIL("Returned sparse image properties count changes between queries");
211 }
212
213 return properties;
214 }
215
getImageSparseMemoryRequirements(const DeviceInterface & vk,VkDevice device,VkImage image)216 std::vector<VkSparseImageMemoryRequirements> getImageSparseMemoryRequirements(const DeviceInterface& vk, VkDevice device, VkImage image)
217 {
218 deUint32 requirementsCount = 0;
219 vector<VkSparseImageMemoryRequirements> requirements;
220
221 vk.getImageSparseMemoryRequirements(device, image, &requirementsCount, DE_NULL);
222
223 if (requirementsCount > 0)
224 {
225 requirements.resize(requirementsCount);
226 vk.getImageSparseMemoryRequirements(device, image, &requirementsCount, &requirements[0]);
227
228 if ((size_t)requirementsCount != requirements.size())
229 TCU_FAIL("Returned sparse image memory requirements count changes between queries");
230 }
231
232 return requirements;
233 }
234
getBufferMemoryRequirements(const DeviceInterface & vk,VkDevice device,VkBuffer buffer)235 VkMemoryRequirements getBufferMemoryRequirements (const DeviceInterface& vk, VkDevice device, VkBuffer buffer)
236 {
237 VkMemoryRequirements req;
238 vk.getBufferMemoryRequirements(device, buffer, &req);
239 return req;
240 }
241
getImageMemoryRequirements(const DeviceInterface & vk,VkDevice device,VkImage image)242 VkMemoryRequirements getImageMemoryRequirements (const DeviceInterface& vk, VkDevice device, VkImage image)
243 {
244 VkMemoryRequirements req;
245 vk.getImageMemoryRequirements(device, image, &req);
246 return req;
247 }
248
getImagePlaneMemoryRequirements(const DeviceInterface & vkd,VkDevice device,VkImage image,VkImageAspectFlagBits planeAspect)249 VkMemoryRequirements getImagePlaneMemoryRequirements (const DeviceInterface& vkd,
250 VkDevice device,
251 VkImage image,
252 VkImageAspectFlagBits planeAspect)
253 {
254 VkImageMemoryRequirementsInfo2 coreInfo;
255 VkImagePlaneMemoryRequirementsInfo planeInfo;
256 VkMemoryRequirements2 reqs;
257
258 deMemset(&coreInfo, 0, sizeof(coreInfo));
259 deMemset(&planeInfo, 0, sizeof(planeInfo));
260 deMemset(&reqs, 0, sizeof(reqs));
261
262 coreInfo.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2_KHR;
263 coreInfo.pNext = &planeInfo;
264 coreInfo.image = image;
265
266 planeInfo.sType = VK_STRUCTURE_TYPE_IMAGE_PLANE_MEMORY_REQUIREMENTS_INFO_KHR;
267 planeInfo.planeAspect = planeAspect;
268
269 reqs.sType = VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2_KHR;
270
271 vkd.getImageMemoryRequirements2(device, &coreInfo, &reqs);
272
273 return reqs.memoryRequirements;
274 }
275
enumerateInstanceLayerProperties(const PlatformInterface & vkp)276 vector<VkLayerProperties> enumerateInstanceLayerProperties (const PlatformInterface& vkp)
277 {
278 vector<VkLayerProperties> properties;
279 deUint32 numLayers = 0;
280
281 VK_CHECK(vkp.enumerateInstanceLayerProperties(&numLayers, DE_NULL));
282
283 if (numLayers > 0)
284 {
285 properties.resize(numLayers);
286 VK_CHECK(vkp.enumerateInstanceLayerProperties(&numLayers, &properties[0]));
287 TCU_CHECK((size_t)numLayers == properties.size());
288 }
289
290 return properties;
291 }
292
enumerateInstanceExtensionProperties(const PlatformInterface & vkp,const char * layerName)293 vector<VkExtensionProperties> enumerateInstanceExtensionProperties (const PlatformInterface& vkp, const char* layerName)
294 {
295 vector<VkExtensionProperties> properties;
296 deUint32 numExtensions = 0;
297
298 VK_CHECK(vkp.enumerateInstanceExtensionProperties(layerName, &numExtensions, DE_NULL));
299
300 if (numExtensions > 0)
301 {
302 properties.resize(numExtensions);
303 VK_CHECK(vkp.enumerateInstanceExtensionProperties(layerName, &numExtensions, &properties[0]));
304 TCU_CHECK((size_t)numExtensions == properties.size());
305 }
306
307 return properties;
308 }
309
enumerateDeviceLayerProperties(const InstanceInterface & vki,VkPhysicalDevice physicalDevice)310 vector<VkLayerProperties> enumerateDeviceLayerProperties (const InstanceInterface& vki, VkPhysicalDevice physicalDevice)
311 {
312 vector<VkLayerProperties> properties;
313 deUint32 numLayers = 0;
314
315 VK_CHECK(vki.enumerateDeviceLayerProperties(physicalDevice, &numLayers, DE_NULL));
316
317 if (numLayers > 0)
318 {
319 properties.resize(numLayers);
320 VK_CHECK(vki.enumerateDeviceLayerProperties(physicalDevice, &numLayers, &properties[0]));
321 TCU_CHECK((size_t)numLayers == properties.size());
322 }
323
324 return properties;
325 }
326
enumerateDeviceExtensionProperties(const InstanceInterface & vki,VkPhysicalDevice physicalDevice,const char * layerName)327 vector<VkExtensionProperties> enumerateDeviceExtensionProperties (const InstanceInterface& vki, VkPhysicalDevice physicalDevice, const char* layerName)
328 {
329 vector<VkExtensionProperties> properties;
330 deUint32 numExtensions = 0;
331
332 VK_CHECK(vki.enumerateDeviceExtensionProperties(physicalDevice, layerName, &numExtensions, DE_NULL));
333
334 if (numExtensions > 0)
335 {
336 properties.resize(numExtensions);
337 VK_CHECK(vki.enumerateDeviceExtensionProperties(physicalDevice, layerName, &numExtensions, &properties[0]));
338 TCU_CHECK((size_t)numExtensions == properties.size());
339 }
340
341 return properties;
342 }
343
isShaderStageSupported(const VkPhysicalDeviceFeatures & deviceFeatures,VkShaderStageFlagBits stage)344 bool isShaderStageSupported (const VkPhysicalDeviceFeatures& deviceFeatures, VkShaderStageFlagBits stage)
345 {
346 if (stage == VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT || stage == VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT)
347 return deviceFeatures.tessellationShader == VK_TRUE;
348 else if (stage == VK_SHADER_STAGE_GEOMETRY_BIT)
349 return deviceFeatures.geometryShader == VK_TRUE;
350 else
351 return true;
352 }
353
isCompatible(const VkExtensionProperties & extensionProperties,const RequiredExtension & required)354 bool isCompatible (const VkExtensionProperties& extensionProperties, const RequiredExtension& required)
355 {
356 if (required.name != extensionProperties.extensionName)
357 return false;
358
359 if (required.minVersion && required.minVersion.get() > extensionProperties.specVersion)
360 return false;
361
362 if (required.maxVersion && required.maxVersion.get() < extensionProperties.specVersion)
363 return false;
364
365 return true;
366 }
367
isCompatible(const VkLayerProperties & layerProperties,const RequiredLayer & required)368 bool isCompatible (const VkLayerProperties& layerProperties, const RequiredLayer& required)
369 {
370 if (required.name != layerProperties.layerName)
371 return false;
372
373 if (required.minSpecVersion && required.minSpecVersion.get() > layerProperties.specVersion)
374 return false;
375
376 if (required.maxSpecVersion && required.maxSpecVersion.get() < layerProperties.specVersion)
377 return false;
378
379 if (required.minImplVersion && required.minImplVersion.get() > layerProperties.implementationVersion)
380 return false;
381
382 if (required.maxImplVersion && required.maxImplVersion.get() < layerProperties.implementationVersion)
383 return false;
384
385 return true;
386 }
387
isInstanceExtensionSupported(const deUint32 instanceVersion,const std::vector<std::string> & extensions,const std::string & required)388 bool isInstanceExtensionSupported (const deUint32 instanceVersion, const std::vector<std::string>& extensions, const std::string& required)
389 {
390 if (isCoreInstanceExtension(instanceVersion, required))
391 return true;
392 else
393 return de::contains(extensions.begin(), extensions.end(), required);
394 }
395
isDeviceExtensionSupported(const deUint32 deviceVersion,const std::vector<std::string> & extensions,const std::string & required)396 bool isDeviceExtensionSupported (const deUint32 deviceVersion, const std::vector<std::string>& extensions, const std::string& required)
397 {
398 if (isCoreDeviceExtension(deviceVersion, required))
399 return true;
400 else
401 return de::contains(extensions.begin(), extensions.end(), required);
402 }
403
isInstanceExtensionSupported(const deUint32 instanceVersion,const std::vector<VkExtensionProperties> & extensions,const RequiredExtension & required)404 bool isInstanceExtensionSupported (const deUint32 instanceVersion, const std::vector<VkExtensionProperties>& extensions, const RequiredExtension& required)
405 {
406 if (isCoreInstanceExtension(instanceVersion, required.name))
407 return true;
408 else
409 return isExtensionSupported(extensions.begin(), extensions.end(), required);
410 }
411
isDeviceExtensionSupported(const deUint32 deviceVersion,const std::vector<VkExtensionProperties> & extensions,const RequiredExtension & required)412 bool isDeviceExtensionSupported (const deUint32 deviceVersion, const std::vector<VkExtensionProperties>& extensions, const RequiredExtension& required)
413 {
414 if (isCoreDeviceExtension(deviceVersion, required.name))
415 return true;
416 else
417 return isExtensionSupported(extensions.begin(), extensions.end(), required);
418 }
419
isExtensionSupported(const std::vector<VkExtensionProperties> & extensions,const RequiredExtension & required)420 bool isExtensionSupported (const std::vector<VkExtensionProperties>& extensions, const RequiredExtension& required)
421 {
422 return isExtensionSupported(extensions.begin(), extensions.end(), required);
423 }
424
isExtensionSupported(const vector<std::string> & extensionStrings,const std::string & extensionName)425 bool isExtensionSupported (const vector<std::string>& extensionStrings, const std::string& extensionName)
426 {
427 return de::contains(extensionStrings.begin(), extensionStrings.end(), extensionName);
428 }
429
isLayerSupported(const std::vector<VkLayerProperties> & layers,const RequiredLayer & required)430 bool isLayerSupported (const std::vector<VkLayerProperties>& layers, const RequiredLayer& required)
431 {
432 return isLayerSupported(layers.begin(), layers.end(), required);
433 }
434
getDeviceQueue(const DeviceInterface & vkd,VkDevice device,deUint32 queueFamilyIndex,deUint32 queueIndex)435 VkQueue getDeviceQueue (const DeviceInterface& vkd, VkDevice device, deUint32 queueFamilyIndex, deUint32 queueIndex)
436 {
437 VkQueue queue;
438
439 vkd.getDeviceQueue(device, queueFamilyIndex, queueIndex, &queue);
440
441 return queue;
442 }
443
getDeviceQueue2(const DeviceInterface & vkd,VkDevice device,const VkDeviceQueueInfo2 * queueInfo)444 VkQueue getDeviceQueue2 (const DeviceInterface& vkd, VkDevice device, const VkDeviceQueueInfo2* queueInfo)
445 {
446 VkQueue queue;
447
448 vkd.getDeviceQueue2(device, queueInfo, &queue);
449
450 return queue;
451 }
452
findStructureInChain(const void * first,VkStructureType type)453 const void* findStructureInChain (const void* first, VkStructureType type)
454 {
455 struct StructureBase
456 {
457 VkStructureType sType;
458 void* pNext;
459 };
460
461 const StructureBase* cur = reinterpret_cast<const StructureBase*>(first);
462
463 while (cur)
464 {
465 if (cur->sType == type)
466 break;
467 else
468 cur = reinterpret_cast<const StructureBase*>(cur->pNext);
469 }
470
471 return cur;
472 }
473
findStructureInChain(void * first,VkStructureType type)474 void* findStructureInChain (void* first, VkStructureType type)
475 {
476 return const_cast<void*>(findStructureInChain(const_cast<const void*>(first), type));
477 }
478
479 // getStructureType<T> implementations
480 #include "vkGetStructureTypeImpl.inl"
481
482 } // vk
483