blob: 964943459d43fa5dfe325c5111333c27864b614b [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
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;
Jesse Hall04f4f472015-08-16 19:51:04 -070035 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;
Jesse Hall04f4f472015-08-16 19:51:04 -070040 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;
Jesse Hall5ae3abb2015-10-08 14:00:22 -070042 case VK_ERROR_INITIALIZATION_FAILED: result_str = "VK_ERROR_INITIALIZATION_FAILED"; break;
Jesse Hall04f4f472015-08-16 19:51:04 -070043 case VK_ERROR_DEVICE_LOST: result_str = "VK_ERROR_DEVICE_LOST"; break;
Jesse Hall04f4f472015-08-16 19:51:04 -070044 case VK_ERROR_MEMORY_MAP_FAILED: result_str = "VK_ERROR_MEMORY_MAP_FAILED"; break;
Jesse Hall5ae3abb2015-10-08 14:00:22 -070045 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;
Jesse Hall04f4f472015-08-16 19:51:04 -070047 case VK_ERROR_INCOMPATIBLE_DRIVER: result_str = "VK_ERROR_INCOMPATIBLE_DRIVER"; break;
Jesse Hall04f4f472015-08-16 19:51:04 -070048 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
Jesse Hallc1ab3032016-01-04 07:26:53 -080055uint32_t ExtractMajorVersion(uint32_t version) {
56 return (version >> 22) & 0x3FF;
57}
58uint32_t ExtractMinorVersion(uint32_t version) {
59 return (version >> 12) & 0x3FF;
60}
61uint32_t ExtractPatchVersion(uint32_t version) {
62 return (version >> 0) & 0xFFF;
63}
64
Jesse Hall04f4f472015-08-16 19:51:04 -070065const char* VkPhysicalDeviceTypeStr(VkPhysicalDeviceType type) {
66 switch (type) {
67 case VK_PHYSICAL_DEVICE_TYPE_OTHER:
68 return "OTHER";
69 case VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU:
70 return "INTEGRATED_GPU";
71 case VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU:
72 return "DISCRETE_GPU";
73 case VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU:
74 return "VIRTUAL_GPU";
75 case VK_PHYSICAL_DEVICE_TYPE_CPU:
76 return "CPU";
77 default:
78 return "<UNKNOWN>";
79 }
80}
81
Jesse Hall5ae3abb2015-10-08 14:00:22 -070082const char* VkQueueFlagBitStr(VkQueueFlagBits bit) {
83 switch (bit) {
84 case VK_QUEUE_GRAPHICS_BIT:
85 return "GRAPHICS";
86 case VK_QUEUE_COMPUTE_BIT:
87 return "COMPUTE";
Jesse Hall65ab5522015-11-30 00:07:16 -080088 case VK_QUEUE_TRANSFER_BIT:
89 return "TRANSFER";
Jesse Hallb00daad2015-11-29 19:46:20 -080090 case VK_QUEUE_SPARSE_BINDING_BIT:
Jesse Hall5ae3abb2015-10-08 14:00:22 -070091 return "SPARSE";
Jesse Hall5ae3abb2015-10-08 14:00:22 -070092 }
93}
94
Jesse Hallc1ab3032016-01-04 07:26:53 -080095struct VulkanInfo {
96 std::vector<VkExtensionProperties> extensions;
97 std::vector<VkLayerProperties> layers;
98 std::vector<std::vector<VkExtensionProperties>> layer_extensions;
99};
100
Jesse Hall04f4f472015-08-16 19:51:04 -0700101void DumpPhysicalDevice(uint32_t idx, VkPhysicalDevice pdev) {
102 VkResult result;
Jesse Hall73ab0ac2015-08-25 15:09:15 +0100103 std::ostringstream strbuf;
Jesse Hall04f4f472015-08-16 19:51:04 -0700104
105 VkPhysicalDeviceProperties props;
Jesse Hall606a54e2015-11-19 22:17:28 -0800106 vkGetPhysicalDeviceProperties(pdev, &props);
Jesse Hall04f4f472015-08-16 19:51:04 -0700107 printf(" %u: \"%s\" (%s) %u.%u.%u/%#x [%04x:%04x]\n", idx,
108 props.deviceName, VkPhysicalDeviceTypeStr(props.deviceType),
Jesse Hallc1ab3032016-01-04 07:26:53 -0800109 ExtractMajorVersion(props.apiVersion),
110 ExtractMinorVersion(props.apiVersion),
111 ExtractPatchVersion(props.apiVersion), props.driverVersion,
112 props.vendorID, props.deviceID);
Jesse Hall73ab0ac2015-08-25 15:09:15 +0100113
114 VkPhysicalDeviceMemoryProperties mem_props;
Jesse Hall606a54e2015-11-19 22:17:28 -0800115 vkGetPhysicalDeviceMemoryProperties(pdev, &mem_props);
Jesse Hall73ab0ac2015-08-25 15:09:15 +0100116 for (uint32_t heap = 0; heap < mem_props.memoryHeapCount; heap++) {
Jesse Hall5ae3abb2015-10-08 14:00:22 -0700117 if ((mem_props.memoryHeaps[heap].flags &
Jesse Halld1af8122015-11-29 23:50:38 -0800118 VK_MEMORY_HEAP_DEVICE_LOCAL_BIT) != 0)
119 strbuf << "DEVICE_LOCAL";
Jesse Hall73ab0ac2015-08-25 15:09:15 +0100120 printf(" Heap %u: 0x%" PRIx64 " %s\n", heap,
121 mem_props.memoryHeaps[heap].size, strbuf.str().c_str());
122 strbuf.str(std::string());
123
124 for (uint32_t type = 0; type < mem_props.memoryTypeCount; type++) {
125 if (mem_props.memoryTypes[type].heapIndex != heap)
126 continue;
127 VkMemoryPropertyFlags flags =
128 mem_props.memoryTypes[type].propertyFlags;
Jesse Halld1af8122015-11-29 23:50:38 -0800129 if ((flags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT) != 0)
Jesse Hall1f91d392015-12-11 16:28:44 -0800130 strbuf << " DEVICE_LOCAL";
Jesse Hall73ab0ac2015-08-25 15:09:15 +0100131 if ((flags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) != 0)
Jesse Hall1f91d392015-12-11 16:28:44 -0800132 strbuf << " HOST_VISIBLE";
Jesse Halld1af8122015-11-29 23:50:38 -0800133 if ((flags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT) != 0)
134 strbuf << " COHERENT";
135 if ((flags & VK_MEMORY_PROPERTY_HOST_CACHED_BIT) != 0)
136 strbuf << " CACHED";
Jesse Hall73ab0ac2015-08-25 15:09:15 +0100137 if ((flags & VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT) != 0)
138 strbuf << " LAZILY_ALLOCATED";
Jesse Hall1f91d392015-12-11 16:28:44 -0800139 printf(" Type %u:%s\n", type, strbuf.str().c_str());
Jesse Hall73ab0ac2015-08-25 15:09:15 +0100140 strbuf.str(std::string());
141 }
142 }
Jesse Hall5ae3abb2015-10-08 14:00:22 -0700143
144 uint32_t num_queue_families;
Jesse Hall606a54e2015-11-19 22:17:28 -0800145 vkGetPhysicalDeviceQueueFamilyProperties(pdev, &num_queue_families,
146 nullptr);
Jesse Hall5ae3abb2015-10-08 14:00:22 -0700147 std::vector<VkQueueFamilyProperties> queue_family_properties(
148 num_queue_families);
Jesse Hall606a54e2015-11-19 22:17:28 -0800149 vkGetPhysicalDeviceQueueFamilyProperties(pdev, &num_queue_families,
150 queue_family_properties.data());
Jesse Hall5ae3abb2015-10-08 14:00:22 -0700151 for (uint32_t family = 0; family < num_queue_families; family++) {
152 const VkQueueFamilyProperties& qprops = queue_family_properties[family];
153 const char* sep = "";
154 int bit, queue_flags = static_cast<int>(qprops.queueFlags);
155 while ((bit = __builtin_ffs(queue_flags)) != 0) {
156 VkQueueFlagBits flag = VkQueueFlagBits(1 << (bit - 1));
157 strbuf << sep << VkQueueFlagBitStr(flag);
158 queue_flags &= ~flag;
159 sep = "+";
160 }
Jesse Hallacfa5342015-11-19 21:51:33 -0800161 printf(" Queue Family %u: %2ux %s timestamps:%ub\n", family,
Jesse Hall5ae3abb2015-10-08 14:00:22 -0700162 qprops.queueCount, strbuf.str().c_str(),
Jesse Hallacfa5342015-11-19 21:51:33 -0800163 qprops.timestampValidBits);
Jesse Hall5ae3abb2015-10-08 14:00:22 -0700164 strbuf.str(std::string());
165 }
Jesse Hall04f4f472015-08-16 19:51:04 -0700166}
167
Jesse Hallc1ab3032016-01-04 07:26:53 -0800168void EnumerateInstanceExtensions(
169 const char* layer_name,
170 std::vector<VkExtensionProperties>* extensions) {
171 VkResult result;
172 uint32_t count;
173 result =
174 vkEnumerateInstanceExtensionProperties(layer_name, &count, nullptr);
175 if (result != VK_SUCCESS)
176 die("vkEnumerateInstanceExtensionProperties (count)", result);
177 extensions->resize(count);
178 result = vkEnumerateInstanceExtensionProperties(layer_name, &count,
179 extensions->data());
180 if (result != VK_SUCCESS)
181 die("vkEnumerateInstanceExtensionProperties (data)", result);
182}
183
184void GatherInfo(VulkanInfo* info) {
185 VkResult result;
186 uint32_t count;
187
188 result = vkEnumerateInstanceLayerProperties(&count, nullptr);
189 if (result != VK_SUCCESS)
190 die("vkEnumerateInstanceLayerProperties (count)", result);
191 info->layers.resize(count);
192 result = vkEnumerateInstanceLayerProperties(&count, info->layers.data());
193 if (result != VK_SUCCESS)
194 die("vkEnumerateInstanceLayerProperties (data)", result);
195 info->layer_extensions.resize(info->layers.size());
196
197 EnumerateInstanceExtensions(nullptr, &info->extensions);
198 for (size_t i = 0; i < info->extensions.size(); i++)
199 EnumerateInstanceExtensions(info->layers[i].layerName,
200 &info->layer_extensions[i]);
201}
202
203void PrintExtensions(const std::vector<VkExtensionProperties>& extensions,
204 const char* prefix) {
205 for (const auto& e : extensions)
206 printf("%s%s (v%u)\n", prefix, e.extensionName, e.specVersion);
207}
208
209void PrintInfo(const VulkanInfo& info) {
210 printf("Instance Extensions [%u]:\n", info.extensions.size());
211 PrintExtensions(info.extensions, " ");
212 if (!info.layers.empty()) {
213 printf("Instance Layers [%u]:\n", info.layers.size());
214 for (size_t i = 0; i < info.layers.size(); i++) {
215 const auto& layer = info.layers[i];
216 printf(
217 " %s %u.%u.%u/%u \"%s\"\n",
218 layer.layerName, ExtractMajorVersion(layer.specVersion),
219 ExtractMinorVersion(layer.specVersion),
220 ExtractPatchVersion(layer.specVersion),
221 layer.implementationVersion, layer.description);
222 if (!info.layer_extensions[i].empty()) {
223 printf(" Extensions [%zu]:\n",
224 info.layer_extensions.size());
225 PrintExtensions(info.layer_extensions[i], " ");
226 }
227 }
228 }
229}
230
Jesse Hall04f4f472015-08-16 19:51:04 -0700231} // namespace
232
233int main(int /*argc*/, char const* /*argv*/ []) {
Jesse Hallc1ab3032016-01-04 07:26:53 -0800234 VulkanInfo info;
235 GatherInfo(&info);
236 PrintInfo(info);
237
Jesse Hall04f4f472015-08-16 19:51:04 -0700238 VkResult result;
239
240 VkInstance instance;
241 const VkInstanceCreateInfo create_info = {
242 .sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
243 .pNext = nullptr,
Jesse Hall3fbc8562015-11-29 22:10:52 -0800244 .pApplicationInfo = nullptr,
Jesse Hall03b6fe12015-11-24 12:44:21 -0800245 .enabledLayerNameCount = 0,
Jesse Hall04f4f472015-08-16 19:51:04 -0700246 .ppEnabledLayerNames = nullptr,
Jesse Hall03b6fe12015-11-24 12:44:21 -0800247 .enabledExtensionNameCount = 0,
Jesse Hall04f4f472015-08-16 19:51:04 -0700248 .ppEnabledExtensionNames = nullptr,
249 };
Jesse Hall03b6fe12015-11-24 12:44:21 -0800250 result = vkCreateInstance(&create_info, nullptr, &instance);
Jesse Hall04f4f472015-08-16 19:51:04 -0700251 if (result != VK_SUCCESS)
252 die("vkCreateInstance", result);
253
254 uint32_t num_physical_devices;
255 result =
256 vkEnumeratePhysicalDevices(instance, &num_physical_devices, nullptr);
257 if (result != VK_SUCCESS)
258 die("vkEnumeratePhysicalDevices (count)", result);
259 std::vector<VkPhysicalDevice> physical_devices(num_physical_devices,
260 VK_NULL_HANDLE);
261 result = vkEnumeratePhysicalDevices(instance, &num_physical_devices,
262 physical_devices.data());
263 if (result != VK_SUCCESS)
264 die("vkEnumeratePhysicalDevices (data)", result);
265 if (num_physical_devices != physical_devices.size()) {
266 fprintf(stderr,
267 "number of physical devices decreased from %zu to %u!\n",
268 physical_devices.size(), num_physical_devices);
269 physical_devices.resize(num_physical_devices);
270 }
Jesse Hallc1ab3032016-01-04 07:26:53 -0800271 printf("PhysicalDevices [%zu]:\n", physical_devices.size());
Jesse Hall04f4f472015-08-16 19:51:04 -0700272 for (uint32_t i = 0; i < physical_devices.size(); i++)
273 DumpPhysicalDevice(i, physical_devices[i]);
274
Jesse Hall03b6fe12015-11-24 12:44:21 -0800275 vkDestroyInstance(instance, nullptr);
Jesse Hall04f4f472015-08-16 19:51:04 -0700276
277 return 0;
278}