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 33namespace vk 34{ 35 36using std::vector; 37 38namespace 39{ 40 41#include "vkSupportedExtensions.inl" 42 43} 44 45void getCoreInstanceExtensions(deUint32 apiVersion, vector<const char*>& dst) 46{ 47 getCoreInstanceExtensionsImpl(apiVersion, dst); 48} 49 50void getCoreDeviceExtensions(deUint32 apiVersion, vector<const char*>& dst) 51{ 52 getCoreDeviceExtensionsImpl(apiVersion, dst); 53} 54 55bool 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 65bool 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 75vector<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 94vector<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 117vector<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 136VkPhysicalDeviceFeatures 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 146VkPhysicalDeviceFeatures2 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 157VkPhysicalDeviceProperties 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 167VkPhysicalDeviceMemoryProperties 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 177VkFormatProperties 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 187VkImageFormatProperties 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 197std::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 216std::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 235VkMemoryRequirements getBufferMemoryRequirements (const DeviceInterface& vk, VkDevice device, VkBuffer buffer) 236{ 237 VkMemoryRequirements req; 238 vk.getBufferMemoryRequirements(device, buffer, &req); 239 return req; 240} 241 242VkMemoryRequirements getImageMemoryRequirements (const DeviceInterface& vk, VkDevice device, VkImage image) 243{ 244 VkMemoryRequirements req; 245 vk.getImageMemoryRequirements(device, image, &req); 246 return req; 247} 248 249VkMemoryRequirements 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 276vector<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 293vector<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 310vector<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 327vector<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 344bool 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 354bool 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 368bool 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 388bool 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 396bool 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 404bool 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 412bool 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 420bool isExtensionSupported (const std::vector<VkExtensionProperties>& extensions, const RequiredExtension& required) 421{ 422 return isExtensionSupported(extensions.begin(), extensions.end(), required); 423} 424 425bool isLayerSupported (const std::vector<VkLayerProperties>& layers, const RequiredLayer& required) 426{ 427 return isLayerSupported(layers.begin(), layers.end(), required); 428} 429 430VkQueue getDeviceQueue (const DeviceInterface& vkd, VkDevice device, deUint32 queueFamilyIndex, deUint32 queueIndex) 431{ 432 VkQueue queue; 433 434 vkd.getDeviceQueue(device, queueFamilyIndex, queueIndex, &queue); 435 436 return queue; 437} 438 439VkQueue getDeviceQueue2 (const DeviceInterface& vkd, VkDevice device, const VkDeviceQueueInfo2* queueInfo) 440{ 441 VkQueue queue; 442 443 vkd.getDeviceQueue2(device, queueInfo, &queue); 444 445 return queue; 446} 447 448const void* findStructureInChain (const void* first, VkStructureType type) 449{ 450 struct StructureBase 451 { 452 VkStructureType sType; 453 void* pNext; 454 }; 455 456 const StructureBase* cur = reinterpret_cast<const StructureBase*>(first); 457 458 while (cur) 459 { 460 if (cur->sType == type) 461 break; 462 else 463 cur = reinterpret_cast<const StructureBase*>(cur->pNext); 464 } 465 466 return cur; 467} 468 469void* findStructureInChain (void* first, VkStructureType type) 470{ 471 return const_cast<void*>(findStructureInChain(const_cast<const void*>(first), type)); 472} 473 474// getStructureType<T> implementations 475#include "vkGetStructureTypeImpl.inl" 476 477} // vk 478