aboutsummaryrefslogtreecommitdiff
path: root/vulkaninfo/vulkaninfo.cpp
diff options
context:
space:
mode:
authorCharles Giessen <charles@lunarg.com>2021-06-18 18:32:32 -0600
committerCharles Giessen <46324611+charles-lunarg@users.noreply.github.com>2021-11-29 13:03:31 -0700
commit181bcce094cefd4df30861b760ff1779bfb65fce (patch)
treea76add366ff71390c5756cfb326c3292c4a4cac8 /vulkaninfo/vulkaninfo.cpp
parentde6e3eed59dca4e8e9875e2c08255cc41322d8d4 (diff)
downloadusermoji-181bcce094cefd4df30861b760ff1779bfb65fce.tar.xz
vulkaninfo: Refactor main function
The main funciton was a chonky 300+ lines of code, this commit pulls out some of the sections into their own functions to make it easier to read. It also simplifies the logic in many places by doing so.
Diffstat (limited to 'vulkaninfo/vulkaninfo.cpp')
-rw-r--r--vulkaninfo/vulkaninfo.cpp341
1 files changed, 186 insertions, 155 deletions
diff --git a/vulkaninfo/vulkaninfo.cpp b/vulkaninfo/vulkaninfo.cpp
index ef172bbf..70cb30f7 100644
--- a/vulkaninfo/vulkaninfo.cpp
+++ b/vulkaninfo/vulkaninfo.cpp
@@ -841,66 +841,183 @@ void print_usage(const char *argv0) {
std::cout << "--summary Show a summary of the instance and GPU's on a system.\n\n";
}
-#ifdef VK_USE_PLATFORM_IOS_MVK
-// On iOS, we'll call this ourselves from a parent routine in the GUI
-int vulkanInfoMain(int argc, char **argv) {
-#else
-int main(int argc, char **argv) {
-#endif
- OutputCategory output_category = OutputCategory::text;
- uint32_t selected_gpu = 0;
- bool show_tool_props = false;
- bool show_formats = false;
- char *output_path = nullptr;
-
-#ifdef _WIN32
- if (ConsoleIsExclusive()) ConsoleEnlarge();
- User32Handles local_user32_handles;
- user32_handles = &local_user32_handles;
- if (local_user32_handles.load()) {
- fprintf(stderr, "Failed to load user32.dll library!\n");
- if (output_category == OutputCategory::text) wait_for_console_destroy();
- exit(1);
- }
-#endif
+struct ParsedResults {
+ OutputCategory output_category;
+ uint32_t selected_gpu;
+ bool has_selected_gpu; // differentiate between selecting the 0th gpu and using the default 0th value
+ bool show_tool_props;
+ bool show_formats;
+ char *output_path;
+};
- // Combinations of output: html only, html AND json, json only, human readable only
+util::trivial_optional<ParsedResults> parse_arguments(int argc, char **argv) {
+ ParsedResults results{}; // default it to zero init everything
for (int i = 1; i < argc; ++i) {
// A internal-use-only format for communication with the Vulkan Configurator tool
// Usage "--vkconfig_output <path>"
if (0 == strcmp("--vkconfig_output", argv[i]) && argc > (i + 1)) {
- output_category = OutputCategory::vkconfig_output;
- output_path = argv[i + 1];
+ results.output_category = OutputCategory::vkconfig_output;
+ results.output_path = argv[i + 1];
++i;
} else if (strncmp("--json", argv[i], 6) == 0 || strcmp(argv[i], "-j") == 0) {
if (strlen(argv[i]) > 7 && strncmp("--json=", argv[i], 7) == 0) {
- selected_gpu = static_cast<uint32_t>(strtol(argv[i] + 7, nullptr, 10));
+ results.selected_gpu = static_cast<uint32_t>(strtol(argv[i] + 7, nullptr, 10));
+ results.has_selected_gpu = true;
}
- output_category = OutputCategory::devsim_json;
+ results.output_category = OutputCategory::devsim_json;
#if defined(VK_ENABLE_BETA_EXTENSIONS)
} else if (strncmp("--portability", argv[i], 13) == 0) {
if (strlen(argv[i]) > 14 && strncmp("--portability=", argv[i], 14) == 0) {
- selected_gpu = static_cast<uint32_t>(strtol(argv[i] + 14, nullptr, 10));
+ results.selected_gpu = static_cast<uint32_t>(strtol(argv[i] + 14, nullptr, 10));
}
- output_category = OutputCategory::portability_json;
+ results.output_category = OutputCategory::portability_json;
#endif // defined(VK_ENABLE_BETA_EXTENSIONS)
} else if (strcmp(argv[i], "--summary") == 0) {
- output_category = OutputCategory::summary;
+ results.output_category = OutputCategory::summary;
} else if (strcmp(argv[i], "--html") == 0) {
- output_category = OutputCategory::html;
} else if (strcmp(argv[i], "--show-tool-props") == 0) {
- show_tool_props = true;
+ results.show_tool_props = true;
} else if (strcmp(argv[i], "--show-formats") == 0) {
- show_formats = true;
- } else if (strcmp(argv[i], "--help") == 0 || strcmp(argv[i], "-h") == 0) {
print_usage(argv[0]);
- return 1;
+ return {};
} else {
print_usage(argv[0]);
- return 1;
+ return {};
+ }
+ }
+ return results;
+}
+struct PrinterCreateDetails {
+ OutputType output_type = OutputType::text;
+ bool use_file_output = false;
+ std::string file_name = "vulkaninfo.txt";
+ std::string start_string = "";
+};
+
+PrinterCreateDetails get_printer_create_details(ParsedResults &parse_data, AppInstance &inst, AppGpu &selected_gpu) {
+ PrinterCreateDetails create{};
+
+ switch (parse_data.output_category) {
+ default:
+ case (OutputCategory::text):
+ // Default values are for the text output
+ break;
+ case (OutputCategory::html):
+ create.output_type = OutputType::html;
+ create.file_name = "vulkaninfo.html";
+ create.use_file_output = true;
+ break;
+ case (OutputCategory::devsim_json):
+ create.output_type = OutputType::json;
+ create.start_string = std::string("{\n\t\"$schema\": \"https://schema.khronos.org/vulkan/devsim_1_0_0.json#\",\n") +
+ "\t\"comments\": {\n\t\t\"desc\": \"JSON configuration file describing GPU " +
+ std::to_string(parse_data.selected_gpu) + " (" + selected_gpu.props.deviceName +
+ "). Generated using the vulkaninfo program.\",\n\t\t\"vulkanApiVersion\": \"" +
+ VkVersionString(inst.vk_version) + "\"\n" + "\t}";
+#ifdef VK_USE_PLATFORM_IOS_MVK
+ create.file_name = "vulkaninfo.json";
+ create.use_file_output = true;
+#endif
+ break;
+#if defined(VK_ENABLE_BETA_EXTENSIONS)
+ case (OutputCategory::portability_json):
+ create.output_type = OutputType::json;
+ create.start_string =
+ std::string(
+ "{\n\t\"$schema\": "
+ "\"https://schema.khronos.org/vulkan/devsim_VK_KHR_portability_subset-provisional-1.json#\",\n") +
+ "\t\"comments\": {\n\t\t\"desc\": \"JSON configuration file describing GPU " +
+ std::to_string(parse_data.selected_gpu) + "'s (" + selected_gpu.props.deviceName +
+ "( portability features and properties. Generated using the vulkaninfo "
+ "program.\",\n\t\t\"vulkanApiVersion\": "
+ "\"" +
+ VkVersionString(inst.vk_version) + "\"\n" + "\t}";
+#ifdef VK_USE_PLATFORM_IOS_MVK
+ create.file_name = "portability.json";
+ create.use_file_output = true;
+#endif
+ break;
+#endif // defined(VK_ENABLE_BETA_EXTENSIONS)
+
+ case (OutputCategory::vkconfig_output):
+ create.output_type = OutputType::vkconfig_output;
+#ifdef WIN32
+ create.file_name = std::string(parse_data.output_path) + "\\vulkaninfo.json";
+#else
+ create.file_name = std::string(parse_data.output_path) + "/vulkaninfo.json";
+#endif
+ create.use_file_output = true;
+ create.start_string = "{\n\t\"Vulkan Instance Version\": \"" + VkVersionString(inst.vk_version) + "\"";
+ break;
+ }
+ return create;
+}
+
+void RunPrinter(Printer &p, ParsedResults parse_data, AppInstance &instance, std::vector<std::unique_ptr<AppGpu>> &gpus,
+ std::vector<std::unique_ptr<AppSurface>> &surfaces) {
+#ifdef VK_USE_PLATFORM_IOS_MVK
+ p.SetAlwaysOpenDetails(true);
+#endif
+ if (parse_data.output_category == OutputCategory::summary) {
+ DumpSummaryInstance(p, instance);
+ p.SetHeader();
+ ObjectWrapper obj(p, "Devices");
+ IndentWrapper indent(p);
+ for (auto &gpu : gpus) {
+ DumpSummaryGPU(p, *(gpu.get()));
+ }
+ }
+#if defined(VK_ENABLE_BETA_EXTENSIONS)
+ else if (parse_data.output_category == OutputCategory::portability_json) {
+ DumpPortability(p, *(gpus.at(parse_data.selected_gpu).get()));
+#endif // defined(VK_ENABLE_BETA_EXTENSIONS)
+ } else if (parse_data.output_category == OutputCategory::devsim_json) {
+ DumpLayers(p, instance.global_layers, gpus);
+ DumpGpuJson(p, *(gpus.at(parse_data.selected_gpu).get()));
+ } else {
+ // text, html, vkconfig_output
+ p.SetHeader();
+ DumpExtensions(p, "Instance", instance.global_extensions);
+ p.AddNewline();
+
+ DumpLayers(p, instance.global_layers, gpus);
+ // Doesn't print anything if no surfaces are available
+ DumpPresentableSurfaces(p, instance, gpus, surfaces);
+ DumpGroups(p, instance);
+
+ p.SetHeader();
+ ObjectWrapper obj(p, "Device Properties and Extensions");
+ IndentWrapper indent(p);
+
+ for (auto &gpu : gpus) {
+ DumpGpu(p, *(gpu.get()), parse_data.show_tool_props, parse_data.show_formats);
}
}
- std::vector<std::unique_ptr<Printer>> printers;
+}
+
+#ifdef VK_USE_PLATFORM_IOS_MVK
+// On iOS, we'll call this ourselves from a parent routine in the GUI
+int vulkanInfoMain(int argc, char **argv) {
+#else
+int main(int argc, char **argv) {
+#endif
+
+ auto parsing_return = parse_arguments(argc, argv);
+ if (!parsing_return) return 1;
+ ParsedResults parse_data = parsing_return.value();
+
+#ifdef _WIN32
+ if (ConsoleIsExclusive()) ConsoleEnlarge();
+ User32Handles local_user32_handles;
+ user32_handles = &local_user32_handles;
+ if (!local_user32_handles.load()) {
+ fprintf(stderr, "Failed to load user32.dll library!\n");
+ if (parse_data.output_category == OutputCategory::text) wait_for_console_destroy();
+ return 1;
+ }
+#endif
+
+ std::unique_ptr<Printer> printer;
std::ostream out(std::cout.rdbuf());
std::ofstream file_out;
@@ -930,123 +1047,41 @@ int main(int argc, char **argv) {
gpus.push_back(std::unique_ptr<AppGpu>(new AppGpu(instance, gpu_counter++, phys_device, pNext_chains)));
}
- if (selected_gpu >= gpus.size()) {
- std::cout << "The selected gpu (" << selected_gpu << ") is not a valid GPU index. ";
- if (gpus.size() == 0)
- std::cout << "There are no available GPUs.\n";
- else if (gpus.size() == 1)
- std::cout << "The only available GPU selection is 0.\n";
- else
- std::cout << "The available GPUs are in the range of 0 to " << gpus.size() - 1 << ".\n";
- return 0;
- }
- switch (output_category) {
- default:
- case (OutputCategory::text):
- printers.push_back(std::unique_ptr<Printer>(new Printer(OutputType::text, out, selected_gpu, instance.vk_version)));
- break;
- case (OutputCategory::html):
- file_out = std::ofstream("vulkaninfo.html");
- printers.push_back(
- std::unique_ptr<Printer>(new Printer(OutputType::html, file_out, selected_gpu, instance.vk_version)));
- break;
- case (OutputCategory::devsim_json): {
- std::string start_string =
- std::string("{\n\t\"$schema\": \"https://schema.khronos.org/vulkan/devsim_1_0_0.json#\",\n") +
- "\t\"comments\": {\n\t\t\"desc\": \"JSON configuration file describing GPU " + std::to_string(selected_gpu) +
- " (" + gpus.at(selected_gpu)->props.deviceName +
- "). Generated using the vulkaninfo program.\",\n\t\t\"vulkanApiVersion\": \"" +
- VkVersionString(instance.vk_version) + "\"\n" + "\t}";
-#ifdef VK_USE_PLATFORM_IOS_MVK
- file_out = std::ofstream("vulkaninfo.json");
- printers.push_back(std::unique_ptr<Printer>(
- new Printer(OutputType::json, file_out, selected_gpu, instance.vk_version, start_string)));
-#else
- printers.push_back(
- std::unique_ptr<Printer>(new Printer(OutputType::json, out, selected_gpu, instance.vk_version, start_string)));
-#endif
- } break;
-#if defined(VK_ENABLE_BETA_EXTENSIONS)
- case (OutputCategory::portability_json):
- if (!gpus.at(selected_gpu)->CheckPhysicalDeviceExtensionIncluded(VK_KHR_PORTABILITY_SUBSET_EXTENSION_NAME)) {
- std::cerr << "Cannot create a json because the current selected GPU (" << selected_gpu
- << ") does not support the VK_KHR_portability_subset extension.\n";
+ if (parse_data.selected_gpu >= gpus.size()) {
+ if (parse_data.has_selected_gpu) {
+ std::cout << "The selected gpu (" << parse_data.selected_gpu << ") is not a valid GPU index. ";
+ if (gpus.size() == 0) {
+ std::cout << "vulkaninfo could not find any GPU's.\n";
+ }
+ if (gpus.size() == 1) {
+ std::cout << "The only available GPU selection is 0.\n";
} else {
- std::string start_string =
- std::string(
- "{\n\t\"$schema\": "
- "\"https://schema.khronos.org/vulkan/devsim_VK_KHR_portability_subset-provisional-1.json#\",\n") +
- "\t\"comments\": {\n\t\t\"desc\": \"JSON configuration file describing GPU " +
- std::to_string(selected_gpu) + "'s (" + gpus.at(selected_gpu)->props.deviceName +
- "( portability features and properties. Generated using the vulkaninfo "
- "program.\",\n\t\t\"vulkanApiVersion\": "
- "\"" +
- VkVersionString(instance.vk_version) + "\"\n" + "\t}";
-#ifdef VK_USE_PLATFORM_IOS_MVK
- portability_out = std::ofstream("portability.json");
- printers.push_back(std::unique_ptr<Printer>(
- new Printer(OutputType::json, portability_out, selected_gpu, instance.vk_version, start_string)));
-#else
- printers.push_back(std::unique_ptr<Printer>(
- new Printer(OutputType::json, out, selected_gpu, instance.vk_version, start_string)));
-#endif
+ std::cout << "The available GPUs are in the range of 0 to " << gpus.size() - 1 << ".\n";
}
- break;
-#endif // defined(VK_ENABLE_BETA_EXTENSIONS)
- case (OutputCategory::vkconfig_output): {
-#ifdef WIN32
- file_out = std::ofstream(std::string(output_path) + "\\vulkaninfo.json");
-#else
- file_out = std::ofstream(std::string(output_path) + "/vulkaninfo.json");
-#endif
- std::string start_string = "{\n\t\"Vulkan Instance Version\": \"" + VkVersionString(instance.vk_version) + "\"";
- printers.push_back(std::unique_ptr<Printer>(
- new Printer(OutputType::vkconfig_output, file_out, selected_gpu, instance.vk_version, start_string)));
- break;
+ return 1;
+ } else if (parse_data.output_category == OutputCategory::devsim_json ||
+ parse_data.output_category == OutputCategory::portability_json) {
+ std::cout << "vulkaninfo could not find any GPU's.\n";
}
}
- for (auto &p : printers) {
-#ifdef VK_USE_PLATFORM_IOS_MVK
- p->SetAlwaysOpenDetails(true);
-#endif
- if (output_category == OutputCategory::summary) {
- DumpSummaryInstance(*p.get(), instance);
- p->SetHeader();
- ObjectWrapper obj(*p, "Devices");
- IndentWrapper indent(*p);
- for (auto &gpu : gpus) {
- DumpSummaryGPU(*p.get(), *gpu.get());
- }
- } else if (p->Type() == OutputType::json) {
- if (output_category == OutputCategory::portability_json) {
#if defined(VK_ENABLE_BETA_EXTENSIONS)
- DumpPortability(*p.get(), *gpus.at(selected_gpu).get());
-#endif // defined(VK_ENABLE_BETA_EXTENSIONS)
- } else if (output_category == OutputCategory::devsim_json) {
- DumpLayers(*p.get(), instance.global_layers, gpus);
- DumpGpuJson(*p.get(), *gpus.at(selected_gpu).get());
- }
- } else {
- // text, html, vkconfig_output
- p->SetHeader();
- DumpExtensions(*p.get(), "Instance", instance.global_extensions);
- p->AddNewline();
-
- DumpLayers(*p.get(), instance.global_layers, gpus);
- // Doesn't print anything if no surfaces are available
- DumpPresentableSurfaces(*p.get(), instance, gpus, surfaces);
- DumpGroups(*p.get(), instance);
-
- p->SetHeader();
- ObjectWrapper obj(*p, "Device Properties and Extensions");
- IndentWrapper indent(*p);
+ if (parse_data.output_category == OutputCategory::portability_json &&
+ !gpus.at(parse_data.selected_gpu)->CheckPhysicalDeviceExtensionIncluded(VK_KHR_PORTABILITY_SUBSET_EXTENSION_NAME)) {
+ std::cerr << "Cannot create a json because the current selected GPU (" << parse_data.selected_gpu
+ << ") does not support the VK_KHR_portability_subset extension.\n";
+ return 1;
+ }
+#endif
- for (auto &gpu : gpus) {
- DumpGpu(*p.get(), *gpu.get(), show_tool_props, show_formats);
- }
- }
+ auto printer_data = get_printer_create_details(parse_data, instance, *gpus.at(parse_data.selected_gpu));
+ if (printer_data.use_file_output) {
+ file_out = std::ofstream(printer_data.file_name);
}
+ printer = std::unique_ptr<Printer>(new Printer(printer_data.output_type, printer_data.use_file_output ? file_out : out,
+ parse_data.selected_gpu, instance.vk_version, printer_data.start_string));
+
+ RunPrinter(*(printer.get()), parse_data, instance, gpus, surfaces);
for (auto &surface_extension : instance.surface_extensions) {
AppDestroySurface(instance, surface_extension.surface);
@@ -1055,19 +1090,15 @@ int main(int argc, char **argv) {
} catch (std::exception &e) {
// Print the error to stderr and leave all outputs in a valid state (mainly for json)
std::cerr << "ERROR at " << e.what() << "\n";
- for (auto &p : printers) {
- if (p) {
- p->FinishOutput();
- }
+ if (printer) {
+ printer->FinishOutput();
}
}
- // Call the printer's descrtuctor before the file handle gets closed
- for (auto &p : printers) {
- p.reset(nullptr);
- }
+ // Call the printer's destructor before the file handle gets closed
+ printer.reset(nullptr);
#ifdef _WIN32
- if (output_category == OutputCategory::text) wait_for_console_destroy();
+ if (parse_data.output_category == OutputCategory::text) wait_for_console_destroy();
#endif
return 0;