vkinfo.cpp revision a3a7a1d37bdfad56245b75edac49f8aceded321d
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_NOT_READY: result_str = "VK_NOT_READY"; break;
36        case VK_TIMEOUT: result_str = "VK_TIMEOUT"; break;
37        case VK_EVENT_SET: result_str = "VK_EVENT_SET"; break;
38        case VK_EVENT_RESET: result_str = "VK_EVENT_RESET"; break;
39        case VK_INCOMPLETE: result_str = "VK_INCOMPLETE"; break;
40        case VK_ERROR_OUT_OF_HOST_MEMORY: result_str = "VK_ERROR_OUT_OF_HOST_MEMORY"; break;
41        case VK_ERROR_OUT_OF_DEVICE_MEMORY: result_str = "VK_ERROR_OUT_OF_DEVICE_MEMORY"; break;
42        case VK_ERROR_INITIALIZATION_FAILED: result_str = "VK_ERROR_INITIALIZATION_FAILED"; break;
43        case VK_ERROR_DEVICE_LOST: result_str = "VK_ERROR_DEVICE_LOST"; break;
44        case VK_ERROR_MEMORY_MAP_FAILED: result_str = "VK_ERROR_MEMORY_MAP_FAILED"; break;
45        case VK_ERROR_LAYER_NOT_PRESENT: result_str = "VK_ERROR_LAYER_NOT_PRESENT"; break;
46        case VK_ERROR_EXTENSION_NOT_PRESENT: result_str = "VK_ERROR_EXTENSION_NOT_PRESENT"; break;
47        case VK_ERROR_INCOMPATIBLE_DRIVER: result_str = "VK_ERROR_INCOMPATIBLE_DRIVER"; break;
48        default: result_str = "<unknown VkResult>"; break;
49            // clang-format on
50    }
51    fprintf(stderr, "%s failed: %s (%d)\n", proc, result_str, result);
52    exit(1);
53}
54
55const char* VkPhysicalDeviceTypeStr(VkPhysicalDeviceType type) {
56    switch (type) {
57        case VK_PHYSICAL_DEVICE_TYPE_OTHER:
58            return "OTHER";
59        case VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU:
60            return "INTEGRATED_GPU";
61        case VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU:
62            return "DISCRETE_GPU";
63        case VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU:
64            return "VIRTUAL_GPU";
65        case VK_PHYSICAL_DEVICE_TYPE_CPU:
66            return "CPU";
67        default:
68            return "<UNKNOWN>";
69    }
70}
71
72const char* VkQueueFlagBitStr(VkQueueFlagBits bit) {
73    switch (bit) {
74        case VK_QUEUE_GRAPHICS_BIT:
75            return "GRAPHICS";
76        case VK_QUEUE_COMPUTE_BIT:
77            return "COMPUTE";
78        case VK_QUEUE_DMA_BIT:
79            return "DMA";
80        case VK_QUEUE_SPARSE_MEMMGR_BIT:
81            return "SPARSE";
82    }
83}
84
85void DumpPhysicalDevice(uint32_t idx, VkPhysicalDevice pdev) {
86    VkResult result;
87    std::ostringstream strbuf;
88
89    VkPhysicalDeviceProperties props;
90    vkGetPhysicalDeviceProperties(pdev, &props);
91    printf("  %u: \"%s\" (%s) %u.%u.%u/%#x [%04x:%04x]\n", idx,
92           props.deviceName, VkPhysicalDeviceTypeStr(props.deviceType),
93           (props.apiVersion >> 22) & 0x3FF, (props.apiVersion >> 12) & 0x3FF,
94           (props.apiVersion >> 0) & 0xFFF, props.driverVersion, props.vendorId,
95           props.deviceId);
96
97    VkPhysicalDeviceMemoryProperties mem_props;
98    vkGetPhysicalDeviceMemoryProperties(pdev, &mem_props);
99    for (uint32_t heap = 0; heap < mem_props.memoryHeapCount; heap++) {
100        if ((mem_props.memoryHeaps[heap].flags &
101             VK_MEMORY_HEAP_HOST_LOCAL_BIT) != 0)
102            strbuf << "HOST_LOCAL";
103        printf("     Heap %u: 0x%" PRIx64 " %s\n", heap,
104               mem_props.memoryHeaps[heap].size, strbuf.str().c_str());
105        strbuf.str(std::string());
106
107        for (uint32_t type = 0; type < mem_props.memoryTypeCount; type++) {
108            if (mem_props.memoryTypes[type].heapIndex != heap)
109                continue;
110            VkMemoryPropertyFlags flags =
111                mem_props.memoryTypes[type].propertyFlags;
112            if (flags == VK_MEMORY_PROPERTY_DEVICE_ONLY)
113                strbuf << "DEVICE_ONLY";
114            if ((flags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) != 0)
115                strbuf << "HOST_VISIBLE";
116            if ((flags & VK_MEMORY_PROPERTY_HOST_NON_COHERENT_BIT) != 0)
117                strbuf << " NON_COHERENT";
118            if ((flags & VK_MEMORY_PROPERTY_HOST_UNCACHED_BIT) != 0)
119                strbuf << " UNCACHED";
120            if ((flags & VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT) != 0)
121                strbuf << " LAZILY_ALLOCATED";
122            printf("       Type %u: %s\n", type, strbuf.str().c_str());
123            strbuf.str(std::string());
124        }
125    }
126
127    uint32_t num_queue_families;
128    vkGetPhysicalDeviceQueueFamilyProperties(pdev, &num_queue_families,
129                                             nullptr);
130    std::vector<VkQueueFamilyProperties> queue_family_properties(
131        num_queue_families);
132    vkGetPhysicalDeviceQueueFamilyProperties(pdev, &num_queue_families,
133                                             queue_family_properties.data());
134    for (uint32_t family = 0; family < num_queue_families; family++) {
135        const VkQueueFamilyProperties& qprops = queue_family_properties[family];
136        const char* sep = "";
137        int bit, queue_flags = static_cast<int>(qprops.queueFlags);
138        while ((bit = __builtin_ffs(queue_flags)) != 0) {
139            VkQueueFlagBits flag = VkQueueFlagBits(1 << (bit - 1));
140            strbuf << sep << VkQueueFlagBitStr(flag);
141            queue_flags &= ~flag;
142            sep = "+";
143        }
144        printf("     Queue Family %u: %2ux %s timestamps:%ub\n", family,
145               qprops.queueCount, strbuf.str().c_str(),
146               qprops.timestampValidBits);
147        strbuf.str(std::string());
148    }
149}
150
151}  // namespace
152
153int main(int /*argc*/, char const* /*argv*/ []) {
154    VkResult result;
155
156    VkInstance instance;
157    const VkInstanceCreateInfo create_info = {
158        .sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
159        .pNext = nullptr,
160        .pAppInfo = nullptr,
161        .pAllocCb = nullptr,
162        .layerCount = 0,
163        .ppEnabledLayerNames = nullptr,
164        .extensionCount = 0,
165        .ppEnabledExtensionNames = nullptr,
166    };
167    result = vkCreateInstance(&create_info, &instance);
168    if (result != VK_SUCCESS)
169        die("vkCreateInstance", result);
170
171    uint32_t num_physical_devices;
172    result =
173        vkEnumeratePhysicalDevices(instance, &num_physical_devices, nullptr);
174    if (result != VK_SUCCESS)
175        die("vkEnumeratePhysicalDevices (count)", result);
176    std::vector<VkPhysicalDevice> physical_devices(num_physical_devices,
177                                                   VK_NULL_HANDLE);
178    result = vkEnumeratePhysicalDevices(instance, &num_physical_devices,
179                                        physical_devices.data());
180    if (result != VK_SUCCESS)
181        die("vkEnumeratePhysicalDevices (data)", result);
182    if (num_physical_devices != physical_devices.size()) {
183        fprintf(stderr,
184                "number of physical devices decreased from %zu to %u!\n",
185                physical_devices.size(), num_physical_devices);
186        physical_devices.resize(num_physical_devices);
187    }
188    printf("PhysicalDevices:\n");
189    for (uint32_t i = 0; i < physical_devices.size(); i++)
190        DumpPhysicalDevice(i, physical_devices[i]);
191
192    vkDestroyInstance(instance);
193
194    return 0;
195}
196