blob: eaec272386145fe751e7f9b36a082c5ea5f3474e [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>
18#include <sstream>
Jesse Hall04f4f472015-08-16 19:51:04 -070019#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;
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
55const char* VkPhysicalDeviceTypeStr(VkPhysicalDeviceType type) {
56 switch (type) {
57 case VK_PHYSICAL_DEVICE_TYPE_OTHER:
58 return "OTHER";
59 case VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU:
60 return "INTEGRATED_GPU";
61 case VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU:
62 return "DISCRETE_GPU";
63 case VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU:
64 return "VIRTUAL_GPU";
65 case VK_PHYSICAL_DEVICE_TYPE_CPU:
66 return "CPU";
67 default:
68 return "<UNKNOWN>";
69 }
70}
71
Jesse Hall5ae3abb2015-10-08 14:00:22 -070072const char* VkQueueFlagBitStr(VkQueueFlagBits bit) {
73 switch (bit) {
74 case VK_QUEUE_GRAPHICS_BIT:
75 return "GRAPHICS";
76 case VK_QUEUE_COMPUTE_BIT:
77 return "COMPUTE";
78 case VK_QUEUE_DMA_BIT:
79 return "DMA";
Jesse Hallb00daad2015-11-29 19:46:20 -080080 case VK_QUEUE_SPARSE_BINDING_BIT:
Jesse Hall5ae3abb2015-10-08 14:00:22 -070081 return "SPARSE";
Jesse Hall5ae3abb2015-10-08 14:00:22 -070082 }
83}
84
Jesse Hall04f4f472015-08-16 19:51:04 -070085void DumpPhysicalDevice(uint32_t idx, VkPhysicalDevice pdev) {
86 VkResult result;
Jesse Hall73ab0ac2015-08-25 15:09:15 +010087 std::ostringstream strbuf;
Jesse Hall04f4f472015-08-16 19:51:04 -070088
89 VkPhysicalDeviceProperties props;
Jesse Hall606a54e2015-11-19 22:17:28 -080090 vkGetPhysicalDeviceProperties(pdev, &props);
Jesse Hall04f4f472015-08-16 19:51:04 -070091 printf(" %u: \"%s\" (%s) %u.%u.%u/%#x [%04x:%04x]\n", idx,
92 props.deviceName, VkPhysicalDeviceTypeStr(props.deviceType),
93 (props.apiVersion >> 22) & 0x3FF, (props.apiVersion >> 12) & 0x3FF,
94 (props.apiVersion >> 0) & 0xFFF, props.driverVersion, props.vendorId,
95 props.deviceId);
Jesse Hall73ab0ac2015-08-25 15:09:15 +010096
97 VkPhysicalDeviceMemoryProperties mem_props;
Jesse Hall606a54e2015-11-19 22:17:28 -080098 vkGetPhysicalDeviceMemoryProperties(pdev, &mem_props);
Jesse Hall73ab0ac2015-08-25 15:09:15 +010099 for (uint32_t heap = 0; heap < mem_props.memoryHeapCount; heap++) {
Jesse Hall5ae3abb2015-10-08 14:00:22 -0700100 if ((mem_props.memoryHeaps[heap].flags &
101 VK_MEMORY_HEAP_HOST_LOCAL_BIT) != 0)
Jesse Hall73ab0ac2015-08-25 15:09:15 +0100102 strbuf << "HOST_LOCAL";
103 printf(" Heap %u: 0x%" PRIx64 " %s\n", heap,
104 mem_props.memoryHeaps[heap].size, strbuf.str().c_str());
105 strbuf.str(std::string());
106
107 for (uint32_t type = 0; type < mem_props.memoryTypeCount; type++) {
108 if (mem_props.memoryTypes[type].heapIndex != heap)
109 continue;
110 VkMemoryPropertyFlags flags =
111 mem_props.memoryTypes[type].propertyFlags;
112 if (flags == VK_MEMORY_PROPERTY_DEVICE_ONLY)
113 strbuf << "DEVICE_ONLY";
114 if ((flags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) != 0)
115 strbuf << "HOST_VISIBLE";
116 if ((flags & VK_MEMORY_PROPERTY_HOST_NON_COHERENT_BIT) != 0)
117 strbuf << " NON_COHERENT";
118 if ((flags & VK_MEMORY_PROPERTY_HOST_UNCACHED_BIT) != 0)
119 strbuf << " UNCACHED";
Jesse Hall73ab0ac2015-08-25 15:09:15 +0100120 if ((flags & VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT) != 0)
121 strbuf << " LAZILY_ALLOCATED";
Jesse Hall5ae3abb2015-10-08 14:00:22 -0700122 printf(" Type %u: %s\n", type, strbuf.str().c_str());
Jesse Hall73ab0ac2015-08-25 15:09:15 +0100123 strbuf.str(std::string());
124 }
125 }
Jesse Hall5ae3abb2015-10-08 14:00:22 -0700126
127 uint32_t num_queue_families;
Jesse Hall606a54e2015-11-19 22:17:28 -0800128 vkGetPhysicalDeviceQueueFamilyProperties(pdev, &num_queue_families,
129 nullptr);
Jesse Hall5ae3abb2015-10-08 14:00:22 -0700130 std::vector<VkQueueFamilyProperties> queue_family_properties(
131 num_queue_families);
Jesse Hall606a54e2015-11-19 22:17:28 -0800132 vkGetPhysicalDeviceQueueFamilyProperties(pdev, &num_queue_families,
133 queue_family_properties.data());
Jesse Hall5ae3abb2015-10-08 14:00:22 -0700134 for (uint32_t family = 0; family < num_queue_families; family++) {
135 const VkQueueFamilyProperties& qprops = queue_family_properties[family];
136 const char* sep = "";
137 int bit, queue_flags = static_cast<int>(qprops.queueFlags);
138 while ((bit = __builtin_ffs(queue_flags)) != 0) {
139 VkQueueFlagBits flag = VkQueueFlagBits(1 << (bit - 1));
140 strbuf << sep << VkQueueFlagBitStr(flag);
141 queue_flags &= ~flag;
142 sep = "+";
143 }
Jesse Hallacfa5342015-11-19 21:51:33 -0800144 printf(" Queue Family %u: %2ux %s timestamps:%ub\n", family,
Jesse Hall5ae3abb2015-10-08 14:00:22 -0700145 qprops.queueCount, strbuf.str().c_str(),
Jesse Hallacfa5342015-11-19 21:51:33 -0800146 qprops.timestampValidBits);
Jesse Hall5ae3abb2015-10-08 14:00:22 -0700147 strbuf.str(std::string());
148 }
Jesse Hall04f4f472015-08-16 19:51:04 -0700149}
150
151} // namespace
152
153int main(int /*argc*/, char const* /*argv*/ []) {
154 VkResult result;
155
156 VkInstance instance;
157 const VkInstanceCreateInfo create_info = {
158 .sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
159 .pNext = nullptr,
160 .pAppInfo = nullptr,
Jesse Hall03b6fe12015-11-24 12:44:21 -0800161 .enabledLayerNameCount = 0,
Jesse Hall04f4f472015-08-16 19:51:04 -0700162 .ppEnabledLayerNames = nullptr,
Jesse Hall03b6fe12015-11-24 12:44:21 -0800163 .enabledExtensionNameCount = 0,
Jesse Hall04f4f472015-08-16 19:51:04 -0700164 .ppEnabledExtensionNames = nullptr,
165 };
Jesse Hall03b6fe12015-11-24 12:44:21 -0800166 result = vkCreateInstance(&create_info, nullptr, &instance);
Jesse Hall04f4f472015-08-16 19:51:04 -0700167 if (result != VK_SUCCESS)
168 die("vkCreateInstance", result);
169
170 uint32_t num_physical_devices;
171 result =
172 vkEnumeratePhysicalDevices(instance, &num_physical_devices, nullptr);
173 if (result != VK_SUCCESS)
174 die("vkEnumeratePhysicalDevices (count)", result);
175 std::vector<VkPhysicalDevice> physical_devices(num_physical_devices,
176 VK_NULL_HANDLE);
177 result = vkEnumeratePhysicalDevices(instance, &num_physical_devices,
178 physical_devices.data());
179 if (result != VK_SUCCESS)
180 die("vkEnumeratePhysicalDevices (data)", result);
181 if (num_physical_devices != physical_devices.size()) {
182 fprintf(stderr,
183 "number of physical devices decreased from %zu to %u!\n",
184 physical_devices.size(), num_physical_devices);
185 physical_devices.resize(num_physical_devices);
186 }
187 printf("PhysicalDevices:\n");
188 for (uint32_t i = 0; i < physical_devices.size(); i++)
189 DumpPhysicalDevice(i, physical_devices[i]);
190
Jesse Hall03b6fe12015-11-24 12:44:21 -0800191 vkDestroyInstance(instance, nullptr);
Jesse Hall04f4f472015-08-16 19:51:04 -0700192
193 return 0;
194}