From 2bfd6a752dc6cb26ceda4ec9d56e7dce98527680 Mon Sep 17 00:00:00 2001 From: Charles Giessen Date: Tue, 22 Sep 2020 17:39:45 -0600 Subject: vulkaninfo: Add json output for portability subset Print the Properties and Features of the KHR_porability_subset. Requires a driver which supports the extension to get any usable output. Change-Id: I45d0d63108f0542868207247d0e6ec42b5a84b67 --- vulkaninfo/outputprinter.h | 19 ++------ vulkaninfo/vulkaninfo.cpp | 117 +++++++++++++++++++++++++++++++++++++-------- vulkaninfo/vulkaninfo.h | 1 + vulkaninfo/vulkaninfo.md | 33 +++++++------ 4 files changed, 121 insertions(+), 49 deletions(-) diff --git a/vulkaninfo/outputprinter.h b/vulkaninfo/outputprinter.h index ee3078be..42e15e4e 100644 --- a/vulkaninfo/outputprinter.h +++ b/vulkaninfo/outputprinter.h @@ -67,7 +67,8 @@ enum class OutputType { text, html, json, vkconfig_output }; class Printer { public: - Printer(OutputType output_type, std::ostream &out, const uint32_t selected_gpu, const VulkanVersion vulkan_version) + Printer(OutputType output_type, std::ostream &out, const uint32_t selected_gpu, const VulkanVersion vulkan_version, + std::string start_string = "") : output_type(output_type), out(out) { switch (output_type) { case (OutputType::text): @@ -75,7 +76,6 @@ class Printer { out << "VULKANINFO\n"; out << "==========\n\n"; out << "Vulkan Instance Version: " << VkVersionString(vulkan_version) << "\n\n\n"; - break; case (OutputType::html): out << "\n"; @@ -172,20 +172,9 @@ class Printer { indents += 3; break; case (OutputType::json): - out << "{\n"; - out << "\t\"$schema\": \"https://schema.khronos.org/vulkan/devsim_1_0_0.json#\",\n"; - out << "\t\"comments\": {\n"; - out << "\t\t\"desc\": \"JSON configuration file describing GPU " << selected_gpu - << ". Generated using the vulkaninfo program.\",\n"; - out << "\t\t\"vulkanApiVersion\": \"" << VkVersionString(vulkan_version) << "\"\n"; - out << "\t}"; - indents++; - is_first_item.push(false); - is_array.push(false); - break; + /* fall through */ case (OutputType::vkconfig_output): - out << "{\n"; - out << "\t\"Vulkan Instance Version\": \"" << VkVersionString(vulkan_version) << "\""; + out << start_string; indents++; is_first_item.push(false); is_array.push(false); diff --git a/vulkaninfo/vulkaninfo.cpp b/vulkaninfo/vulkaninfo.cpp index 56f12894..e8f7a5d7 100644 --- a/vulkaninfo/vulkaninfo.cpp +++ b/vulkaninfo/vulkaninfo.cpp @@ -766,6 +766,38 @@ void DumpSummaryGPU(Printer &p, AppGpu &gpu) { } } +#if defined(VK_ENABLE_BETA_EXTENSIONS) +void DumpPortability(Printer &p, AppGpu &gpu) { + if (gpu.CheckPhysicalDeviceExtensionIncluded(VK_KHR_PORTABILITY_SUBSET_EXTENSION_NAME)) { + if (gpu.inst.CheckExtensionEnabled(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) { + void *props_place = gpu.props2.pNext; + while (props_place) { + struct VkStructureHeader *structure = (struct VkStructureHeader *)props_place; + if (structure->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PORTABILITY_SUBSET_PROPERTIES_KHR) { + VkPhysicalDevicePortabilitySubsetPropertiesKHR *props = + (VkPhysicalDevicePortabilitySubsetPropertiesKHR *)structure; + DumpVkPhysicalDevicePortabilitySubsetPropertiesKHR(p, "VkPhysicalDevicePortabilitySubsetPropertiesKHR", *props); + break; + } + props_place = structure->pNext; + } + + void *feats_place = gpu.features2.pNext; + while (feats_place) { + struct VkStructureHeader *structure = (struct VkStructureHeader *)feats_place; + if (structure->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PORTABILITY_SUBSET_FEATURES_KHR) { + VkPhysicalDevicePortabilitySubsetFeaturesKHR *features = + (VkPhysicalDevicePortabilitySubsetFeaturesKHR *)structure; + DumpVkPhysicalDevicePortabilitySubsetFeaturesKHR(p, "VkPhysicalDevicePortabilitySubsetFeaturesKHR", *features); + break; + } + feats_place = structure->pNext; + } + } + } +} +#endif // defined(VK_ENABLE_BETA_EXTENSIONS) + // ============ Printing Logic ============= // #ifdef _WIN32 @@ -797,20 +829,25 @@ void print_usage(const char *argv0) { std::cout << "\nvulkaninfo - Summarize Vulkan information in relation to the current environment.\n\n"; std::cout << "USAGE: " << argv0 << " [options]\n\n"; std::cout << "OPTIONS:\n"; - std::cout << "-h, --help Print this help.\n"; - std::cout << "--html Produce an html version of vulkaninfo output, saved as\n"; - std::cout << " \"vulkaninfo.html\" in the directory in which the command is\n"; - std::cout << " run.\n"; - std::cout << "-j, --json Produce a json version of vulkaninfo to standard output of the\n"; - std::cout << " first gpu in the system conforming to the DevSim schema.\n"; - std::cout << "--json= For a multi-gpu system, a single gpu can be targetted by\n"; - std::cout << " specifying the gpu-number associated with the gpu of \n"; - std::cout << " interest. This number can be determined by running\n"; - std::cout << " vulkaninfo without any options specified.\n"; - std::cout << "--show-formats Display the format properties of each physical device.\n"; - std::cout << " Note: This option does not affect html or json output;\n"; - std::cout << " they will always print format properties.\n\n"; - std::cout << "--summary Show a summary of the instance and GPU's on a system.\n\n"; + std::cout << "-h, --help Print this help.\n"; + std::cout << "--html Produce an html version of vulkaninfo output, saved as\n"; + std::cout << " \"vulkaninfo.html\" in the directory in which the command\n"; + std::cout << " is run.\n"; + std::cout << "-j, --json Produce a json version of vulkaninfo to standard output of the\n"; + std::cout << " first gpu in the system conforming to the DevSim schema.\n"; + std::cout << "--json= For a multi-gpu system, a single gpu can be targetted by\n"; + std::cout << " specifying the gpu-number associated with the gpu of \n"; + std::cout << " interest. This number can be determined by running\n"; + std::cout << " vulkaninfo without any options specified.\n"; + std::cout << "--portability Produce a json version of vulkaninfo to standard output of the first\n"; + std::cout << " gpu in the system conforming to the DevSim Portability Subset schema.\n"; + std::cout << "--portability= Produce the json output conforming to the DevSim Portability\n"; + std::cout << " Subset Schema for the GPU specified to standard output,\n"; + std::cout << " where N is the GPU desired.\n"; + std::cout << "--show-formats Display the format properties of each physical device.\n"; + std::cout << " Note: This option does not affect html or json output;\n"; + std::cout << " they will always print format properties.\n\n"; + std::cout << "--summary Show a summary of the instance and GPU's on a system.\n\n"; } int main(int argc, char **argv) { @@ -842,6 +879,14 @@ int main(int argc, char **argv) { } human_readable_output = false; json_output = true; + portability_json = false; + } else if (strncmp("--portability", argv[i], 13) == 0) { + if (strlen(argv[i]) > 14 && strncmp("--portability=", argv[i], 14) == 0) { + selected_gpu = static_cast(strtol(argv[i] + 14, nullptr, 10)); + } + human_readable_output = false; + portability_json = true; + json_output = false; } else if (strcmp(argv[i], "--summary") == 0) { summary = true; } else if (strcmp(argv[i], "--html") == 0) { @@ -893,7 +938,11 @@ int main(int argc, char **argv) { } if (selected_gpu >= gpus.size()) { - std::cout << "The selected gpu (" << selected_gpu << ") is not in the valid range of 0 to " << gpus.size() - 1 << ".\n"; + std::cout << "The selected gpu (" << selected_gpu << ") is not a valid GPU index. "; + 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; } @@ -906,7 +955,30 @@ int main(int argc, char **argv) { std::unique_ptr(new Printer(OutputType::html, html_out, selected_gpu, instance.vk_version))); } if (json_output) { - printers.push_back(std::unique_ptr(new Printer(OutputType::json, out, selected_gpu, instance.vk_version))); + 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) + + ". Generated using the vulkaninfo program.\",\n\t\t\"vulkanApiVersion\": \"" + + VkVersionString(instance.vk_version) + "\"\n" + "\t}"; + printers.push_back( + std::unique_ptr(new Printer(OutputType::json, out, selected_gpu, instance.vk_version, start_string))); + } + if (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"; + } 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 portability features and properties. Generated using the vulkaninfo program.\",\n\t\t\"vulkanApiVersion\": " + "\"" + + VkVersionString(instance.vk_version) + "\"\n" + "\t}"; + printers.push_back( + std::unique_ptr(new Printer(OutputType::json, out, selected_gpu, instance.vk_version, start_string))); + } } if (vkconfig_output) { #ifdef WIN32 @@ -914,8 +986,9 @@ int main(int argc, char **argv) { #else vkconfig_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( - new Printer(OutputType::vkconfig_output, vkconfig_out, selected_gpu, instance.vk_version))); + new Printer(OutputType::vkconfig_output, vkconfig_out, selected_gpu, instance.vk_version, start_string))); } for (auto &p : printers) { @@ -928,10 +1001,14 @@ int main(int argc, char **argv) { DumpSummaryGPU(*p.get(), *gpu.get()); } } else if (p->Type() == OutputType::json) { - DumpLayers(*p.get(), instance.global_layers, gpus); - DumpGpuJson(*p.get(), *gpus.at(selected_gpu).get()); - + if (portability_json) { + DumpPortability(*p.get(), *gpus.at(selected_gpu).get()); + } else if (json_output) { + 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(); diff --git a/vulkaninfo/vulkaninfo.h b/vulkaninfo/vulkaninfo.h index 21a83cba..04e40d6b 100644 --- a/vulkaninfo/vulkaninfo.h +++ b/vulkaninfo/vulkaninfo.h @@ -113,6 +113,7 @@ bool human_readable_output = true; bool html_output = false; bool json_output = false; bool vkconfig_output = false; +bool portability_json = false; bool summary = false; #ifdef _WIN32 diff --git a/vulkaninfo/vulkaninfo.md b/vulkaninfo/vulkaninfo.md index 696025b9..1546b8cf 100644 --- a/vulkaninfo/vulkaninfo.md +++ b/vulkaninfo/vulkaninfo.md @@ -53,20 +53,25 @@ vulkaninfo - Summarize Vulkan information in relation to the current environment USAGE: ./vulkaninfo [options] OPTIONS: --h, --help Print this help. ---html Produce an html version of vulkaninfo output, saved as - "vulkaninfo.html" in the directory in which the command is - run. --j, --json Produce a json version of vulkaninfo output to standard - output. ---json= For a multi-gpu system, a single gpu can be targetted by - specifying the gpu-number associated with the gpu of - interest. This number can be determined by running - vulkaninfo without any options specified. ---show-formats Display the format properties of each physical device. - Note: This option does not affect html or json output; - they will always print format properties. ---summary Show a summary of the instance and GPU's on a system. +-h, --help Print this help. +--html Produce an html version of vulkaninfo output, saved as + "vulkaninfo.html" in the directory in which the command is + run. +-j, --json Produce a json version of vulkaninfo output to standard + output. +--json= For a multi-gpu system, a single gpu can be targetted by + specifying the gpu-number associated with the gpu of + interest. This number can be determined by running + vulkaninfo without any options specified. +--portability Produce a json version of vulkaninfo to standard output of the first + gpu in the system conforming to the DevSim Portability Subset schema. +--portability= Produce the json output conforming to the DevSim Portability + Subset Schema for the GPU specified to standard output + where N is the GPU desired. +--show-formats Display the format properties of each physical device. + Note: This option does not affect html or json output; + they will always print format properties. +--summary Show a summary of the instance and GPU's on a system. ``` ### Windows -- cgit v1.2.3