vkjson: initial commit
diff --git a/libs/vkjson/vkjson_info.cc b/libs/vkjson/vkjson_info.cc
new file mode 100644
index 0000000..134a231
--- /dev/null
+++ b/libs/vkjson/vkjson_info.cc
@@ -0,0 +1,195 @@
+// Copyright 2015 Google Inc. All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#define VK_PROTOTYPES
+#include "vkjson.h"
+
+#include <stdio.h>
+#include <string.h>
+
+#include <iostream>
+#include <vector>
+
+struct Options {
+ uint32_t device_index = -1u;
+ std::string device_name;
+ std::string output_file;
+};
+
+bool ParseOptions(int argc, char* argv[], Options* options) {
+ for (int i = 1; i < argc; ++i) {
+ std::string arg(argv[i]);
+ if (arg == "--first" || arg == "-f") {
+ options->device_index = 0;
+ } else {
+ ++i;
+ if (i >= argc) {
+ std::cerr << "Missing parameter after: " << arg << std::endl;
+ return false;
+ }
+ std::string arg2(argv[i]);
+ if (arg == "--device-index" || arg == "-d") {
+ int result = sscanf(arg2.c_str(), "%u", &options->device_index);
+ if (result != 1) {
+ options->device_index = -1;
+ std::cerr << "Unable to parse index: " << arg2 << std::endl;
+ return false;
+ }
+ } else if (arg == "--device-name" || arg == "-n") {
+ options->device_name = arg2;
+ } else if (arg == "--output" || arg == "-o") {
+ options->output_file = arg2;
+ } else {
+ std::cerr << "Unknown argument: " << arg << std::endl;
+ return false;
+ }
+ }
+ }
+ if (options->device_index != -1u && !options->device_name.empty()) {
+ std::cerr << "Must specify only one of device index and device name."
+ << std::endl;
+ return false;
+ }
+ if (!options->output_file.empty() && options->device_index == -1u &&
+ options->device_name.empty()) {
+ std::cerr << "Must specify device index or device name when specifying "
+ "output file"
+ << std::endl;
+ return false;
+ }
+ return true;
+}
+
+bool DumpProperties(const VkJsonAllProperties& props, const Options& options) {
+ std::string device_name(props.properties.deviceName);
+ std::string output_file = options.output_file;
+ if (output_file.empty())
+ output_file = device_name + ".json";
+ FILE* file = nullptr;
+ if (output_file == "-") {
+ file = stdout;
+ } else {
+ file = fopen(output_file.c_str(), "w");
+ if (!file) {
+ std::cerr << "Unable to open file " << output_file << "." << std::endl;
+ return false;
+ }
+ }
+
+ std::string json = VkJsonAllPropertiesToJson(props) + '\n';
+ fwrite(json.data(), 1, json.size(), file);
+
+ if (output_file != "-") {
+ fclose(file);
+ std::cout << "Wrote file " << output_file << " for device " << device_name
+ << "." << std::endl;
+ }
+ return true;
+}
+
+int main(int argc, char* argv[]) {
+ Options options;
+ if (!ParseOptions(argc, argv, &options))
+ return 1;
+
+ const VkApplicationInfo app_info = {VK_STRUCTURE_TYPE_APPLICATION_INFO,
+ nullptr,
+ "vkjson_info",
+ 1,
+ "",
+ 0,
+ VK_API_VERSION};
+ VkInstanceCreateInfo instance_info = {VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
+ nullptr,
+ 0,
+ &app_info,
+ 0,
+ nullptr,
+ 0,
+ nullptr};
+ VkInstance instance;
+ VkResult result = vkCreateInstance(&instance_info, nullptr, &instance);
+ if (result != VK_SUCCESS) {
+ std::cerr << "Error: vkCreateInstance failed with error: " << result
+ << "." << std::endl;
+ return 1;
+ }
+
+ uint32_t device_count = 0;
+ result = vkEnumeratePhysicalDevices(instance, &device_count, nullptr);
+ if (result != VK_SUCCESS) {
+ std::cerr << "Error: vkEnumeratePhysicalDevices failed with error "
+ << result << "." << std::endl;
+ return 1;
+ }
+ if (device_count == 0) {
+ std::cerr << "Error: no Vulkan device found.";
+ return 1;
+ }
+
+ std::vector<VkPhysicalDevice> physical_devices(device_count,
+ VkPhysicalDevice());
+ result = vkEnumeratePhysicalDevices(instance, &device_count,
+ physical_devices.data());
+ if (result != VK_SUCCESS) {
+ std::cerr << "Error: vkEnumeratePhysicalDevices failed with error "
+ << result << std::endl;
+ return 1;
+ }
+
+ if (options.device_index != -1u) {
+ if (static_cast<uint32_t>(options.device_index) >= device_count) {
+ std::cerr << "Error: device " << options.device_index
+ << " requested but only " << device_count << " found."
+ << std::endl;
+ return 1;
+ }
+ auto props = VkJsonGetAllProperties(physical_devices[options.device_index]);
+ if (!DumpProperties(props, options))
+ return 1;
+ return 0;
+ }
+
+ bool found = false;
+ for (auto physical_device : physical_devices) {
+ auto props = VkJsonGetAllProperties(physical_device);
+ if (!options.device_name.empty() &&
+ options.device_name != props.properties.deviceName)
+ continue;
+ if (!DumpProperties(props, options))
+ return 1;
+ found = true;
+ }
+
+ if (!found) {
+ std::cerr << "Error: device " << options.device_name << " not found."
+ << std::endl;
+ return 1;
+ }
+ return 0;
+}