blob: d5d8845703f476d447810b986827cb075ce55837 [file] [log] [blame]
Karl Schultzb932f102016-02-04 09:41:29 -07001///////////////////////////////////////////////////////////////////////////////
Antoine Laboure3795c12015-10-27 12:21:09 -07002//
Karl Schultzb932f102016-02-04 09:41:29 -07003// Copyright (c) 2015-2016 The Khronos Group Inc.
4// Copyright (c) 2015-2016 Valve Corporation
5// Copyright (c) 2015-2016 LunarG, Inc.
6// Copyright (c) 2015-2016 Google, Inc.
Antoine Laboure3795c12015-10-27 12:21:09 -07007//
Karl Schultzb932f102016-02-04 09:41:29 -07008// Permission is hereby granted, free of charge, to any person obtaining a copy
9// of this software and/or associated documentation files (the "Materials"), to
10// deal in the Materials without restriction, including without limitation the
11// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
12// sell copies of the Materials, and to permit persons to whom the Materials are
13// furnished to do so, subject to the following conditions:
Antoine Laboure3795c12015-10-27 12:21:09 -070014//
Karl Schultzb932f102016-02-04 09:41:29 -070015// The above copyright notice(s) and this permission notice shall be included in
16// all copies or substantial portions of the Materials.
17//
18// The Materials are Confidential Information as defined by the Khronos
19// Membership Agreement until designated non-confidential by Khronos, at which
20// point this condition clause shall be removed.
21//
22// THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
Antoine Labour38841df2016-01-28 15:05:57 -080023// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
Karl Schultzb932f102016-02-04 09:41:29 -070024// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
25//
26// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
27// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
28// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE
29// USE OR OTHER DEALINGS IN THE MATERIALS.
30///////////////////////////////////////////////////////////////////////////////
Antoine Laboure3795c12015-10-27 12:21:09 -070031
32#define VK_PROTOTYPES
33#include "vkjson.h"
34
35#include <stdio.h>
36#include <string.h>
37
38#include <iostream>
39#include <vector>
40
Mark Young8928c062016-01-25 13:37:06 -070041const uint32_t unsignedNegOne = (uint32_t)(-1);
42
Antoine Laboure3795c12015-10-27 12:21:09 -070043struct Options {
Mark Young8928c062016-01-25 13:37:06 -070044 uint32_t device_index = unsignedNegOne;
Antoine Laboure3795c12015-10-27 12:21:09 -070045 std::string device_name;
46 std::string output_file;
47};
48
49bool ParseOptions(int argc, char* argv[], Options* options) {
50 for (int i = 1; i < argc; ++i) {
51 std::string arg(argv[i]);
52 if (arg == "--first" || arg == "-f") {
53 options->device_index = 0;
54 } else {
55 ++i;
56 if (i >= argc) {
57 std::cerr << "Missing parameter after: " << arg << std::endl;
58 return false;
59 }
60 std::string arg2(argv[i]);
61 if (arg == "--device-index" || arg == "-d") {
62 int result = sscanf(arg2.c_str(), "%u", &options->device_index);
63 if (result != 1) {
64 options->device_index = -1;
65 std::cerr << "Unable to parse index: " << arg2 << std::endl;
66 return false;
67 }
68 } else if (arg == "--device-name" || arg == "-n") {
69 options->device_name = arg2;
70 } else if (arg == "--output" || arg == "-o") {
71 options->output_file = arg2;
72 } else {
73 std::cerr << "Unknown argument: " << arg << std::endl;
74 return false;
75 }
76 }
77 }
Mark Young8928c062016-01-25 13:37:06 -070078 if (options->device_index != unsignedNegOne && !options->device_name.empty()) {
Antoine Laboure3795c12015-10-27 12:21:09 -070079 std::cerr << "Must specify only one of device index and device name."
80 << std::endl;
81 return false;
82 }
Mark Young8928c062016-01-25 13:37:06 -070083 if (!options->output_file.empty() && options->device_index == unsignedNegOne &&
Antoine Laboure3795c12015-10-27 12:21:09 -070084 options->device_name.empty()) {
85 std::cerr << "Must specify device index or device name when specifying "
86 "output file"
87 << std::endl;
88 return false;
89 }
90 return true;
91}
92
93bool DumpProperties(const VkJsonAllProperties& props, const Options& options) {
94 std::string device_name(props.properties.deviceName);
95 std::string output_file = options.output_file;
96 if (output_file.empty())
97 output_file = device_name + ".json";
98 FILE* file = nullptr;
99 if (output_file == "-") {
100 file = stdout;
101 } else {
102 file = fopen(output_file.c_str(), "w");
103 if (!file) {
104 std::cerr << "Unable to open file " << output_file << "." << std::endl;
105 return false;
106 }
107 }
108
109 std::string json = VkJsonAllPropertiesToJson(props) + '\n';
110 fwrite(json.data(), 1, json.size(), file);
111
112 if (output_file != "-") {
113 fclose(file);
114 std::cout << "Wrote file " << output_file << " for device " << device_name
115 << "." << std::endl;
116 }
117 return true;
118}
119
120int main(int argc, char* argv[]) {
121 Options options;
122 if (!ParseOptions(argc, argv, &options))
123 return 1;
124
125 const VkApplicationInfo app_info = {VK_STRUCTURE_TYPE_APPLICATION_INFO,
126 nullptr,
127 "vkjson_info",
128 1,
129 "",
130 0,
131 VK_API_VERSION};
132 VkInstanceCreateInfo instance_info = {VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
133 nullptr,
134 0,
135 &app_info,
136 0,
137 nullptr,
138 0,
139 nullptr};
140 VkInstance instance;
141 VkResult result = vkCreateInstance(&instance_info, nullptr, &instance);
142 if (result != VK_SUCCESS) {
143 std::cerr << "Error: vkCreateInstance failed with error: " << result
144 << "." << std::endl;
145 return 1;
146 }
147
148 uint32_t device_count = 0;
149 result = vkEnumeratePhysicalDevices(instance, &device_count, nullptr);
150 if (result != VK_SUCCESS) {
151 std::cerr << "Error: vkEnumeratePhysicalDevices failed with error "
152 << result << "." << std::endl;
153 return 1;
154 }
155 if (device_count == 0) {
156 std::cerr << "Error: no Vulkan device found.";
157 return 1;
158 }
159
160 std::vector<VkPhysicalDevice> physical_devices(device_count,
161 VkPhysicalDevice());
162 result = vkEnumeratePhysicalDevices(instance, &device_count,
163 physical_devices.data());
164 if (result != VK_SUCCESS) {
165 std::cerr << "Error: vkEnumeratePhysicalDevices failed with error "
166 << result << std::endl;
167 return 1;
168 }
169
Mark Young8928c062016-01-25 13:37:06 -0700170 if (options.device_index != unsignedNegOne) {
Antoine Laboure3795c12015-10-27 12:21:09 -0700171 if (static_cast<uint32_t>(options.device_index) >= device_count) {
172 std::cerr << "Error: device " << options.device_index
173 << " requested but only " << device_count << " found."
174 << std::endl;
175 return 1;
176 }
177 auto props = VkJsonGetAllProperties(physical_devices[options.device_index]);
178 if (!DumpProperties(props, options))
179 return 1;
180 return 0;
181 }
182
183 bool found = false;
184 for (auto physical_device : physical_devices) {
185 auto props = VkJsonGetAllProperties(physical_device);
186 if (!options.device_name.empty() &&
187 options.device_name != props.properties.deviceName)
188 continue;
189 if (!DumpProperties(props, options))
190 return 1;
191 found = true;
192 }
193
194 if (!found) {
195 std::cerr << "Error: device " << options.device_name << " not found."
196 << std::endl;
197 return 1;
198 }
199 return 0;
200}