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 45 void getCoreInstanceExtensions(deUint32 apiVersion, vector<const char*>& dst) 46 { 47 getCoreInstanceExtensionsImpl(apiVersion, dst); 48 } 49 50 void getCoreDeviceExtensions(deUint32 apiVersion, vector<const char*>& dst) 51 { 52 getCoreDeviceExtensionsImpl(apiVersion, dst); 53 } 54 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 420 bool isExtensionSupported (const std::vector<VkExtensionProperties>& extensions, const RequiredExtension& required) 421 { 422 return isExtensionSupported(extensions.begin(), extensions.end(), required); 423 } 424 425 bool isExtensionSupported (const vector<std::string>& extensionStrings, const std::string& extensionName) 426 { 427 return de::contains(extensionStrings.begin(), extensionStrings.end(), extensionName); 428 } 429 430 bool isLayerSupported (const std::vector<VkLayerProperties>& layers, const RequiredLayer& required) 431 { 432 return isLayerSupported(layers.begin(), layers.end(), required); 433 } 434 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 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 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 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