blob: 71f989e891bc75b32c9b12b377b1fc090c842412 [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 Hall4da3bd62016-01-16 22:14:40 -080017#include <algorithm>
18#include <array>
Jesse Hall73ab0ac2015-08-25 15:09:15 +010019#include <inttypes.h>
Jesse Hall04f4f472015-08-16 19:51:04 -070020#include <stdlib.h>
Jesse Hall1f91d392015-12-11 16:28:44 -080021#include <sstream>
Jesse Hall04f4f472015-08-16 19:51:04 -070022#include <vector>
23
Jesse Hall04f4f472015-08-16 19:51:04 -070024#include <vulkan/vulkan.h>
Jesse Hall4da3bd62016-01-16 22:14:40 -080025#include <vulkan/vk_ext_debug_report.h>
Jesse Hall04f4f472015-08-16 19:51:04 -070026
27#define LOG_TAG "vkinfo"
28#include <log/log.h>
29
30namespace {
31
Jesse Hall09559b52016-01-07 21:50:19 -080032struct GpuInfo {
33 VkPhysicalDeviceProperties properties;
34 VkPhysicalDeviceMemoryProperties memory;
35 std::vector<VkQueueFamilyProperties> queue_families;
Jesse Hall6e4ab312016-01-07 22:26:20 -080036 std::vector<VkExtensionProperties> extensions;
37 std::vector<VkLayerProperties> layers;
38 std::vector<std::vector<VkExtensionProperties>> layer_extensions;
Jesse Hall09559b52016-01-07 21:50:19 -080039};
40struct VulkanInfo {
41 std::vector<VkExtensionProperties> extensions;
42 std::vector<VkLayerProperties> layers;
43 std::vector<std::vector<VkExtensionProperties>> layer_extensions;
44 std::vector<GpuInfo> gpus;
45};
46
47// ----------------------------------------------------------------------------
48
Jesse Hall04f4f472015-08-16 19:51:04 -070049[[noreturn]] void die(const char* proc, VkResult result) {
50 const char* result_str;
51 switch (result) {
52 // clang-format off
53 case VK_SUCCESS: result_str = "VK_SUCCESS"; break;
Jesse Hall04f4f472015-08-16 19:51:04 -070054 case VK_NOT_READY: result_str = "VK_NOT_READY"; break;
55 case VK_TIMEOUT: result_str = "VK_TIMEOUT"; break;
56 case VK_EVENT_SET: result_str = "VK_EVENT_SET"; break;
57 case VK_EVENT_RESET: result_str = "VK_EVENT_RESET"; break;
58 case VK_INCOMPLETE: result_str = "VK_INCOMPLETE"; break;
Jesse Hall04f4f472015-08-16 19:51:04 -070059 case VK_ERROR_OUT_OF_HOST_MEMORY: result_str = "VK_ERROR_OUT_OF_HOST_MEMORY"; break;
60 case VK_ERROR_OUT_OF_DEVICE_MEMORY: result_str = "VK_ERROR_OUT_OF_DEVICE_MEMORY"; break;
Jesse Hall5ae3abb2015-10-08 14:00:22 -070061 case VK_ERROR_INITIALIZATION_FAILED: result_str = "VK_ERROR_INITIALIZATION_FAILED"; break;
Jesse Hall04f4f472015-08-16 19:51:04 -070062 case VK_ERROR_DEVICE_LOST: result_str = "VK_ERROR_DEVICE_LOST"; break;
Jesse Hall04f4f472015-08-16 19:51:04 -070063 case VK_ERROR_MEMORY_MAP_FAILED: result_str = "VK_ERROR_MEMORY_MAP_FAILED"; break;
Jesse Hall5ae3abb2015-10-08 14:00:22 -070064 case VK_ERROR_LAYER_NOT_PRESENT: result_str = "VK_ERROR_LAYER_NOT_PRESENT"; break;
65 case VK_ERROR_EXTENSION_NOT_PRESENT: result_str = "VK_ERROR_EXTENSION_NOT_PRESENT"; break;
Jesse Hall04f4f472015-08-16 19:51:04 -070066 case VK_ERROR_INCOMPATIBLE_DRIVER: result_str = "VK_ERROR_INCOMPATIBLE_DRIVER"; break;
Jesse Hall04f4f472015-08-16 19:51:04 -070067 default: result_str = "<unknown VkResult>"; break;
68 // clang-format on
69 }
70 fprintf(stderr, "%s failed: %s (%d)\n", proc, result_str, result);
71 exit(1);
72}
73
Jesse Hall4da3bd62016-01-16 22:14:40 -080074bool HasExtension(const std::vector<VkExtensionProperties>& extensions,
75 const char* name) {
76 return std::find_if(extensions.cbegin(), extensions.cend(),
77 [=](const VkExtensionProperties& prop) {
78 return strcmp(prop.extensionName, name) == 0;
79 }) != extensions.end();
80}
81
Jesse Hall09559b52016-01-07 21:50:19 -080082void EnumerateInstanceExtensions(
83 const char* layer_name,
84 std::vector<VkExtensionProperties>* extensions) {
85 VkResult result;
86 uint32_t count;
87 result =
88 vkEnumerateInstanceExtensionProperties(layer_name, &count, nullptr);
89 if (result != VK_SUCCESS)
90 die("vkEnumerateInstanceExtensionProperties (count)", result);
91 do {
92 extensions->resize(count);
93 result = vkEnumerateInstanceExtensionProperties(layer_name, &count,
94 extensions->data());
95 } while (result == VK_INCOMPLETE);
96 if (result != VK_SUCCESS)
97 die("vkEnumerateInstanceExtensionProperties (data)", result);
98}
99
Jesse Hall6e4ab312016-01-07 22:26:20 -0800100void EnumerateDeviceExtensions(VkPhysicalDevice gpu,
101 const char* layer_name,
102 std::vector<VkExtensionProperties>* extensions) {
103 VkResult result;
104 uint32_t count;
105 result =
106 vkEnumerateDeviceExtensionProperties(gpu, layer_name, &count, nullptr);
107 if (result != VK_SUCCESS)
108 die("vkEnumerateDeviceExtensionProperties (count)", result);
109 do {
110 extensions->resize(count);
111 result = vkEnumerateDeviceExtensionProperties(gpu, layer_name, &count,
112 extensions->data());
113 } while (result == VK_INCOMPLETE);
114 if (result != VK_SUCCESS)
115 die("vkEnumerateDeviceExtensionProperties (data)", result);
116}
117
Jesse Hall09559b52016-01-07 21:50:19 -0800118void GatherInfo(VulkanInfo* info) {
119 VkResult result;
120 uint32_t count;
121
122 result = vkEnumerateInstanceLayerProperties(&count, nullptr);
123 if (result != VK_SUCCESS)
124 die("vkEnumerateInstanceLayerProperties (count)", result);
125 do {
126 info->layers.resize(count);
127 result =
128 vkEnumerateInstanceLayerProperties(&count, info->layers.data());
129 } while (result == VK_INCOMPLETE);
130 if (result != VK_SUCCESS)
131 die("vkEnumerateInstanceLayerProperties (data)", result);
132 info->layer_extensions.resize(info->layers.size());
133
134 EnumerateInstanceExtensions(nullptr, &info->extensions);
135 for (size_t i = 0; i < info->layers.size(); i++) {
136 EnumerateInstanceExtensions(info->layers[i].layerName,
137 &info->layer_extensions[i]);
138 }
139
Jesse Hall4da3bd62016-01-16 22:14:40 -0800140 const std::array<const char*, 1> kDesiredExtensions = {
141 {VK_EXT_DEBUG_REPORT_EXTENSION_NAME},
142 };
143 const char* extensions[kDesiredExtensions.size()];
144 uint32_t num_extensions = 0;
145 for (const auto& desired_ext : kDesiredExtensions) {
146 bool available = HasExtension(info->extensions, desired_ext);
147 for (size_t i = 0; !available && i < info->layer_extensions.size(); i++)
148 available = HasExtension(info->layer_extensions[i], desired_ext);
149 if (available)
150 extensions[num_extensions++] = desired_ext;
151 }
152
Jesse Hall09559b52016-01-07 21:50:19 -0800153 const VkInstanceCreateInfo create_info = {
154 .sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
Jesse Hall4da3bd62016-01-16 22:14:40 -0800155 .enabledExtensionCount = num_extensions,
156 .ppEnabledExtensionNames = extensions,
Jesse Hall09559b52016-01-07 21:50:19 -0800157 };
Jesse Hall4da3bd62016-01-16 22:14:40 -0800158 VkInstance instance;
Jesse Hall09559b52016-01-07 21:50:19 -0800159 result = vkCreateInstance(&create_info, nullptr, &instance);
160 if (result != VK_SUCCESS)
161 die("vkCreateInstance", result);
162
163 uint32_t num_gpus;
164 result = vkEnumeratePhysicalDevices(instance, &num_gpus, nullptr);
165 if (result != VK_SUCCESS)
166 die("vkEnumeratePhysicalDevices (count)", result);
167 std::vector<VkPhysicalDevice> gpus(num_gpus, VK_NULL_HANDLE);
168 do {
169 gpus.resize(num_gpus, VK_NULL_HANDLE);
170 result = vkEnumeratePhysicalDevices(instance, &num_gpus, gpus.data());
171 } while (result == VK_INCOMPLETE);
172 if (result != VK_SUCCESS)
173 die("vkEnumeratePhysicalDevices (data)", result);
174
175 info->gpus.resize(num_gpus);
176 for (size_t gpu_idx = 0; gpu_idx < gpus.size(); gpu_idx++) {
177 VkPhysicalDevice gpu = gpus[gpu_idx];
178 GpuInfo& gpu_info = info->gpus.at(gpu_idx);
179
180 vkGetPhysicalDeviceProperties(gpu, &gpu_info.properties);
181 vkGetPhysicalDeviceMemoryProperties(gpu, &gpu_info.memory);
182
183 vkGetPhysicalDeviceQueueFamilyProperties(gpu, &count, nullptr);
184 gpu_info.queue_families.resize(count);
185 vkGetPhysicalDeviceQueueFamilyProperties(
186 gpu, &count, gpu_info.queue_families.data());
Jesse Hall6e4ab312016-01-07 22:26:20 -0800187
188 result = vkEnumerateDeviceLayerProperties(gpu, &count, nullptr);
189 if (result != VK_SUCCESS)
190 die("vkEnumerateDeviceLayerProperties (count)", result);
191 do {
192 gpu_info.layers.resize(count);
193 result = vkEnumerateDeviceLayerProperties(gpu, &count,
194 gpu_info.layers.data());
195 } while (result == VK_INCOMPLETE);
196 if (result != VK_SUCCESS)
197 die("vkEnumerateDeviceLayerProperties (data)", result);
198 gpu_info.layer_extensions.resize(gpu_info.layers.size());
199
200 EnumerateDeviceExtensions(gpu, nullptr, &gpu_info.extensions);
201 for (size_t i = 0; i < gpu_info.layers.size(); i++) {
202 EnumerateDeviceExtensions(gpu, gpu_info.layers[i].layerName,
203 &gpu_info.layer_extensions[i]);
204 }
Jesse Hall09559b52016-01-07 21:50:19 -0800205 }
206
207 vkDestroyInstance(instance, nullptr);
208}
209
210// ----------------------------------------------------------------------------
211
Jesse Hallc1ab3032016-01-04 07:26:53 -0800212uint32_t ExtractMajorVersion(uint32_t version) {
213 return (version >> 22) & 0x3FF;
214}
215uint32_t ExtractMinorVersion(uint32_t version) {
216 return (version >> 12) & 0x3FF;
217}
218uint32_t ExtractPatchVersion(uint32_t version) {
219 return (version >> 0) & 0xFFF;
220}
221
Jesse Hall04f4f472015-08-16 19:51:04 -0700222const char* VkPhysicalDeviceTypeStr(VkPhysicalDeviceType type) {
223 switch (type) {
224 case VK_PHYSICAL_DEVICE_TYPE_OTHER:
225 return "OTHER";
226 case VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU:
227 return "INTEGRATED_GPU";
228 case VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU:
229 return "DISCRETE_GPU";
230 case VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU:
231 return "VIRTUAL_GPU";
232 case VK_PHYSICAL_DEVICE_TYPE_CPU:
233 return "CPU";
234 default:
235 return "<UNKNOWN>";
236 }
237}
238
Jesse Hall5ae3abb2015-10-08 14:00:22 -0700239const char* VkQueueFlagBitStr(VkQueueFlagBits bit) {
240 switch (bit) {
241 case VK_QUEUE_GRAPHICS_BIT:
242 return "GRAPHICS";
243 case VK_QUEUE_COMPUTE_BIT:
244 return "COMPUTE";
Jesse Hall65ab5522015-11-30 00:07:16 -0800245 case VK_QUEUE_TRANSFER_BIT:
246 return "TRANSFER";
Jesse Hallb00daad2015-11-29 19:46:20 -0800247 case VK_QUEUE_SPARSE_BINDING_BIT:
Jesse Hall5ae3abb2015-10-08 14:00:22 -0700248 return "SPARSE";
Jesse Hall5ae3abb2015-10-08 14:00:22 -0700249 }
250}
251
Jesse Hall09559b52016-01-07 21:50:19 -0800252void PrintExtensions(const std::vector<VkExtensionProperties>& extensions,
253 const char* prefix) {
254 for (const auto& e : extensions)
Jesse Hall8966bf42016-01-16 17:26:48 -0800255 printf("%s%s (v%u)\n", prefix, e.extensionName, e.specVersion);
Jesse Hall09559b52016-01-07 21:50:19 -0800256}
Jesse Hallc1ab3032016-01-04 07:26:53 -0800257
Jesse Hallaa410942016-01-17 13:07:10 -0800258void PrintLayers(
259 const std::vector<VkLayerProperties>& layers,
260 const std::vector<std::vector<VkExtensionProperties>> extensions,
261 const char* prefix) {
262 std::string ext_prefix(prefix);
263 ext_prefix.append(" ");
264 for (size_t i = 0; i < layers.size(); i++) {
265 printf(
266 "%s%s %u.%u.%u/%u\n"
267 "%s %s\n",
268 prefix, layers[i].layerName,
269 ExtractMajorVersion(layers[i].specVersion),
270 ExtractMinorVersion(layers[i].specVersion),
271 ExtractPatchVersion(layers[i].specVersion),
272 layers[i].implementationVersion, prefix, layers[i].description);
273 if (!extensions[i].empty())
274 printf("%s Extensions [%zu]:\n", prefix, extensions[i].size());
275 PrintExtensions(extensions[i], ext_prefix.c_str());
276 }
277}
278
Jesse Hall09559b52016-01-07 21:50:19 -0800279void PrintGpuInfo(const GpuInfo& info) {
Jesse Hall04f4f472015-08-16 19:51:04 -0700280 VkResult result;
Jesse Hall73ab0ac2015-08-25 15:09:15 +0100281 std::ostringstream strbuf;
Jesse Hall04f4f472015-08-16 19:51:04 -0700282
Jesse Hall8966bf42016-01-16 17:26:48 -0800283 printf(" \"%s\" (%s) %u.%u.%u/%#x [%04x:%04x]\n",
Jesse Hall09559b52016-01-07 21:50:19 -0800284 info.properties.deviceName,
285 VkPhysicalDeviceTypeStr(info.properties.deviceType),
286 ExtractMajorVersion(info.properties.apiVersion),
287 ExtractMinorVersion(info.properties.apiVersion),
288 ExtractPatchVersion(info.properties.apiVersion),
289 info.properties.driverVersion, info.properties.vendorID,
290 info.properties.deviceID);
Jesse Hall73ab0ac2015-08-25 15:09:15 +0100291
Jesse Hall09559b52016-01-07 21:50:19 -0800292 for (uint32_t heap = 0; heap < info.memory.memoryHeapCount; heap++) {
293 if ((info.memory.memoryHeaps[heap].flags &
Jesse Halld1af8122015-11-29 23:50:38 -0800294 VK_MEMORY_HEAP_DEVICE_LOCAL_BIT) != 0)
295 strbuf << "DEVICE_LOCAL";
Jesse Hall8966bf42016-01-16 17:26:48 -0800296 printf(" Heap %u: %" PRIu64 " MiB (0x%" PRIx64 " B) %s\n", heap,
297 info.memory.memoryHeaps[heap].size / 0x1000000,
Jesse Hall09559b52016-01-07 21:50:19 -0800298 info.memory.memoryHeaps[heap].size, strbuf.str().c_str());
Jesse Hall73ab0ac2015-08-25 15:09:15 +0100299 strbuf.str(std::string());
300
Jesse Hall09559b52016-01-07 21:50:19 -0800301 for (uint32_t type = 0; type < info.memory.memoryTypeCount; type++) {
302 if (info.memory.memoryTypes[type].heapIndex != heap)
Jesse Hall73ab0ac2015-08-25 15:09:15 +0100303 continue;
304 VkMemoryPropertyFlags flags =
Jesse Hall09559b52016-01-07 21:50:19 -0800305 info.memory.memoryTypes[type].propertyFlags;
Jesse Halld1af8122015-11-29 23:50:38 -0800306 if ((flags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT) != 0)
Jesse Hall1f91d392015-12-11 16:28:44 -0800307 strbuf << " DEVICE_LOCAL";
Jesse Hall73ab0ac2015-08-25 15:09:15 +0100308 if ((flags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) != 0)
Jesse Hall1f91d392015-12-11 16:28:44 -0800309 strbuf << " HOST_VISIBLE";
Jesse Halld1af8122015-11-29 23:50:38 -0800310 if ((flags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT) != 0)
311 strbuf << " COHERENT";
312 if ((flags & VK_MEMORY_PROPERTY_HOST_CACHED_BIT) != 0)
313 strbuf << " CACHED";
Jesse Hall73ab0ac2015-08-25 15:09:15 +0100314 if ((flags & VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT) != 0)
315 strbuf << " LAZILY_ALLOCATED";
Jesse Hall09559b52016-01-07 21:50:19 -0800316 printf(" Type %u:%s\n", type, strbuf.str().c_str());
Jesse Hall73ab0ac2015-08-25 15:09:15 +0100317 strbuf.str(std::string());
318 }
319 }
Jesse Hall5ae3abb2015-10-08 14:00:22 -0700320
Jesse Hall09559b52016-01-07 21:50:19 -0800321 for (uint32_t family = 0; family < info.queue_families.size(); family++) {
322 const VkQueueFamilyProperties& qprops = info.queue_families[family];
Jesse Hall8966bf42016-01-16 17:26:48 -0800323 VkQueueFlags flags = qprops.queueFlags;
324 char flags_str[5];
325 flags_str[0] = (flags & VK_QUEUE_GRAPHICS_BIT) ? 'G' : '_';
326 flags_str[1] = (flags & VK_QUEUE_COMPUTE_BIT) ? 'C' : '_';
327 flags_str[2] = (flags & VK_QUEUE_TRANSFER_BIT) ? 'T' : '_';
328 flags_str[3] = (flags & VK_QUEUE_SPARSE_BINDING_BIT) ? 'S' : '_';
329 flags_str[4] = '\0';
330 printf(
331 " Queue Family %u: %ux %s\n"
332 " timestampValidBits: %ub\n"
333 " minImageTransferGranularity: (%u,%u,%u)\n",
334 family, qprops.queueCount, flags_str, qprops.timestampValidBits,
335 qprops.minImageTransferGranularity.width,
336 qprops.minImageTransferGranularity.height,
337 qprops.minImageTransferGranularity.depth);
Jesse Hall6e4ab312016-01-07 22:26:20 -0800338
339 if (!info.extensions.empty()) {
Jesse Hall30ac78b2016-01-11 21:29:40 -0800340 printf(" Extensions [%zu]:\n", info.extensions.size());
Jesse Hall6e4ab312016-01-07 22:26:20 -0800341 PrintExtensions(info.extensions, " ");
342 }
343 if (!info.layers.empty()) {
Jesse Hall30ac78b2016-01-11 21:29:40 -0800344 printf(" Layers [%zu]:\n", info.layers.size());
Jesse Hallaa410942016-01-17 13:07:10 -0800345 PrintLayers(info.layers, info.layer_extensions, " ");
Jesse Hall6e4ab312016-01-07 22:26:20 -0800346 }
Jesse Hall5ae3abb2015-10-08 14:00:22 -0700347 }
Jesse Hall04f4f472015-08-16 19:51:04 -0700348}
349
Jesse Hallc1ab3032016-01-04 07:26:53 -0800350void PrintInfo(const VulkanInfo& info) {
Jesse Hall09559b52016-01-07 21:50:19 -0800351 std::ostringstream strbuf;
352
Jesse Hall30ac78b2016-01-11 21:29:40 -0800353 printf("Instance Extensions [%zu]:\n", info.extensions.size());
Jesse Hallc1ab3032016-01-04 07:26:53 -0800354 PrintExtensions(info.extensions, " ");
355 if (!info.layers.empty()) {
Jesse Hall30ac78b2016-01-11 21:29:40 -0800356 printf("Instance Layers [%zu]:\n", info.layers.size());
Jesse Hallaa410942016-01-17 13:07:10 -0800357 PrintLayers(info.layers, info.layer_extensions, " ");
Jesse Hallc1ab3032016-01-04 07:26:53 -0800358 }
Jesse Hall09559b52016-01-07 21:50:19 -0800359
360 printf("PhysicalDevices [%zu]:\n", info.gpus.size());
361 for (const auto& gpu : info.gpus)
362 PrintGpuInfo(gpu);
Jesse Hallc1ab3032016-01-04 07:26:53 -0800363}
364
Jesse Hall04f4f472015-08-16 19:51:04 -0700365} // namespace
366
Jesse Hall09559b52016-01-07 21:50:19 -0800367// ----------------------------------------------------------------------------
368
Jesse Hall04f4f472015-08-16 19:51:04 -0700369int main(int /*argc*/, char const* /*argv*/ []) {
Jesse Hallc1ab3032016-01-04 07:26:53 -0800370 VulkanInfo info;
371 GatherInfo(&info);
372 PrintInfo(info);
Jesse Hall04f4f472015-08-16 19:51:04 -0700373 return 0;
374}