blob: 134a23116437e1c7b7c62316399d24f0820df43b [file] [log] [blame]
Antoine Laboure3795c12015-10-27 12:21:09 -07001// Copyright 2015 Google Inc. All rights reserved.
2//
3// Redistribution and use in source and binary forms, with or without
4// modification, are permitted provided that the following conditions are
5// met:
6//
7// * Redistributions of source code must retain the above copyright
8// notice, this list of conditions and the following disclaimer.
9// * Redistributions in binary form must reproduce the above
10// copyright notice, this list of conditions and the following disclaimer
11// in the documentation and/or other materials provided with the
12// distribution.
13// * Neither the name of Google Inc. nor the names of its
14// contributors may be used to endorse or promote products derived from
15// this software without specific prior written permission.
16//
17// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
29#define VK_PROTOTYPES
30#include "vkjson.h"
31
32#include <stdio.h>
33#include <string.h>
34
35#include <iostream>
36#include <vector>
37
38struct Options {
39 uint32_t device_index = -1u;
40 std::string device_name;
41 std::string output_file;
42};
43
44bool ParseOptions(int argc, char* argv[], Options* options) {
45 for (int i = 1; i < argc; ++i) {
46 std::string arg(argv[i]);
47 if (arg == "--first" || arg == "-f") {
48 options->device_index = 0;
49 } else {
50 ++i;
51 if (i >= argc) {
52 std::cerr << "Missing parameter after: " << arg << std::endl;
53 return false;
54 }
55 std::string arg2(argv[i]);
56 if (arg == "--device-index" || arg == "-d") {
57 int result = sscanf(arg2.c_str(), "%u", &options->device_index);
58 if (result != 1) {
59 options->device_index = -1;
60 std::cerr << "Unable to parse index: " << arg2 << std::endl;
61 return false;
62 }
63 } else if (arg == "--device-name" || arg == "-n") {
64 options->device_name = arg2;
65 } else if (arg == "--output" || arg == "-o") {
66 options->output_file = arg2;
67 } else {
68 std::cerr << "Unknown argument: " << arg << std::endl;
69 return false;
70 }
71 }
72 }
73 if (options->device_index != -1u && !options->device_name.empty()) {
74 std::cerr << "Must specify only one of device index and device name."
75 << std::endl;
76 return false;
77 }
78 if (!options->output_file.empty() && options->device_index == -1u &&
79 options->device_name.empty()) {
80 std::cerr << "Must specify device index or device name when specifying "
81 "output file"
82 << std::endl;
83 return false;
84 }
85 return true;
86}
87
88bool DumpProperties(const VkJsonAllProperties& props, const Options& options) {
89 std::string device_name(props.properties.deviceName);
90 std::string output_file = options.output_file;
91 if (output_file.empty())
92 output_file = device_name + ".json";
93 FILE* file = nullptr;
94 if (output_file == "-") {
95 file = stdout;
96 } else {
97 file = fopen(output_file.c_str(), "w");
98 if (!file) {
99 std::cerr << "Unable to open file " << output_file << "." << std::endl;
100 return false;
101 }
102 }
103
104 std::string json = VkJsonAllPropertiesToJson(props) + '\n';
105 fwrite(json.data(), 1, json.size(), file);
106
107 if (output_file != "-") {
108 fclose(file);
109 std::cout << "Wrote file " << output_file << " for device " << device_name
110 << "." << std::endl;
111 }
112 return true;
113}
114
115int main(int argc, char* argv[]) {
116 Options options;
117 if (!ParseOptions(argc, argv, &options))
118 return 1;
119
120 const VkApplicationInfo app_info = {VK_STRUCTURE_TYPE_APPLICATION_INFO,
121 nullptr,
122 "vkjson_info",
123 1,
124 "",
125 0,
126 VK_API_VERSION};
127 VkInstanceCreateInfo instance_info = {VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
128 nullptr,
129 0,
130 &app_info,
131 0,
132 nullptr,
133 0,
134 nullptr};
135 VkInstance instance;
136 VkResult result = vkCreateInstance(&instance_info, nullptr, &instance);
137 if (result != VK_SUCCESS) {
138 std::cerr << "Error: vkCreateInstance failed with error: " << result
139 << "." << std::endl;
140 return 1;
141 }
142
143 uint32_t device_count = 0;
144 result = vkEnumeratePhysicalDevices(instance, &device_count, nullptr);
145 if (result != VK_SUCCESS) {
146 std::cerr << "Error: vkEnumeratePhysicalDevices failed with error "
147 << result << "." << std::endl;
148 return 1;
149 }
150 if (device_count == 0) {
151 std::cerr << "Error: no Vulkan device found.";
152 return 1;
153 }
154
155 std::vector<VkPhysicalDevice> physical_devices(device_count,
156 VkPhysicalDevice());
157 result = vkEnumeratePhysicalDevices(instance, &device_count,
158 physical_devices.data());
159 if (result != VK_SUCCESS) {
160 std::cerr << "Error: vkEnumeratePhysicalDevices failed with error "
161 << result << std::endl;
162 return 1;
163 }
164
165 if (options.device_index != -1u) {
166 if (static_cast<uint32_t>(options.device_index) >= device_count) {
167 std::cerr << "Error: device " << options.device_index
168 << " requested but only " << device_count << " found."
169 << std::endl;
170 return 1;
171 }
172 auto props = VkJsonGetAllProperties(physical_devices[options.device_index]);
173 if (!DumpProperties(props, options))
174 return 1;
175 return 0;
176 }
177
178 bool found = false;
179 for (auto physical_device : physical_devices) {
180 auto props = VkJsonGetAllProperties(physical_device);
181 if (!options.device_name.empty() &&
182 options.device_name != props.properties.deviceName)
183 continue;
184 if (!DumpProperties(props, options))
185 return 1;
186 found = true;
187 }
188
189 if (!found) {
190 std::cerr << "Error: device " << options.device_name << " not found."
191 << std::endl;
192 return 1;
193 }
194 return 0;
195}