vkinfo.cpp revision d02edcbb40d476b6d3b5ae279a6ccef786be8848
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_UNKNOWN: result_str = "VK_ERROR_UNKNOWN"; break;
42        case VK_ERROR_UNAVAILABLE: result_str = "VK_ERROR_UNAVAILABLE"; break;
43        case VK_ERROR_INITIALIZATION_FAILED: result_str = "VK_ERROR_INITIALIZATION_FAILED"; break;
44        case VK_ERROR_OUT_OF_HOST_MEMORY: result_str = "VK_ERROR_OUT_OF_HOST_MEMORY"; break;
45        case VK_ERROR_OUT_OF_DEVICE_MEMORY: result_str = "VK_ERROR_OUT_OF_DEVICE_MEMORY"; break;
46        case VK_ERROR_DEVICE_ALREADY_CREATED: result_str = "VK_ERROR_DEVICE_ALREADY_CREATED"; break;
47        case VK_ERROR_DEVICE_LOST: result_str = "VK_ERROR_DEVICE_LOST"; break;
48        case VK_ERROR_INVALID_POINTER: result_str = "VK_ERROR_INVALID_POINTER"; break;
49        case VK_ERROR_INVALID_VALUE: result_str = "VK_ERROR_INVALID_VALUE"; break;
50        case VK_ERROR_INVALID_HANDLE: result_str = "VK_ERROR_INVALID_HANDLE"; break;
51        case VK_ERROR_INVALID_ORDINAL: result_str = "VK_ERROR_INVALID_ORDINAL"; break;
52        case VK_ERROR_INVALID_MEMORY_SIZE: result_str = "VK_ERROR_INVALID_MEMORY_SIZE"; break;
53        case VK_ERROR_INVALID_EXTENSION: result_str = "VK_ERROR_INVALID_EXTENSION"; break;
54        case VK_ERROR_INVALID_FLAGS: result_str = "VK_ERROR_INVALID_FLAGS"; break;
55        case VK_ERROR_INVALID_ALIGNMENT: result_str = "VK_ERROR_INVALID_ALIGNMENT"; break;
56        case VK_ERROR_INVALID_FORMAT: result_str = "VK_ERROR_INVALID_FORMAT"; break;
57        case VK_ERROR_INVALID_IMAGE: result_str = "VK_ERROR_INVALID_IMAGE"; break;
58        case VK_ERROR_INVALID_DESCRIPTOR_SET_DATA: result_str = "VK_ERROR_INVALID_DESCRIPTOR_SET_DATA"; break;
59        case VK_ERROR_INVALID_QUEUE_TYPE: result_str = "VK_ERROR_INVALID_QUEUE_TYPE"; break;
60        case VK_ERROR_UNSUPPORTED_SHADER_IL_VERSION: result_str = "VK_ERROR_UNSUPPORTED_SHADER_IL_VERSION"; break;
61        case VK_ERROR_BAD_SHADER_CODE: result_str = "VK_ERROR_BAD_SHADER_CODE"; break;
62        case VK_ERROR_BAD_PIPELINE_DATA: result_str = "VK_ERROR_BAD_PIPELINE_DATA"; break;
63        case VK_ERROR_NOT_MAPPABLE: result_str = "VK_ERROR_NOT_MAPPABLE"; break;
64        case VK_ERROR_MEMORY_MAP_FAILED: result_str = "VK_ERROR_MEMORY_MAP_FAILED"; break;
65        case VK_ERROR_MEMORY_UNMAP_FAILED: result_str = "VK_ERROR_MEMORY_UNMAP_FAILED"; break;
66        case VK_ERROR_INCOMPATIBLE_DEVICE: result_str = "VK_ERROR_INCOMPATIBLE_DEVICE"; break;
67        case VK_ERROR_INCOMPATIBLE_DRIVER: result_str = "VK_ERROR_INCOMPATIBLE_DRIVER"; break;
68        case VK_ERROR_INCOMPLETE_COMMAND_BUFFER: result_str = "VK_ERROR_INCOMPLETE_COMMAND_BUFFER"; break;
69        case VK_ERROR_BUILDING_COMMAND_BUFFER: result_str = "VK_ERROR_BUILDING_COMMAND_BUFFER"; break;
70        case VK_ERROR_MEMORY_NOT_BOUND: result_str = "VK_ERROR_MEMORY_NOT_BOUND"; break;
71        case VK_ERROR_INCOMPATIBLE_QUEUE: result_str = "VK_ERROR_INCOMPATIBLE_QUEUE"; break;
72        case VK_ERROR_INVALID_LAYER: result_str = "VK_ERROR_INVALID_LAYER"; break;
73        default: result_str = "<unknown VkResult>"; break;
74            // clang-format on
75    }
76    fprintf(stderr, "%s failed: %s (%d)\n", proc, result_str, result);
77    exit(1);
78}
79
80const char* VkPhysicalDeviceTypeStr(VkPhysicalDeviceType type) {
81    switch (type) {
82        case VK_PHYSICAL_DEVICE_TYPE_OTHER:
83            return "OTHER";
84        case VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU:
85            return "INTEGRATED_GPU";
86        case VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU:
87            return "DISCRETE_GPU";
88        case VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU:
89            return "VIRTUAL_GPU";
90        case VK_PHYSICAL_DEVICE_TYPE_CPU:
91            return "CPU";
92        default:
93            return "<UNKNOWN>";
94    }
95}
96
97void DumpPhysicalDevice(uint32_t idx, VkPhysicalDevice pdev) {
98    VkResult result;
99    std::ostringstream strbuf;
100
101    VkPhysicalDeviceProperties props;
102    result = vkGetPhysicalDeviceProperties(pdev, &props);
103    if (result != VK_SUCCESS)
104        die("vkGetPhysicalDeviceProperties", result);
105    printf("  %u: \"%s\" (%s) %u.%u.%u/%#x [%04x:%04x]\n", idx,
106           props.deviceName, VkPhysicalDeviceTypeStr(props.deviceType),
107           (props.apiVersion >> 22) & 0x3FF, (props.apiVersion >> 12) & 0x3FF,
108           (props.apiVersion >> 0) & 0xFFF, props.driverVersion, props.vendorId,
109           props.deviceId);
110
111    VkPhysicalDeviceMemoryProperties mem_props;
112    result = vkGetPhysicalDeviceMemoryProperties(pdev, &mem_props);
113    if (result != VK_SUCCESS)
114        die("vkGetPhysicalDeviceMemoryProperties", result);
115    for (uint32_t heap = 0; heap < mem_props.memoryHeapCount; heap++) {
116        if ((mem_props.memoryHeaps[heap].flags & VK_MEMORY_HEAP_HOST_LOCAL) !=
117            0)
118            strbuf << "HOST_LOCAL";
119        printf("     Heap %u: 0x%" PRIx64 " %s\n", heap,
120               mem_props.memoryHeaps[heap].size, strbuf.str().c_str());
121        strbuf.str(std::string());
122
123        for (uint32_t type = 0; type < mem_props.memoryTypeCount; type++) {
124            if (mem_props.memoryTypes[type].heapIndex != heap)
125                continue;
126            VkMemoryPropertyFlags flags =
127                mem_props.memoryTypes[type].propertyFlags;
128            if (flags == VK_MEMORY_PROPERTY_DEVICE_ONLY)
129                strbuf << "DEVICE_ONLY";
130            if ((flags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) != 0)
131                strbuf << "HOST_VISIBLE";
132            if ((flags & VK_MEMORY_PROPERTY_HOST_NON_COHERENT_BIT) != 0)
133                strbuf << " NON_COHERENT";
134            if ((flags & VK_MEMORY_PROPERTY_HOST_UNCACHED_BIT) != 0)
135                strbuf << " UNCACHED";
136            if ((flags & VK_MEMORY_PROPERTY_HOST_WRITE_COMBINED_BIT) != 0)
137                strbuf << " WRITE_COMBINED";
138            if ((flags & VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT) != 0)
139                strbuf << " LAZILY_ALLOCATED";
140            printf("        Type %u: %s\n", type, strbuf.str().c_str());
141            strbuf.str(std::string());
142        }
143    }
144}
145
146}  // namespace
147
148int main(int /*argc*/, char const* /*argv*/ []) {
149    VkResult result;
150
151    VkInstance instance;
152    const VkInstanceCreateInfo create_info = {
153        .sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
154        .pNext = nullptr,
155        .pAppInfo = nullptr,
156        .pAllocCb = nullptr,
157        .layerCount = 0,
158        .ppEnabledLayerNames = nullptr,
159        .extensionCount = 0,
160        .ppEnabledExtensionNames = nullptr,
161    };
162    result = vkCreateInstance(&create_info, &instance);
163    if (result != VK_SUCCESS)
164        die("vkCreateInstance", result);
165
166    uint32_t num_physical_devices;
167    result =
168        vkEnumeratePhysicalDevices(instance, &num_physical_devices, nullptr);
169    if (result != VK_SUCCESS)
170        die("vkEnumeratePhysicalDevices (count)", result);
171    std::vector<VkPhysicalDevice> physical_devices(num_physical_devices,
172                                                   VK_NULL_HANDLE);
173    result = vkEnumeratePhysicalDevices(instance, &num_physical_devices,
174                                        physical_devices.data());
175    if (result != VK_SUCCESS)
176        die("vkEnumeratePhysicalDevices (data)", result);
177    if (num_physical_devices != physical_devices.size()) {
178        fprintf(stderr,
179                "number of physical devices decreased from %zu to %u!\n",
180                physical_devices.size(), num_physical_devices);
181        physical_devices.resize(num_physical_devices);
182    }
183    printf("PhysicalDevices:\n");
184    for (uint32_t i = 0; i < physical_devices.size(); i++)
185        DumpPhysicalDevice(i, physical_devices[i]);
186
187    result = vkDestroyInstance(instance);
188    if (result != VK_SUCCESS)
189        die("vkDestroyInstance", result);
190
191    return 0;
192}
193