blob: 5f4253e1e1bc7f13483c04f314f430d81e6cc9bb [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;
Jesse Hall6e4ab312016-01-07 22:26:20 -080034 std::vector<VkExtensionProperties> extensions;
35 std::vector<VkLayerProperties> layers;
36 std::vector<std::vector<VkExtensionProperties>> layer_extensions;
Jesse Hall09559b52016-01-07 21:50:19 -080037};
38struct VulkanInfo {
39 std::vector<VkExtensionProperties> extensions;
40 std::vector<VkLayerProperties> layers;
41 std::vector<std::vector<VkExtensionProperties>> layer_extensions;
42 std::vector<GpuInfo> gpus;
43};
44
45// ----------------------------------------------------------------------------
46
Jesse Hall04f4f472015-08-16 19:51:04 -070047[[noreturn]] void die(const char* proc, VkResult result) {
48 const char* result_str;
49 switch (result) {
50 // clang-format off
51 case VK_SUCCESS: result_str = "VK_SUCCESS"; break;
Jesse Hall04f4f472015-08-16 19:51:04 -070052 case VK_NOT_READY: result_str = "VK_NOT_READY"; break;
53 case VK_TIMEOUT: result_str = "VK_TIMEOUT"; break;
54 case VK_EVENT_SET: result_str = "VK_EVENT_SET"; break;
55 case VK_EVENT_RESET: result_str = "VK_EVENT_RESET"; break;
56 case VK_INCOMPLETE: result_str = "VK_INCOMPLETE"; break;
Jesse Hall04f4f472015-08-16 19:51:04 -070057 case VK_ERROR_OUT_OF_HOST_MEMORY: result_str = "VK_ERROR_OUT_OF_HOST_MEMORY"; break;
58 case VK_ERROR_OUT_OF_DEVICE_MEMORY: result_str = "VK_ERROR_OUT_OF_DEVICE_MEMORY"; break;
Jesse Hall5ae3abb2015-10-08 14:00:22 -070059 case VK_ERROR_INITIALIZATION_FAILED: result_str = "VK_ERROR_INITIALIZATION_FAILED"; break;
Jesse Hall04f4f472015-08-16 19:51:04 -070060 case VK_ERROR_DEVICE_LOST: result_str = "VK_ERROR_DEVICE_LOST"; break;
Jesse Hall04f4f472015-08-16 19:51:04 -070061 case VK_ERROR_MEMORY_MAP_FAILED: result_str = "VK_ERROR_MEMORY_MAP_FAILED"; break;
Jesse Hall5ae3abb2015-10-08 14:00:22 -070062 case VK_ERROR_LAYER_NOT_PRESENT: result_str = "VK_ERROR_LAYER_NOT_PRESENT"; break;
63 case VK_ERROR_EXTENSION_NOT_PRESENT: result_str = "VK_ERROR_EXTENSION_NOT_PRESENT"; break;
Jesse Hall04f4f472015-08-16 19:51:04 -070064 case VK_ERROR_INCOMPATIBLE_DRIVER: result_str = "VK_ERROR_INCOMPATIBLE_DRIVER"; break;
Jesse Hall04f4f472015-08-16 19:51:04 -070065 default: result_str = "<unknown VkResult>"; break;
66 // clang-format on
67 }
68 fprintf(stderr, "%s failed: %s (%d)\n", proc, result_str, result);
69 exit(1);
70}
71
Jesse Hall09559b52016-01-07 21:50:19 -080072void EnumerateInstanceExtensions(
73 const char* layer_name,
74 std::vector<VkExtensionProperties>* extensions) {
75 VkResult result;
76 uint32_t count;
77 result =
78 vkEnumerateInstanceExtensionProperties(layer_name, &count, nullptr);
79 if (result != VK_SUCCESS)
80 die("vkEnumerateInstanceExtensionProperties (count)", result);
81 do {
82 extensions->resize(count);
83 result = vkEnumerateInstanceExtensionProperties(layer_name, &count,
84 extensions->data());
85 } while (result == VK_INCOMPLETE);
86 if (result != VK_SUCCESS)
87 die("vkEnumerateInstanceExtensionProperties (data)", result);
88}
89
Jesse Hall6e4ab312016-01-07 22:26:20 -080090void EnumerateDeviceExtensions(VkPhysicalDevice gpu,
91 const char* layer_name,
92 std::vector<VkExtensionProperties>* extensions) {
93 VkResult result;
94 uint32_t count;
95 result =
96 vkEnumerateDeviceExtensionProperties(gpu, layer_name, &count, nullptr);
97 if (result != VK_SUCCESS)
98 die("vkEnumerateDeviceExtensionProperties (count)", result);
99 do {
100 extensions->resize(count);
101 result = vkEnumerateDeviceExtensionProperties(gpu, layer_name, &count,
102 extensions->data());
103 } while (result == VK_INCOMPLETE);
104 if (result != VK_SUCCESS)
105 die("vkEnumerateDeviceExtensionProperties (data)", result);
106}
107
Jesse Hall09559b52016-01-07 21:50:19 -0800108void GatherInfo(VulkanInfo* info) {
109 VkResult result;
110 uint32_t count;
111
112 result = vkEnumerateInstanceLayerProperties(&count, nullptr);
113 if (result != VK_SUCCESS)
114 die("vkEnumerateInstanceLayerProperties (count)", result);
115 do {
116 info->layers.resize(count);
117 result =
118 vkEnumerateInstanceLayerProperties(&count, info->layers.data());
119 } while (result == VK_INCOMPLETE);
120 if (result != VK_SUCCESS)
121 die("vkEnumerateInstanceLayerProperties (data)", result);
122 info->layer_extensions.resize(info->layers.size());
123
124 EnumerateInstanceExtensions(nullptr, &info->extensions);
125 for (size_t i = 0; i < info->layers.size(); i++) {
126 EnumerateInstanceExtensions(info->layers[i].layerName,
127 &info->layer_extensions[i]);
128 }
129
130 VkInstance instance;
131 const VkInstanceCreateInfo create_info = {
132 .sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
133 };
134 result = vkCreateInstance(&create_info, nullptr, &instance);
135 if (result != VK_SUCCESS)
136 die("vkCreateInstance", result);
137
138 uint32_t num_gpus;
139 result = vkEnumeratePhysicalDevices(instance, &num_gpus, nullptr);
140 if (result != VK_SUCCESS)
141 die("vkEnumeratePhysicalDevices (count)", result);
142 std::vector<VkPhysicalDevice> gpus(num_gpus, VK_NULL_HANDLE);
143 do {
144 gpus.resize(num_gpus, VK_NULL_HANDLE);
145 result = vkEnumeratePhysicalDevices(instance, &num_gpus, gpus.data());
146 } while (result == VK_INCOMPLETE);
147 if (result != VK_SUCCESS)
148 die("vkEnumeratePhysicalDevices (data)", result);
149
150 info->gpus.resize(num_gpus);
151 for (size_t gpu_idx = 0; gpu_idx < gpus.size(); gpu_idx++) {
152 VkPhysicalDevice gpu = gpus[gpu_idx];
153 GpuInfo& gpu_info = info->gpus.at(gpu_idx);
154
155 vkGetPhysicalDeviceProperties(gpu, &gpu_info.properties);
156 vkGetPhysicalDeviceMemoryProperties(gpu, &gpu_info.memory);
157
158 vkGetPhysicalDeviceQueueFamilyProperties(gpu, &count, nullptr);
159 gpu_info.queue_families.resize(count);
160 vkGetPhysicalDeviceQueueFamilyProperties(
161 gpu, &count, gpu_info.queue_families.data());
Jesse Hall6e4ab312016-01-07 22:26:20 -0800162
163 result = vkEnumerateDeviceLayerProperties(gpu, &count, nullptr);
164 if (result != VK_SUCCESS)
165 die("vkEnumerateDeviceLayerProperties (count)", result);
166 do {
167 gpu_info.layers.resize(count);
168 result = vkEnumerateDeviceLayerProperties(gpu, &count,
169 gpu_info.layers.data());
170 } while (result == VK_INCOMPLETE);
171 if (result != VK_SUCCESS)
172 die("vkEnumerateDeviceLayerProperties (data)", result);
173 gpu_info.layer_extensions.resize(gpu_info.layers.size());
174
175 EnumerateDeviceExtensions(gpu, nullptr, &gpu_info.extensions);
176 for (size_t i = 0; i < gpu_info.layers.size(); i++) {
177 EnumerateDeviceExtensions(gpu, gpu_info.layers[i].layerName,
178 &gpu_info.layer_extensions[i]);
179 }
Jesse Hall09559b52016-01-07 21:50:19 -0800180 }
181
182 vkDestroyInstance(instance, nullptr);
183}
184
185// ----------------------------------------------------------------------------
186
Jesse Hallc1ab3032016-01-04 07:26:53 -0800187uint32_t ExtractMajorVersion(uint32_t version) {
188 return (version >> 22) & 0x3FF;
189}
190uint32_t ExtractMinorVersion(uint32_t version) {
191 return (version >> 12) & 0x3FF;
192}
193uint32_t ExtractPatchVersion(uint32_t version) {
194 return (version >> 0) & 0xFFF;
195}
196
Jesse Hall04f4f472015-08-16 19:51:04 -0700197const char* VkPhysicalDeviceTypeStr(VkPhysicalDeviceType type) {
198 switch (type) {
199 case VK_PHYSICAL_DEVICE_TYPE_OTHER:
200 return "OTHER";
201 case VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU:
202 return "INTEGRATED_GPU";
203 case VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU:
204 return "DISCRETE_GPU";
205 case VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU:
206 return "VIRTUAL_GPU";
207 case VK_PHYSICAL_DEVICE_TYPE_CPU:
208 return "CPU";
209 default:
210 return "<UNKNOWN>";
211 }
212}
213
Jesse Hall5ae3abb2015-10-08 14:00:22 -0700214const char* VkQueueFlagBitStr(VkQueueFlagBits bit) {
215 switch (bit) {
216 case VK_QUEUE_GRAPHICS_BIT:
217 return "GRAPHICS";
218 case VK_QUEUE_COMPUTE_BIT:
219 return "COMPUTE";
Jesse Hall65ab5522015-11-30 00:07:16 -0800220 case VK_QUEUE_TRANSFER_BIT:
221 return "TRANSFER";
Jesse Hallb00daad2015-11-29 19:46:20 -0800222 case VK_QUEUE_SPARSE_BINDING_BIT:
Jesse Hall5ae3abb2015-10-08 14:00:22 -0700223 return "SPARSE";
Jesse Hall5ae3abb2015-10-08 14:00:22 -0700224 }
225}
226
Jesse Hall09559b52016-01-07 21:50:19 -0800227void PrintExtensions(const std::vector<VkExtensionProperties>& extensions,
228 const char* prefix) {
229 for (const auto& e : extensions)
Jesse Hall8966bf42016-01-16 17:26:48 -0800230 printf("%s%s (v%u)\n", prefix, e.extensionName, e.specVersion);
Jesse Hall09559b52016-01-07 21:50:19 -0800231}
Jesse Hallc1ab3032016-01-04 07:26:53 -0800232
Jesse Hall09559b52016-01-07 21:50:19 -0800233void PrintGpuInfo(const GpuInfo& info) {
Jesse Hall04f4f472015-08-16 19:51:04 -0700234 VkResult result;
Jesse Hall73ab0ac2015-08-25 15:09:15 +0100235 std::ostringstream strbuf;
Jesse Hall04f4f472015-08-16 19:51:04 -0700236
Jesse Hall8966bf42016-01-16 17:26:48 -0800237 printf(" \"%s\" (%s) %u.%u.%u/%#x [%04x:%04x]\n",
Jesse Hall09559b52016-01-07 21:50:19 -0800238 info.properties.deviceName,
239 VkPhysicalDeviceTypeStr(info.properties.deviceType),
240 ExtractMajorVersion(info.properties.apiVersion),
241 ExtractMinorVersion(info.properties.apiVersion),
242 ExtractPatchVersion(info.properties.apiVersion),
243 info.properties.driverVersion, info.properties.vendorID,
244 info.properties.deviceID);
Jesse Hall73ab0ac2015-08-25 15:09:15 +0100245
Jesse Hall09559b52016-01-07 21:50:19 -0800246 for (uint32_t heap = 0; heap < info.memory.memoryHeapCount; heap++) {
247 if ((info.memory.memoryHeaps[heap].flags &
Jesse Halld1af8122015-11-29 23:50:38 -0800248 VK_MEMORY_HEAP_DEVICE_LOCAL_BIT) != 0)
249 strbuf << "DEVICE_LOCAL";
Jesse Hall8966bf42016-01-16 17:26:48 -0800250 printf(" Heap %u: %" PRIu64 " MiB (0x%" PRIx64 " B) %s\n", heap,
251 info.memory.memoryHeaps[heap].size / 0x1000000,
Jesse Hall09559b52016-01-07 21:50:19 -0800252 info.memory.memoryHeaps[heap].size, strbuf.str().c_str());
Jesse Hall73ab0ac2015-08-25 15:09:15 +0100253 strbuf.str(std::string());
254
Jesse Hall09559b52016-01-07 21:50:19 -0800255 for (uint32_t type = 0; type < info.memory.memoryTypeCount; type++) {
256 if (info.memory.memoryTypes[type].heapIndex != heap)
Jesse Hall73ab0ac2015-08-25 15:09:15 +0100257 continue;
258 VkMemoryPropertyFlags flags =
Jesse Hall09559b52016-01-07 21:50:19 -0800259 info.memory.memoryTypes[type].propertyFlags;
Jesse Halld1af8122015-11-29 23:50:38 -0800260 if ((flags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT) != 0)
Jesse Hall1f91d392015-12-11 16:28:44 -0800261 strbuf << " DEVICE_LOCAL";
Jesse Hall73ab0ac2015-08-25 15:09:15 +0100262 if ((flags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) != 0)
Jesse Hall1f91d392015-12-11 16:28:44 -0800263 strbuf << " HOST_VISIBLE";
Jesse Halld1af8122015-11-29 23:50:38 -0800264 if ((flags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT) != 0)
265 strbuf << " COHERENT";
266 if ((flags & VK_MEMORY_PROPERTY_HOST_CACHED_BIT) != 0)
267 strbuf << " CACHED";
Jesse Hall73ab0ac2015-08-25 15:09:15 +0100268 if ((flags & VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT) != 0)
269 strbuf << " LAZILY_ALLOCATED";
Jesse Hall09559b52016-01-07 21:50:19 -0800270 printf(" Type %u:%s\n", type, strbuf.str().c_str());
Jesse Hall73ab0ac2015-08-25 15:09:15 +0100271 strbuf.str(std::string());
272 }
273 }
Jesse Hall5ae3abb2015-10-08 14:00:22 -0700274
Jesse Hall09559b52016-01-07 21:50:19 -0800275 for (uint32_t family = 0; family < info.queue_families.size(); family++) {
276 const VkQueueFamilyProperties& qprops = info.queue_families[family];
Jesse Hall8966bf42016-01-16 17:26:48 -0800277 VkQueueFlags flags = qprops.queueFlags;
278 char flags_str[5];
279 flags_str[0] = (flags & VK_QUEUE_GRAPHICS_BIT) ? 'G' : '_';
280 flags_str[1] = (flags & VK_QUEUE_COMPUTE_BIT) ? 'C' : '_';
281 flags_str[2] = (flags & VK_QUEUE_TRANSFER_BIT) ? 'T' : '_';
282 flags_str[3] = (flags & VK_QUEUE_SPARSE_BINDING_BIT) ? 'S' : '_';
283 flags_str[4] = '\0';
284 printf(
285 " Queue Family %u: %ux %s\n"
286 " timestampValidBits: %ub\n"
287 " minImageTransferGranularity: (%u,%u,%u)\n",
288 family, qprops.queueCount, flags_str, qprops.timestampValidBits,
289 qprops.minImageTransferGranularity.width,
290 qprops.minImageTransferGranularity.height,
291 qprops.minImageTransferGranularity.depth);
Jesse Hall6e4ab312016-01-07 22:26:20 -0800292
293 if (!info.extensions.empty()) {
Jesse Hall30ac78b2016-01-11 21:29:40 -0800294 printf(" Extensions [%zu]:\n", info.extensions.size());
Jesse Hall6e4ab312016-01-07 22:26:20 -0800295 PrintExtensions(info.extensions, " ");
296 }
297 if (!info.layers.empty()) {
Jesse Hall30ac78b2016-01-11 21:29:40 -0800298 printf(" Layers [%zu]:\n", info.layers.size());
Jesse Hall6e4ab312016-01-07 22:26:20 -0800299 for (size_t i = 0; i < info.layers.size(); i++) {
300 const auto& layer = info.layers[i];
301 printf(" - %s %u.%u.%u/%u \"%s\"\n", layer.layerName,
302 ExtractMajorVersion(layer.specVersion),
303 ExtractMinorVersion(layer.specVersion),
304 ExtractPatchVersion(layer.specVersion),
305 layer.implementationVersion, layer.description);
306 if (!info.layer_extensions[i].empty()) {
307 printf(" Extensions [%zu]:\n",
308 info.layer_extensions.size());
309 PrintExtensions(info.layer_extensions[i], " ");
310 }
311 }
312 }
Jesse Hall5ae3abb2015-10-08 14:00:22 -0700313 }
Jesse Hall04f4f472015-08-16 19:51:04 -0700314}
315
Jesse Hallc1ab3032016-01-04 07:26:53 -0800316void PrintInfo(const VulkanInfo& info) {
Jesse Hall09559b52016-01-07 21:50:19 -0800317 std::ostringstream strbuf;
318
Jesse Hall30ac78b2016-01-11 21:29:40 -0800319 printf("Instance Extensions [%zu]:\n", info.extensions.size());
Jesse Hallc1ab3032016-01-04 07:26:53 -0800320 PrintExtensions(info.extensions, " ");
321 if (!info.layers.empty()) {
Jesse Hall30ac78b2016-01-11 21:29:40 -0800322 printf("Instance Layers [%zu]:\n", info.layers.size());
Jesse Hallc1ab3032016-01-04 07:26:53 -0800323 for (size_t i = 0; i < info.layers.size(); i++) {
324 const auto& layer = info.layers[i];
Jesse Hall8966bf42016-01-16 17:26:48 -0800325 printf(" %s %u.%u.%u/%u \"%s\"\n", layer.layerName,
Jesse Hall09559b52016-01-07 21:50:19 -0800326 ExtractMajorVersion(layer.specVersion),
327 ExtractMinorVersion(layer.specVersion),
328 ExtractPatchVersion(layer.specVersion),
329 layer.implementationVersion, layer.description);
Jesse Hallc1ab3032016-01-04 07:26:53 -0800330 if (!info.layer_extensions[i].empty()) {
Jesse Hall8966bf42016-01-16 17:26:48 -0800331 PrintExtensions(info.layer_extensions[i], " ");
Jesse Hallc1ab3032016-01-04 07:26:53 -0800332 }
333 }
334 }
Jesse Hall09559b52016-01-07 21:50:19 -0800335
336 printf("PhysicalDevices [%zu]:\n", info.gpus.size());
337 for (const auto& gpu : info.gpus)
338 PrintGpuInfo(gpu);
Jesse Hallc1ab3032016-01-04 07:26:53 -0800339}
340
Jesse Hall04f4f472015-08-16 19:51:04 -0700341} // namespace
342
Jesse Hall09559b52016-01-07 21:50:19 -0800343// ----------------------------------------------------------------------------
344
Jesse Hall04f4f472015-08-16 19:51:04 -0700345int main(int /*argc*/, char const* /*argv*/ []) {
Jesse Hallc1ab3032016-01-04 07:26:53 -0800346 VulkanInfo info;
347 GatherInfo(&info);
348 PrintInfo(info);
Jesse Hall04f4f472015-08-16 19:51:04 -0700349 return 0;
350}