vkinfo.cpp revision 606a54e194a5884c628130ba2eda1b3bfbc157d7
1/* 2 * Copyright 2015 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#include <inttypes.h> 18#include <sstream> 19#include <stdlib.h> 20#include <vector> 21 22#define VK_PROTOTYPES 23#include <vulkan/vulkan.h> 24 25#define LOG_TAG "vkinfo" 26#include <log/log.h> 27 28namespace { 29 30[[noreturn]] void die(const char* proc, VkResult result) { 31 const char* result_str; 32 switch (result) { 33 // clang-format off 34 case VK_SUCCESS: result_str = "VK_SUCCESS"; break; 35 case VK_UNSUPPORTED: result_str = "VK_UNSUPPORTED"; break; 36 case VK_NOT_READY: result_str = "VK_NOT_READY"; break; 37 case VK_TIMEOUT: result_str = "VK_TIMEOUT"; break; 38 case VK_EVENT_SET: result_str = "VK_EVENT_SET"; break; 39 case VK_EVENT_RESET: result_str = "VK_EVENT_RESET"; break; 40 case VK_INCOMPLETE: result_str = "VK_INCOMPLETE"; break; 41 case VK_ERROR_OUT_OF_HOST_MEMORY: result_str = "VK_ERROR_OUT_OF_HOST_MEMORY"; break; 42 case VK_ERROR_OUT_OF_DEVICE_MEMORY: result_str = "VK_ERROR_OUT_OF_DEVICE_MEMORY"; break; 43 case VK_ERROR_INITIALIZATION_FAILED: result_str = "VK_ERROR_INITIALIZATION_FAILED"; break; 44 case VK_ERROR_DEVICE_LOST: result_str = "VK_ERROR_DEVICE_LOST"; break; 45 case VK_ERROR_MEMORY_MAP_FAILED: result_str = "VK_ERROR_MEMORY_MAP_FAILED"; break; 46 case VK_ERROR_LAYER_NOT_PRESENT: result_str = "VK_ERROR_LAYER_NOT_PRESENT"; break; 47 case VK_ERROR_EXTENSION_NOT_PRESENT: result_str = "VK_ERROR_EXTENSION_NOT_PRESENT"; break; 48 case VK_ERROR_INCOMPATIBLE_DRIVER: result_str = "VK_ERROR_INCOMPATIBLE_DRIVER"; break; 49 default: result_str = "<unknown VkResult>"; break; 50 // clang-format on 51 } 52 fprintf(stderr, "%s failed: %s (%d)\n", proc, result_str, result); 53 exit(1); 54} 55 56const char* VkPhysicalDeviceTypeStr(VkPhysicalDeviceType type) { 57 switch (type) { 58 case VK_PHYSICAL_DEVICE_TYPE_OTHER: 59 return "OTHER"; 60 case VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU: 61 return "INTEGRATED_GPU"; 62 case VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU: 63 return "DISCRETE_GPU"; 64 case VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU: 65 return "VIRTUAL_GPU"; 66 case VK_PHYSICAL_DEVICE_TYPE_CPU: 67 return "CPU"; 68 default: 69 return "<UNKNOWN>"; 70 } 71} 72 73const char* VkQueueFlagBitStr(VkQueueFlagBits bit) { 74 switch (bit) { 75 case VK_QUEUE_GRAPHICS_BIT: 76 return "GRAPHICS"; 77 case VK_QUEUE_COMPUTE_BIT: 78 return "COMPUTE"; 79 case VK_QUEUE_DMA_BIT: 80 return "DMA"; 81 case VK_QUEUE_SPARSE_MEMMGR_BIT: 82 return "SPARSE"; 83 case VK_QUEUE_EXTENDED_BIT: 84 return "EXT"; 85 } 86} 87 88void DumpPhysicalDevice(uint32_t idx, VkPhysicalDevice pdev) { 89 VkResult result; 90 std::ostringstream strbuf; 91 92 VkPhysicalDeviceProperties props; 93 vkGetPhysicalDeviceProperties(pdev, &props); 94 printf(" %u: \"%s\" (%s) %u.%u.%u/%#x [%04x:%04x]\n", idx, 95 props.deviceName, VkPhysicalDeviceTypeStr(props.deviceType), 96 (props.apiVersion >> 22) & 0x3FF, (props.apiVersion >> 12) & 0x3FF, 97 (props.apiVersion >> 0) & 0xFFF, props.driverVersion, props.vendorId, 98 props.deviceId); 99 100 VkPhysicalDeviceMemoryProperties mem_props; 101 vkGetPhysicalDeviceMemoryProperties(pdev, &mem_props); 102 for (uint32_t heap = 0; heap < mem_props.memoryHeapCount; heap++) { 103 if ((mem_props.memoryHeaps[heap].flags & 104 VK_MEMORY_HEAP_HOST_LOCAL_BIT) != 0) 105 strbuf << "HOST_LOCAL"; 106 printf(" Heap %u: 0x%" PRIx64 " %s\n", heap, 107 mem_props.memoryHeaps[heap].size, strbuf.str().c_str()); 108 strbuf.str(std::string()); 109 110 for (uint32_t type = 0; type < mem_props.memoryTypeCount; type++) { 111 if (mem_props.memoryTypes[type].heapIndex != heap) 112 continue; 113 VkMemoryPropertyFlags flags = 114 mem_props.memoryTypes[type].propertyFlags; 115 if (flags == VK_MEMORY_PROPERTY_DEVICE_ONLY) 116 strbuf << "DEVICE_ONLY"; 117 if ((flags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) != 0) 118 strbuf << "HOST_VISIBLE"; 119 if ((flags & VK_MEMORY_PROPERTY_HOST_NON_COHERENT_BIT) != 0) 120 strbuf << " NON_COHERENT"; 121 if ((flags & VK_MEMORY_PROPERTY_HOST_UNCACHED_BIT) != 0) 122 strbuf << " UNCACHED"; 123 if ((flags & VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT) != 0) 124 strbuf << " LAZILY_ALLOCATED"; 125 printf(" Type %u: %s\n", type, strbuf.str().c_str()); 126 strbuf.str(std::string()); 127 } 128 } 129 130 uint32_t num_queue_families; 131 vkGetPhysicalDeviceQueueFamilyProperties(pdev, &num_queue_families, 132 nullptr); 133 std::vector<VkQueueFamilyProperties> queue_family_properties( 134 num_queue_families); 135 vkGetPhysicalDeviceQueueFamilyProperties(pdev, &num_queue_families, 136 queue_family_properties.data()); 137 for (uint32_t family = 0; family < num_queue_families; family++) { 138 const VkQueueFamilyProperties& qprops = queue_family_properties[family]; 139 const char* sep = ""; 140 int bit, queue_flags = static_cast<int>(qprops.queueFlags); 141 while ((bit = __builtin_ffs(queue_flags)) != 0) { 142 VkQueueFlagBits flag = VkQueueFlagBits(1 << (bit - 1)); 143 strbuf << sep << VkQueueFlagBitStr(flag); 144 queue_flags &= ~flag; 145 sep = "+"; 146 } 147 printf(" Queue Family %u: %2ux %s timestamps:%ub\n", family, 148 qprops.queueCount, strbuf.str().c_str(), 149 qprops.timestampValidBits); 150 strbuf.str(std::string()); 151 } 152} 153 154} // namespace 155 156int main(int /*argc*/, char const* /*argv*/ []) { 157 VkResult result; 158 159 VkInstance instance; 160 const VkInstanceCreateInfo create_info = { 161 .sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, 162 .pNext = nullptr, 163 .pAppInfo = nullptr, 164 .pAllocCb = nullptr, 165 .layerCount = 0, 166 .ppEnabledLayerNames = nullptr, 167 .extensionCount = 0, 168 .ppEnabledExtensionNames = nullptr, 169 }; 170 result = vkCreateInstance(&create_info, &instance); 171 if (result != VK_SUCCESS) 172 die("vkCreateInstance", result); 173 174 uint32_t num_physical_devices; 175 result = 176 vkEnumeratePhysicalDevices(instance, &num_physical_devices, nullptr); 177 if (result != VK_SUCCESS) 178 die("vkEnumeratePhysicalDevices (count)", result); 179 std::vector<VkPhysicalDevice> physical_devices(num_physical_devices, 180 VK_NULL_HANDLE); 181 result = vkEnumeratePhysicalDevices(instance, &num_physical_devices, 182 physical_devices.data()); 183 if (result != VK_SUCCESS) 184 die("vkEnumeratePhysicalDevices (data)", result); 185 if (num_physical_devices != physical_devices.size()) { 186 fprintf(stderr, 187 "number of physical devices decreased from %zu to %u!\n", 188 physical_devices.size(), num_physical_devices); 189 physical_devices.resize(num_physical_devices); 190 } 191 printf("PhysicalDevices:\n"); 192 for (uint32_t i = 0; i < physical_devices.size(); i++) 193 DumpPhysicalDevice(i, physical_devices[i]); 194 195 vkDestroyInstance(instance); 196 197 return 0; 198} 199