blob: b2688076d10d55f34888db3d14b37b2d9f3d9bcb [file] [log] [blame]
Jesse Halld02edcb2015-09-08 07:44:48 -07001/*
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
Jesse Hall73ab0ac2015-08-25 15:09:15 +010017#include <inttypes.h>
Jesse Hall04f4f472015-08-16 19:51:04 -070018#include <stdlib.h>
Jesse Hall1f91d392015-12-11 16:28:44 -080019#include <sstream>
Jesse Hall04f4f472015-08-16 19:51:04 -070020#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
Jesse Hall09559b52016-01-07 21:50:19 -080030struct GpuInfo {
31 VkPhysicalDeviceProperties properties;
32 VkPhysicalDeviceMemoryProperties memory;
33 std::vector<VkQueueFamilyProperties> queue_families;
34};
35struct VulkanInfo {
36 std::vector<VkExtensionProperties> extensions;
37 std::vector<VkLayerProperties> layers;
38 std::vector<std::vector<VkExtensionProperties>> layer_extensions;
39 std::vector<GpuInfo> gpus;
40};
41
42// ----------------------------------------------------------------------------
43
Jesse Hall04f4f472015-08-16 19:51:04 -070044[[noreturn]] void die(const char* proc, VkResult result) {
45 const char* result_str;
46 switch (result) {
47 // clang-format off
48 case VK_SUCCESS: result_str = "VK_SUCCESS"; break;
Jesse Hall04f4f472015-08-16 19:51:04 -070049 case VK_NOT_READY: result_str = "VK_NOT_READY"; break;
50 case VK_TIMEOUT: result_str = "VK_TIMEOUT"; break;
51 case VK_EVENT_SET: result_str = "VK_EVENT_SET"; break;
52 case VK_EVENT_RESET: result_str = "VK_EVENT_RESET"; break;
53 case VK_INCOMPLETE: result_str = "VK_INCOMPLETE"; break;
Jesse Hall04f4f472015-08-16 19:51:04 -070054 case VK_ERROR_OUT_OF_HOST_MEMORY: result_str = "VK_ERROR_OUT_OF_HOST_MEMORY"; break;
55 case VK_ERROR_OUT_OF_DEVICE_MEMORY: result_str = "VK_ERROR_OUT_OF_DEVICE_MEMORY"; break;
Jesse Hall5ae3abb2015-10-08 14:00:22 -070056 case VK_ERROR_INITIALIZATION_FAILED: result_str = "VK_ERROR_INITIALIZATION_FAILED"; break;
Jesse Hall04f4f472015-08-16 19:51:04 -070057 case VK_ERROR_DEVICE_LOST: result_str = "VK_ERROR_DEVICE_LOST"; break;
Jesse Hall04f4f472015-08-16 19:51:04 -070058 case VK_ERROR_MEMORY_MAP_FAILED: result_str = "VK_ERROR_MEMORY_MAP_FAILED"; break;
Jesse Hall5ae3abb2015-10-08 14:00:22 -070059 case VK_ERROR_LAYER_NOT_PRESENT: result_str = "VK_ERROR_LAYER_NOT_PRESENT"; break;
60 case VK_ERROR_EXTENSION_NOT_PRESENT: result_str = "VK_ERROR_EXTENSION_NOT_PRESENT"; break;
Jesse Hall04f4f472015-08-16 19:51:04 -070061 case VK_ERROR_INCOMPATIBLE_DRIVER: result_str = "VK_ERROR_INCOMPATIBLE_DRIVER"; break;
Jesse Hall04f4f472015-08-16 19:51:04 -070062 default: result_str = "<unknown VkResult>"; break;
63 // clang-format on
64 }
65 fprintf(stderr, "%s failed: %s (%d)\n", proc, result_str, result);
66 exit(1);
67}
68
Jesse Hall09559b52016-01-07 21:50:19 -080069void EnumerateInstanceExtensions(
70 const char* layer_name,
71 std::vector<VkExtensionProperties>* extensions) {
72 VkResult result;
73 uint32_t count;
74 result =
75 vkEnumerateInstanceExtensionProperties(layer_name, &count, nullptr);
76 if (result != VK_SUCCESS)
77 die("vkEnumerateInstanceExtensionProperties (count)", result);
78 do {
79 extensions->resize(count);
80 result = vkEnumerateInstanceExtensionProperties(layer_name, &count,
81 extensions->data());
82 } while (result == VK_INCOMPLETE);
83 if (result != VK_SUCCESS)
84 die("vkEnumerateInstanceExtensionProperties (data)", result);
85}
86
87void GatherInfo(VulkanInfo* info) {
88 VkResult result;
89 uint32_t count;
90
91 result = vkEnumerateInstanceLayerProperties(&count, nullptr);
92 if (result != VK_SUCCESS)
93 die("vkEnumerateInstanceLayerProperties (count)", result);
94 do {
95 info->layers.resize(count);
96 result =
97 vkEnumerateInstanceLayerProperties(&count, info->layers.data());
98 } while (result == VK_INCOMPLETE);
99 if (result != VK_SUCCESS)
100 die("vkEnumerateInstanceLayerProperties (data)", result);
101 info->layer_extensions.resize(info->layers.size());
102
103 EnumerateInstanceExtensions(nullptr, &info->extensions);
104 for (size_t i = 0; i < info->layers.size(); i++) {
105 EnumerateInstanceExtensions(info->layers[i].layerName,
106 &info->layer_extensions[i]);
107 }
108
109 VkInstance instance;
110 const VkInstanceCreateInfo create_info = {
111 .sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
112 };
113 result = vkCreateInstance(&create_info, nullptr, &instance);
114 if (result != VK_SUCCESS)
115 die("vkCreateInstance", result);
116
117 uint32_t num_gpus;
118 result = vkEnumeratePhysicalDevices(instance, &num_gpus, nullptr);
119 if (result != VK_SUCCESS)
120 die("vkEnumeratePhysicalDevices (count)", result);
121 std::vector<VkPhysicalDevice> gpus(num_gpus, VK_NULL_HANDLE);
122 do {
123 gpus.resize(num_gpus, VK_NULL_HANDLE);
124 result = vkEnumeratePhysicalDevices(instance, &num_gpus, gpus.data());
125 } while (result == VK_INCOMPLETE);
126 if (result != VK_SUCCESS)
127 die("vkEnumeratePhysicalDevices (data)", result);
128
129 info->gpus.resize(num_gpus);
130 for (size_t gpu_idx = 0; gpu_idx < gpus.size(); gpu_idx++) {
131 VkPhysicalDevice gpu = gpus[gpu_idx];
132 GpuInfo& gpu_info = info->gpus.at(gpu_idx);
133
134 vkGetPhysicalDeviceProperties(gpu, &gpu_info.properties);
135 vkGetPhysicalDeviceMemoryProperties(gpu, &gpu_info.memory);
136
137 vkGetPhysicalDeviceQueueFamilyProperties(gpu, &count, nullptr);
138 gpu_info.queue_families.resize(count);
139 vkGetPhysicalDeviceQueueFamilyProperties(
140 gpu, &count, gpu_info.queue_families.data());
141 }
142
143 vkDestroyInstance(instance, nullptr);
144}
145
146// ----------------------------------------------------------------------------
147
Jesse Hallc1ab3032016-01-04 07:26:53 -0800148uint32_t ExtractMajorVersion(uint32_t version) {
149 return (version >> 22) & 0x3FF;
150}
151uint32_t ExtractMinorVersion(uint32_t version) {
152 return (version >> 12) & 0x3FF;
153}
154uint32_t ExtractPatchVersion(uint32_t version) {
155 return (version >> 0) & 0xFFF;
156}
157
Jesse Hall04f4f472015-08-16 19:51:04 -0700158const char* VkPhysicalDeviceTypeStr(VkPhysicalDeviceType type) {
159 switch (type) {
160 case VK_PHYSICAL_DEVICE_TYPE_OTHER:
161 return "OTHER";
162 case VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU:
163 return "INTEGRATED_GPU";
164 case VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU:
165 return "DISCRETE_GPU";
166 case VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU:
167 return "VIRTUAL_GPU";
168 case VK_PHYSICAL_DEVICE_TYPE_CPU:
169 return "CPU";
170 default:
171 return "<UNKNOWN>";
172 }
173}
174
Jesse Hall5ae3abb2015-10-08 14:00:22 -0700175const char* VkQueueFlagBitStr(VkQueueFlagBits bit) {
176 switch (bit) {
177 case VK_QUEUE_GRAPHICS_BIT:
178 return "GRAPHICS";
179 case VK_QUEUE_COMPUTE_BIT:
180 return "COMPUTE";
Jesse Hall65ab5522015-11-30 00:07:16 -0800181 case VK_QUEUE_TRANSFER_BIT:
182 return "TRANSFER";
Jesse Hallb00daad2015-11-29 19:46:20 -0800183 case VK_QUEUE_SPARSE_BINDING_BIT:
Jesse Hall5ae3abb2015-10-08 14:00:22 -0700184 return "SPARSE";
Jesse Hall5ae3abb2015-10-08 14:00:22 -0700185 }
186}
187
Jesse Hall09559b52016-01-07 21:50:19 -0800188void PrintExtensions(const std::vector<VkExtensionProperties>& extensions,
189 const char* prefix) {
190 for (const auto& e : extensions)
191 printf("%s- %s (v%u)\n", prefix, e.extensionName, e.specVersion);
192}
Jesse Hallc1ab3032016-01-04 07:26:53 -0800193
Jesse Hall09559b52016-01-07 21:50:19 -0800194void PrintGpuInfo(const GpuInfo& info) {
Jesse Hall04f4f472015-08-16 19:51:04 -0700195 VkResult result;
Jesse Hall73ab0ac2015-08-25 15:09:15 +0100196 std::ostringstream strbuf;
Jesse Hall04f4f472015-08-16 19:51:04 -0700197
Jesse Hall09559b52016-01-07 21:50:19 -0800198 printf(" - \"%s\" (%s) %u.%u.%u/%#x [%04x:%04x]\n",
199 info.properties.deviceName,
200 VkPhysicalDeviceTypeStr(info.properties.deviceType),
201 ExtractMajorVersion(info.properties.apiVersion),
202 ExtractMinorVersion(info.properties.apiVersion),
203 ExtractPatchVersion(info.properties.apiVersion),
204 info.properties.driverVersion, info.properties.vendorID,
205 info.properties.deviceID);
Jesse Hall73ab0ac2015-08-25 15:09:15 +0100206
Jesse Hall09559b52016-01-07 21:50:19 -0800207 for (uint32_t heap = 0; heap < info.memory.memoryHeapCount; heap++) {
208 if ((info.memory.memoryHeaps[heap].flags &
Jesse Halld1af8122015-11-29 23:50:38 -0800209 VK_MEMORY_HEAP_DEVICE_LOCAL_BIT) != 0)
210 strbuf << "DEVICE_LOCAL";
Jesse Hall09559b52016-01-07 21:50:19 -0800211 printf(" Heap %u: 0x%" PRIx64 " %s\n", heap,
212 info.memory.memoryHeaps[heap].size, strbuf.str().c_str());
Jesse Hall73ab0ac2015-08-25 15:09:15 +0100213 strbuf.str(std::string());
214
Jesse Hall09559b52016-01-07 21:50:19 -0800215 for (uint32_t type = 0; type < info.memory.memoryTypeCount; type++) {
216 if (info.memory.memoryTypes[type].heapIndex != heap)
Jesse Hall73ab0ac2015-08-25 15:09:15 +0100217 continue;
218 VkMemoryPropertyFlags flags =
Jesse Hall09559b52016-01-07 21:50:19 -0800219 info.memory.memoryTypes[type].propertyFlags;
Jesse Halld1af8122015-11-29 23:50:38 -0800220 if ((flags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT) != 0)
Jesse Hall1f91d392015-12-11 16:28:44 -0800221 strbuf << " DEVICE_LOCAL";
Jesse Hall73ab0ac2015-08-25 15:09:15 +0100222 if ((flags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) != 0)
Jesse Hall1f91d392015-12-11 16:28:44 -0800223 strbuf << " HOST_VISIBLE";
Jesse Halld1af8122015-11-29 23:50:38 -0800224 if ((flags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT) != 0)
225 strbuf << " COHERENT";
226 if ((flags & VK_MEMORY_PROPERTY_HOST_CACHED_BIT) != 0)
227 strbuf << " CACHED";
Jesse Hall73ab0ac2015-08-25 15:09:15 +0100228 if ((flags & VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT) != 0)
229 strbuf << " LAZILY_ALLOCATED";
Jesse Hall09559b52016-01-07 21:50:19 -0800230 printf(" Type %u:%s\n", type, strbuf.str().c_str());
Jesse Hall73ab0ac2015-08-25 15:09:15 +0100231 strbuf.str(std::string());
232 }
233 }
Jesse Hall5ae3abb2015-10-08 14:00:22 -0700234
Jesse Hall09559b52016-01-07 21:50:19 -0800235 for (uint32_t family = 0; family < info.queue_families.size(); family++) {
236 const VkQueueFamilyProperties& qprops = info.queue_families[family];
Jesse Hall5ae3abb2015-10-08 14:00:22 -0700237 const char* sep = "";
238 int bit, queue_flags = static_cast<int>(qprops.queueFlags);
239 while ((bit = __builtin_ffs(queue_flags)) != 0) {
240 VkQueueFlagBits flag = VkQueueFlagBits(1 << (bit - 1));
241 strbuf << sep << VkQueueFlagBitStr(flag);
242 queue_flags &= ~flag;
243 sep = "+";
244 }
Jesse Hall09559b52016-01-07 21:50:19 -0800245 printf(" Queue Family %u: %2ux %s timestamps:%ub\n", family,
Jesse Hall5ae3abb2015-10-08 14:00:22 -0700246 qprops.queueCount, strbuf.str().c_str(),
Jesse Hallacfa5342015-11-19 21:51:33 -0800247 qprops.timestampValidBits);
Jesse Hall5ae3abb2015-10-08 14:00:22 -0700248 strbuf.str(std::string());
249 }
Jesse Hall04f4f472015-08-16 19:51:04 -0700250}
251
Jesse Hallc1ab3032016-01-04 07:26:53 -0800252void PrintInfo(const VulkanInfo& info) {
Jesse Hall09559b52016-01-07 21:50:19 -0800253 std::ostringstream strbuf;
254
Jesse Hallc1ab3032016-01-04 07:26:53 -0800255 printf("Instance Extensions [%u]:\n", info.extensions.size());
256 PrintExtensions(info.extensions, " ");
257 if (!info.layers.empty()) {
258 printf("Instance Layers [%u]:\n", info.layers.size());
259 for (size_t i = 0; i < info.layers.size(); i++) {
260 const auto& layer = info.layers[i];
Jesse Hall09559b52016-01-07 21:50:19 -0800261 printf(" - %s %u.%u.%u/%u \"%s\"\n", layer.layerName,
262 ExtractMajorVersion(layer.specVersion),
263 ExtractMinorVersion(layer.specVersion),
264 ExtractPatchVersion(layer.specVersion),
265 layer.implementationVersion, layer.description);
Jesse Hallc1ab3032016-01-04 07:26:53 -0800266 if (!info.layer_extensions[i].empty()) {
267 printf(" Extensions [%zu]:\n",
268 info.layer_extensions.size());
269 PrintExtensions(info.layer_extensions[i], " ");
270 }
271 }
272 }
Jesse Hall09559b52016-01-07 21:50:19 -0800273
274 printf("PhysicalDevices [%zu]:\n", info.gpus.size());
275 for (const auto& gpu : info.gpus)
276 PrintGpuInfo(gpu);
Jesse Hallc1ab3032016-01-04 07:26:53 -0800277}
278
Jesse Hall04f4f472015-08-16 19:51:04 -0700279} // namespace
280
Jesse Hall09559b52016-01-07 21:50:19 -0800281// ----------------------------------------------------------------------------
282
Jesse Hall04f4f472015-08-16 19:51:04 -0700283int main(int /*argc*/, char const* /*argv*/ []) {
Jesse Hallc1ab3032016-01-04 07:26:53 -0800284 VulkanInfo info;
285 GatherInfo(&info);
286 PrintInfo(info);
Jesse Hall04f4f472015-08-16 19:51:04 -0700287 return 0;
288}