diff options
| author | Charles Giessen <charles@lunarg.com> | 2019-10-17 16:21:45 -0600 |
|---|---|---|
| committer | Charles Giessen <46324611+charles-lunarg@users.noreply.github.com> | 2020-02-12 16:00:18 -0700 |
| commit | db0a1553991d3d00ee58a7c0de3510ca1415eb75 (patch) | |
| tree | 1a8dce2be39faf43be853a28c89ce3537701a988 /vulkaninfo/vulkaninfo.cpp | |
| parent | 45b9d01815d916a61c66c0c178aad132e19ada47 (diff) | |
| download | usermoji-db0a1553991d3d00ee58a7c0de3510ca1415eb75.tar.xz | |
vulkaninfo: new vkconfig_output backdend
This commit adds a new backend, vkconfig_output, that prints the same information
as the text & html versions in a json format. This output will only be used in
vkconfig. Therefore it does not have a documented flag, but it is accesible with
'--vkconfig_output'.
Many parts of the code needed refactoring to handle the vkconfig_output output.
Replacing PrintElement with PrintString, requiring StartObject instead of
StartArray, and removing many branches to make the code simpler to read.
vkconfig_output does not nest json objects within json arrays, thus keeping every
non-leaf node of a json object named.
files modified
- scripts/vulkaninfo_generator.py
- vulkaninfo/generated/vulkaninfo.hpp
- vulkaninfo/outputprinter.h
- vulkaninfo/vulkaninfo.cpp
- vulkaninfo/vulkaninfo.h
Change-Id: I33d036a75b65942db1ad62b2a1e0c341a2b5e36c
Diffstat (limited to 'vulkaninfo/vulkaninfo.cpp')
| -rw-r--r-- | vulkaninfo/vulkaninfo.cpp | 657 |
1 files changed, 358 insertions, 299 deletions
diff --git a/vulkaninfo/vulkaninfo.cpp b/vulkaninfo/vulkaninfo.cpp index 7068548c..a0b843aa 100644 --- a/vulkaninfo/vulkaninfo.cpp +++ b/vulkaninfo/vulkaninfo.cpp @@ -57,11 +57,10 @@ void DumpExtensions(Printer &p, std::string layer_name, std::vector<VkExtensionP } } - p.ArrayStart(layer_name + " Extensions", extensions.size()); + ObjectWrapper obj(p, layer_name + " Extensions", extensions.size()); for (auto &ext : extensions) { p.PrintExtension(ext.extensionName, ext.specVersion, max_length); } - p.ArrayEnd(); } void DumpLayers(Printer &p, std::vector<LayerExtensionList> layers, const std::vector<std::unique_ptr<AppGpu>> &gpus) { @@ -70,74 +69,89 @@ void DumpLayers(Printer &p, std::vector<LayerExtensionList> layers, const std::v const char *b = right.layer_properties.layerName; return a && (!b || std::strcmp(a, b) < 0); }); + switch (p.Type()) { + case OutputType::text: + case OutputType::html: { + p.SetHeader(); + ArrayWrapper arr(p, "Layers", layers.size()); + p.IndentDecrease(); + for (auto &layer : layers) { + auto v_str = VkVersionString(layer.layer_properties.specVersion); + auto props = layer.layer_properties; + + std::string header = p.DecorateAsType(props.layerName) + " (" + props.description + ") Vulkan version " + + p.DecorateAsValue(v_str) + ", layer version " + + p.DecorateAsValue(std::to_string(props.implementationVersion)); + ObjectWrapper obj(p, header); + DumpExtensions(p, "Layer", layer.extension_properties); + + ArrayWrapper arr(p, "Devices", gpus.size()); + for (auto &gpu : gpus) { + p.PrintKeyValue("GPU id", gpu->id, 0, gpu->props.deviceName); + auto exts = gpu->AppGetPhysicalDeviceLayerExtensions(props.layerName); + DumpExtensions(p, "Layer-Device", exts); + p.AddNewline(); + } + } + p.IndentIncrease(); + break; + } - if (p.Type() == OutputType::text || p.Type() == OutputType::html) { - p.SetHeader().ArrayStart("Layers", layers.size()); - p.IndentDecrease(); - for (auto &layer : layers) { - auto v_str = VkVersionString(layer.layer_properties.specVersion); - auto props = layer.layer_properties; - - std::string header; - if (p.Type() == OutputType::text) - header = std::string(props.layerName) + " (" + props.description + ") Vulkan version " + v_str + - ", layer version " + std::to_string(props.implementationVersion); - else if (p.Type() == OutputType::html) - header = std::string("<span class='type'>") + props.layerName + "</span> (" + props.description + - ") Vulkan version <span class='val'>" + v_str + "</span>, layer version <span class='val'>" + - std::to_string(props.implementationVersion) + "</span>"; - - p.ObjectStart(header); - DumpExtensions(p, "Layer", layer.extension_properties); - - p.ArrayStart("Devices", gpus.size()); - for (auto &gpu : gpus) { - p.PrintElement(std::string("GPU id \t: ") + std::to_string(gpu->id), gpu->props.deviceName); - auto exts = gpu->AppGetPhysicalDeviceLayerExtensions(props.layerName); - DumpExtensions(p, "Layer-Device", exts); - p.AddNewline(); + case OutputType::json: { + ArrayWrapper arr(p, "ArrayOfVkLayerProperties", layers.size()); + int i = 0; + for (auto &layer : layers) { + p.SetElementIndex(i++); + DumpVkLayerProperties(p, "layerProperty", layer.layer_properties); } - p.ArrayEnd(); - p.ObjectEnd(); + break; } - p.IndentIncrease(); - p.ArrayEnd(); - } else if (p.Type() == OutputType::json) { - p.ArrayStart("ArrayOfVkLayerProperties", layers.size()); - int i = 0; - for (auto &layer : layers) { - p.SetElementIndex(i++); - DumpVkLayerProperties(p, "layerProperty", layer.layer_properties); + case OutputType::vkconfig_output: { + ObjectWrapper obj(p, "Layer Properties"); + for (auto &layer : layers) { + ObjectWrapper obj_name(p, layer.layer_properties.layerName); + p.PrintKeyString("layerName", layer.layer_properties.layerName, 21); + p.PrintKeyString("version", VkVersionString(layer.layer_properties.specVersion), 21); + p.PrintKeyValue("implementation version", layer.layer_properties.implementationVersion, 21); + p.PrintKeyString("description", layer.layer_properties.description, 21); + DumpExtensions(p, "Layer", layer.extension_properties); + ObjectWrapper obj_devices(p, "Devices"); + for (auto &gpu : gpus) { + ObjectWrapper obj(p, gpu->props.deviceName); + p.PrintKeyValue("GPU id", gpu->id, 0, gpu->props.deviceName); + auto exts = gpu->AppGetPhysicalDeviceLayerExtensions(layer.layer_properties.layerName); + DumpExtensions(p, "Layer-Device", exts); + } + } + break; } - p.ArrayEnd(); } } void DumpSurfaceFormats(Printer &p, AppInstance &inst, AppSurface &surface) { - int i = 0; + std::vector<VkSurfaceFormatKHR> formats; if (inst.CheckExtensionEnabled(VK_KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME)) { - p.ArrayStart("Formats", surface.surf_formats2.size()); for (auto &format : surface.surf_formats2) { - p.SetElementIndex(i++); - DumpVkSurfaceFormatKHR(p, "SurfaceFormat", format.surfaceFormat); + formats.push_back(format.surfaceFormat); } - p.ArrayEnd(); } else { - p.ArrayStart("Formats", surface.surf_formats.size()); for (auto &format : surface.surf_formats) { - p.SetElementIndex(i++); - DumpVkSurfaceFormatKHR(p, "SurfaceFormat", format); + formats.push_back(format); } - p.ArrayEnd(); + } + ObjectWrapper obj(p, "Formats", formats.size()); + int i = 0; + for (auto &format : formats) { + p.SetElementIndex(i++); + DumpVkSurfaceFormatKHR(p, "SurfaceFormat", format); } } void DumpPresentModes(Printer &p, AppSurface &surface) { - p.ArrayStart("Present Modes", surface.surf_present_modes.size()); + ArrayWrapper arr(p, "Present Modes", surface.surf_present_modes.size()); for (auto &mode : surface.surf_present_modes) { - p.SetAsType().PrintElement(VkPresentModeKHRString(mode)); + p.SetAsType().PrintString(VkPresentModeKHRString(mode)); } - p.ArrayEnd(); } void DumpSurfaceCapabilities(Printer &p, AppInstance &inst, AppGpu &gpu, AppSurface &surface) { @@ -146,16 +160,15 @@ void DumpSurfaceCapabilities(Printer &p, AppInstance &inst, AppGpu &gpu, AppSurf DumpVkSurfaceCapabilitiesKHR(p, "VkSurfaceCapabilitiesKHR", surf_cap); if (inst.CheckExtensionEnabled(VK_EXT_DISPLAY_SURFACE_COUNTER_EXTENSION_NAME)) { - p.SetSubHeader().ObjectStart("VkSurfaceCapabilities2EXT"); + p.SetSubHeader(); + ObjectWrapper obj(p, "VkSurfaceCapabilities2EXT"); { - p.ObjectStart("supportedSurfaceCounters"); - if (surface.surface_capabilities2_ext.supportedSurfaceCounters == 0) p.PrintElement("None"); + ArrayWrapper arr(p, "supportedSurfaceCounters"); + if (surface.surface_capabilities2_ext.supportedSurfaceCounters == 0) p.PrintString("None"); if (surface.surface_capabilities2_ext.supportedSurfaceCounters & VK_SURFACE_COUNTER_VBLANK_EXT) { - p.SetAsType().PrintElement("VK_SURFACE_COUNTER_VBLANK_EXT"); + p.SetAsType().PrintString("VK_SURFACE_COUNTER_VBLANK_EXT"); } - p.ObjectEnd(); } - p.ObjectEnd(); // VkSurfaceCapabilities2EXT } if (inst.CheckExtensionEnabled(VK_KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME)) { chain_iterator_surface_capabilities2(p, inst, gpu, surface.surface_capabilities2_khr.pNext, inst.vk_version); @@ -163,30 +176,23 @@ void DumpSurfaceCapabilities(Printer &p, AppInstance &inst, AppGpu &gpu, AppSurf } void DumpSurface(Printer &p, AppInstance &inst, AppGpu &gpu, AppSurface &surface, std::set<std::string> surface_types) { - std::string header; - if (p.Type() == OutputType::text) - header = std::string("GPU id : ") + std::to_string(gpu.id) + " (" + gpu.props.deviceName + ")"; - else if (p.Type() == OutputType::html) - header = std::string("GPU id : <span class='val'>") + std::to_string(gpu.id) + "</span> (" + gpu.props.deviceName + ")"; - p.ObjectStart(header); + ObjectWrapper obj(p, std::string("GPU id : ") + p.DecorateAsValue(std::to_string(gpu.id)) + " (" + gpu.props.deviceName + ")"); if (surface_types.size() == 0) { - p.SetAsType().PrintKeyValue("Surface type", surface.surface_extension.name); + p.SetAsType().PrintKeyString("Surface type", "No type found"); + } else if (surface_types.size() == 1) { + p.SetAsType().PrintKeyString("Surface type", surface.surface_extension.name); } else { - p.ArrayStart("Surface types", surface_types.size()); + ArrayWrapper arr(p, "Surface types", surface_types.size()); for (auto &name : surface_types) { - p.PrintElement(name); + p.PrintString(name); } - p.ArrayEnd(); } DumpSurfaceFormats(p, inst, surface); - DumpPresentModes(p, surface); - DumpSurfaceCapabilities(p, inst, gpu, surface); - p.ObjectEnd(); p.AddNewline(); } @@ -204,8 +210,10 @@ bool operator==(AppSurface const &a, AppSurface const &b) { void DumpPresentableSurfaces(Printer &p, AppInstance &inst, const std::vector<std::unique_ptr<AppGpu>> &gpus, const std::vector<std::unique_ptr<AppSurface>> &surfaces) { - p.SetHeader().ObjectStart("Presentable Surfaces"); + p.SetHeader(); + ObjectWrapper obj(p, "Presentable Surfaces"); p.IndentDecrease(); + std::vector<SurfaceTypeGroup> surface_list; for (auto &surface : surfaces) { @@ -233,7 +241,6 @@ void DumpPresentableSurfaces(Printer &p, AppInstance &inst, const std::vector<st DumpSurface(p, inst, *group.gpu, *group.surface, group.surface_types); } p.IndentIncrease(); - p.ObjectEnd(); p.AddNewline(); } @@ -241,157 +248,159 @@ void DumpGroups(Printer &p, AppInstance &inst) { if (inst.CheckExtensionEnabled(VK_KHR_DEVICE_GROUP_CREATION_EXTENSION_NAME)) { auto groups = GetGroups(inst); if (groups.size() == 0) { - p.SetHeader().ObjectStart("Groups"); - p.PrintElement("No Device Groups Found"); - p.ObjectEnd(); + p.SetHeader(); + ObjectWrapper obj(p, "Groups"); + p.PrintString("No Device Groups Found"); p.AddNewline(); return; } - p.SetHeader().ObjectStart("Groups"); + + p.SetHeader(); + ObjectWrapper obj(p, "Device Groups"); + p.IndentDecrease(); int group_id = 0; for (auto &group : groups) { - p.ObjectStart("Device Group Properties (Group " + std::to_string(group_id) + ")"); + ObjectWrapper obj(p, "Group " + std::to_string(group_id)); auto group_props = GetGroupProps(group); - p.ArrayStart("physicalDeviceCount", group.physicalDeviceCount); - int id = 0; - for (auto &prop : group_props) { - std::string device_out = prop.deviceName; - if (p.Type() == OutputType::text) { - device_out += " (ID: " + std::to_string(id++) + ")"; - } else if (p.Type() == OutputType::html) { - device_out += " (ID: <span class='val'>" + std::to_string(id++) + "</span>)"; + { + ObjectWrapper obj(p, "Properties"); + { + ArrayWrapper arr(p, "physicalDevices", group.physicalDeviceCount); + int id = 0; + for (auto &prop : group_props) { + p.PrintString(std::string(prop.deviceName) + " (ID: " + p.DecorateAsValue(std::to_string(id++)) + ")"); + } } - p.PrintElement(device_out); + p.PrintKeyValue("subsetAllocation", group.subsetAllocation); } - p.ArrayEnd(); - p.PrintKeyValue("subsetAllocation", group.subsetAllocation); - p.ObjectEnd(); p.AddNewline(); - p.ObjectStart("Device Group Present Capabilities (Group " + std::to_string(group_id) + ")"); auto group_capabilities = GetGroupCapabilities(inst, group); if (group_capabilities.first == false) { - p.PrintElement("Group does not support VK_KHR_device_group, skipping printing capabilities"); + p.PrintKeyString("Present Capabilities", + "Group does not support VK_KHR_device_group, skipping printing present capabilities"); } else { + ObjectWrapper obj(p, "Present Capabilities"); for (uint32_t i = 0; i < group.physicalDeviceCount; i++) { - std::string device_out; - if (p.Type() == OutputType::text) { - device_out = std::string(group_props[i].deviceName) + " (ID: " + std::to_string(i) + ")"; - } else if (p.Type() == OutputType::html) { - device_out = - std::string(group_props[i].deviceName) + " (ID: <span class='val'>" + std::to_string(i) + "</span>)"; - } - p.PrintElement(device_out); - p.ObjectStart("Can present images from the following devices"); + ObjectWrapper obj( + p, std::string(group_props[i].deviceName) + " (ID: " + p.DecorateAsValue(std::to_string(i)) + ")"); + ArrayWrapper arr(p, "Can present images from the following devices", group.physicalDeviceCount); + for (uint32_t j = 0; j < group.physicalDeviceCount; j++) { - uint32_t mask = 1U << j; + uint32_t mask = 1 << j; if (group_capabilities.second.presentMask[i] & mask) { - if (p.Type() == OutputType::text) - p.PrintElement(std::string(group_props[j].deviceName) + " (ID: " + std::to_string(j) + ")"); - if (p.Type() == OutputType::html) - p.PrintElement(std::string(group_props[j].deviceName) + " (ID: <span class='val'>" + - std::to_string(j) + "</span>)"); + p.PrintString(std::string(group_props[j].deviceName) + " (ID: " + p.DecorateAsValue(std::to_string(j)) + + ")"); } } - p.ObjectEnd(); } DumpVkDeviceGroupPresentModeFlagsKHR(p, "Present modes", group_capabilities.second.modes); } - p.ObjectEnd(); p.AddNewline(); group_id++; } - p.ObjectEnd(); + p.IndentIncrease(); p.AddNewline(); } } void GpuDumpProps(Printer &p, AppGpu &gpu) { auto props = gpu.GetDeviceProperties(); - p.SetSubHeader().ObjectStart("VkPhysicalDeviceProperties"); - p.PrintKeyValue("apiVersion", props.apiVersion, 14, VkVersionString(props.apiVersion)); - p.PrintKeyValue("driverVersion", props.driverVersion, 14, to_hex_str(props.driverVersion)); - if (p.Type() == OutputType::json) { - p.PrintKeyValue("vendorID", props.vendorID, 14); - p.PrintKeyValue("deviceID", props.deviceID, 14); - p.PrintKeyValue("deviceType", props.deviceType, 14); - } else { - p.PrintKeyValue("vendorID", to_hex_str(props.vendorID), 14); - p.PrintKeyValue("deviceID", to_hex_str(props.deviceID), 14); + p.SetSubHeader(); + { + ObjectWrapper obj(p, "VkPhysicalDeviceProperties"); + p.PrintKeyValue("apiVersion", props.apiVersion, 14, VkVersionString(props.apiVersion)); + p.PrintKeyValue("driverVersion", props.driverVersion, 14, to_hex_str(props.driverVersion)); + p.PrintKeyString("vendorID", to_hex_str(props.vendorID), 14); + p.PrintKeyString("deviceID", to_hex_str(props.deviceID), 14); p.PrintKeyString("deviceType", VkPhysicalDeviceTypeString(props.deviceType), 14); - } - p.PrintKeyString("deviceName", props.deviceName, 14); - if (p.Type() == OutputType::json) { - p.ArrayStart("pipelineCacheUUID"); - for (uint32_t i = 0; i < VK_UUID_SIZE; ++i) { - p.PrintElement(static_cast<uint32_t>(props.pipelineCacheUUID[i])); + p.PrintKeyString("deviceName", props.deviceName, 14); + if (p.Type() == OutputType::vkconfig_output) { + ArrayWrapper arr(p, "pipelineCacheUUID", VK_UUID_SIZE); + for (uint32_t i = 0; i < VK_UUID_SIZE; ++i) { + p.PrintElement(static_cast<uint32_t>(props.pipelineCacheUUID[i])); + } } - p.ArrayEnd(); } p.AddNewline(); - if (p.Type() != OutputType::json) { - p.ObjectEnd(); // limits and sparse props are not sub objects in the text and html output - } - - if (gpu.inst.CheckExtensionEnabled(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) { - DumpVkPhysicalDeviceLimits(p, "VkPhysicalDeviceLimits", gpu.props2.properties.limits); - } else { - DumpVkPhysicalDeviceLimits(p, "VkPhysicalDeviceLimits", gpu.props.limits); - } + DumpVkPhysicalDeviceLimits(p, "VkPhysicalDeviceLimits", + gpu.inst.CheckExtensionEnabled(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME) + ? gpu.props2.properties.limits + : gpu.props.limits); p.AddNewline(); - if (gpu.inst.CheckExtensionEnabled(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) { - DumpVkPhysicalDeviceSparseProperties(p, "VkPhysicalDeviceSparseProperties", gpu.props2.properties.sparseProperties); - } else { - DumpVkPhysicalDeviceSparseProperties(p, "VkPhysicalDeviceSparseProperties", gpu.props.sparseProperties); - } + DumpVkPhysicalDeviceSparseProperties(p, "VkPhysicalDeviceSparseProperties", + gpu.inst.CheckExtensionEnabled(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME) + ? gpu.props2.properties.sparseProperties + : gpu.props.sparseProperties); p.AddNewline(); - if (p.Type() == OutputType::json) { - p.ObjectEnd(); // limits and sparse props are sub objects in the json output + if (gpu.inst.CheckExtensionEnabled(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) { + void *place = gpu.props2.pNext; + chain_iterator_phys_device_props2(p, gpu.inst, gpu, place, gpu.api_version); + p.AddNewline(); } - - if (p.Type() != OutputType::json) { - if (gpu.inst.CheckExtensionEnabled(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) { - void *place = gpu.props2.pNext; - chain_iterator_phys_device_props2(p, gpu.inst, gpu, place, gpu.api_version); +} +void GpuDumpPropsJson(Printer &p, AppGpu &gpu) { + auto props = gpu.GetDeviceProperties(); + ObjectWrapper obj(p, "VkPhysicalDeviceProperties"); + p.PrintKeyValue("apiVersion", props.apiVersion, 14, VkVersionString(props.apiVersion)); + p.PrintKeyValue("driverVersion", props.driverVersion, 14, to_hex_str(props.driverVersion)); + p.PrintKeyValue("vendorID", props.vendorID, 14); + p.PrintKeyValue("deviceID", props.deviceID, 14); + p.PrintKeyValue("deviceType", props.deviceType, 14); + p.PrintKeyString("deviceName", props.deviceName, 14); + { + ArrayWrapper arr(p, "pipelineCacheUUID", VK_UUID_SIZE); + for (uint32_t i = 0; i < VK_UUID_SIZE; ++i) { + p.PrintElement(static_cast<uint32_t>(props.pipelineCacheUUID[i])); } } - p.AddNewline(); + + DumpVkPhysicalDeviceLimits(p, "VkPhysicalDeviceLimits", + gpu.inst.CheckExtensionEnabled(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME) + ? gpu.props2.properties.limits + : gpu.props.limits); + DumpVkPhysicalDeviceSparseProperties(p, "VkPhysicalDeviceSparseProperties", + gpu.inst.CheckExtensionEnabled(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME) + ? gpu.props2.properties.sparseProperties + : gpu.props.sparseProperties); } + void GpuDumpQueueProps(Printer &p, std::vector<SurfaceExtension> &surfaces, AppQueueFamilyProperties &queue) { - p.SetElementIndex(static_cast<int>(queue.queue_index)).SetSubHeader().ObjectStart("queueProperties"); - if (p.Type() == OutputType::json) { + p.SetSubHeader().SetElementIndex(static_cast<int>(queue.queue_index)); + ObjectWrapper obj(p, "queueProperties"); + if (p.Type() == OutputType::vkconfig_output) { DumpVkExtent3D(p, "minImageTransferGranularity", queue.props.minImageTransferGranularity); } else { p.PrintKeyValue("minImageTransferGranularity", queue.props.minImageTransferGranularity, 27); } p.PrintKeyValue("queueCount", queue.props.queueCount, 27); - if (p.Type() == OutputType::json) { - p.PrintKeyValue("queueFlags", queue.props.queueFlags, 27); - } else { - p.PrintKeyValue("queueFlags", VkQueueFlagsString(queue.props.queueFlags), 27); - } - + p.PrintKeyString("queueFlags", VkQueueFlagsString(queue.props.queueFlags), 27); p.PrintKeyValue("timestampValidBits", queue.props.timestampValidBits, 27); - if (p.Type() != OutputType::json) { - if (queue.is_present_platform_agnostic) { - p.PrintKeyString("present support", queue.platforms_support_present ? "true" : "false"); - } else { - size_t width = 0; - for (auto &surface : surfaces) { - if (surface.name.size() > width) width = surface.name.size(); - } - p.ObjectStart("present support"); - for (auto &surface : surfaces) { - p.PrintKeyString(surface.name, surface.supports_present ? "true" : "false", width); - } - p.ObjectEnd(); + if (queue.is_present_platform_agnostic) { + p.PrintKeyString("present support", queue.platforms_support_present ? "true" : "false"); + } else { + size_t width = 0; + for (auto &surface : surfaces) { + if (surface.name.size() > width) width = surface.name.size(); + } + ObjectWrapper obj(p, "present support"); + for (auto &surface : surfaces) { + p.PrintKeyString(surface.name, surface.supports_present ? "true" : "false", width); } } - p.ObjectEnd(); + p.AddNewline(); } +void GpuDumpQueuePropsJson(Printer &p, std::vector<SurfaceExtension> &surfaces, AppQueueFamilyProperties &queue) { + ObjectWrapper obj(p, ""); + DumpVkExtent3D(p, "minImageTransferGranularity", queue.props.minImageTransferGranularity); + p.PrintKeyValue("queueCount", queue.props.queueCount, 27); + p.PrintKeyValue("queueFlags", queue.props.queueFlags, 27); + p.PrintKeyValue("timestampValidBits", queue.props.timestampValidBits, 27); +} + // This prints a number of bytes in a human-readable format according to prefixes of the International System of Quantities (ISQ), // defined in ISO/IEC 80000. The prefixes used here are not SI prefixes, but rather the binary prefixes based on powers of 1024 // (kibi-, mebi-, gibi- etc.). @@ -419,41 +428,39 @@ std::string NumToNiceStr(const size_t sz) { return std::string(buf); } +std::string append_human_readible(VkDeviceSize memory) { + return std::to_string(memory) + " (" + to_hex_str(memory) + ") (" + NumToNiceStr(static_cast<size_t>(memory)) + ")"; +} + void GpuDumpMemoryProps(Printer &p, AppGpu &gpu) { - p.SetHeader().ObjectStart("VkPhysicalDeviceMemoryProperties"); + p.SetHeader(); + ObjectWrapper obj(p, "VkPhysicalDeviceMemoryProperties"); p.IndentDecrease(); - p.ArrayStart("memoryHeaps", gpu.memory_props.memoryHeapCount); - for (uint32_t i = 0; i < gpu.memory_props.memoryHeapCount; ++i) { - const VkDeviceSize memSize = gpu.memory_props.memoryHeaps[i].size; - std::string mem_size_human_readable = NumToNiceStr(static_cast<size_t>(memSize)); - - std::string mem_size_str = std::to_string(memSize) + " (" + to_hex_str(memSize) + ") (" + mem_size_human_readable + ")"; - - p.SetElementIndex(static_cast<int>(i)).ObjectStart("memoryHeaps"); - if (p.Type() != OutputType::json) { - p.PrintKeyValue("size", mem_size_str, 6); - p.PrintKeyValue("budget", gpu.heapBudget[i], 6); - p.PrintKeyValue("usage", gpu.heapUsage[i], 6); + { + ObjectWrapper obj(p, "memoryHeaps", gpu.memory_props.memoryHeapCount); + + for (uint32_t i = 0; i < gpu.memory_props.memoryHeapCount; ++i) { + p.SetElementIndex(static_cast<int>(i)); + ObjectWrapper obj(p, "memoryHeaps"); + + p.PrintKeyString("size", append_human_readible(gpu.memory_props.memoryHeaps[i].size), 6); + p.PrintKeyString("budget", append_human_readible(gpu.heapBudget[i]), 6); + p.PrintKeyString("usage", append_human_readible(gpu.heapUsage[i]), 6); DumpVkMemoryHeapFlags(p, "flags", gpu.memory_props.memoryHeaps[i].flags, 6); - } else { - p.PrintKeyValue("flags", gpu.memory_props.memoryHeaps[i].flags); - p.PrintKeyValue("size", memSize); } - p.ObjectEnd(); } - p.ArrayEnd(); + { + ObjectWrapper obj(p, "memoryTypes", gpu.memory_props.memoryTypeCount); + + for (uint32_t i = 0; i < gpu.memory_props.memoryTypeCount; ++i) { + p.SetElementIndex(static_cast<int>(i)); + ObjectWrapper obj(p, "memoryTypes"); + p.PrintKeyValue("heapIndex", gpu.memory_props.memoryTypes[i].heapIndex, 13); - p.ArrayStart("memoryTypes", gpu.memory_props.memoryTypeCount); - for (uint32_t i = 0; i < gpu.memory_props.memoryTypeCount; ++i) { - p.SetElementIndex(static_cast<int>(i)).ObjectStart("memoryTypes"); - p.PrintKeyValue("heapIndex", gpu.memory_props.memoryTypes[i].heapIndex, 13); - if (p.Type() == OutputType::json) { - p.PrintKeyValue("propertyFlags", gpu.memory_props.memoryTypes[i].propertyFlags, 13); - } else { auto flags = gpu.memory_props.memoryTypes[i].propertyFlags; DumpVkMemoryPropertyFlags(p, "propertyFlags = " + to_hex_str(flags), flags); - p.ObjectStart("usable for"); + ArrayWrapper arr(p, "usable for", -1); const uint32_t memtype_bit = 1U << i; // only linear and optimal tiling considered @@ -504,73 +511,99 @@ void GpuDumpMemoryProps(Printer &p, AppGpu &gpu) { { usable += "None"; } - p.PrintElement(usable); + p.PrintString(usable); } - p.ObjectEnd(); } - - p.ObjectEnd(); } - p.ArrayEnd(); + p.IndentIncrease(); - p.ObjectEnd(); p.AddNewline(); } +void GpuDumpMemoryPropsJson(Printer &p, AppGpu &gpu) { + ObjectWrapper obj(p, "VkPhysicalDeviceMemoryProperties"); + { + ArrayWrapper arr(p, "memoryHeaps", gpu.memory_props.memoryHeapCount); + for (uint32_t i = 0; i < gpu.memory_props.memoryHeapCount; ++i) { + ObjectWrapper obj(p, ""); + p.PrintKeyValue("flags", gpu.memory_props.memoryHeaps[i].flags); + p.PrintKeyValue("size", gpu.memory_props.memoryHeaps[i].size); + } + } + { + ArrayWrapper arr(p, "memoryTypes", gpu.memory_props.memoryTypeCount); + for (uint32_t i = 0; i < gpu.memory_props.memoryTypeCount; ++i) { + ObjectWrapper obj(p, ""); + p.PrintKeyValue("heapIndex", gpu.memory_props.memoryTypes[i].heapIndex, 13); + p.PrintKeyValue("propertyFlags", gpu.memory_props.memoryTypes[i].propertyFlags, 13); + } + } +} + void GpuDumpFeatures(Printer &p, AppGpu &gpu) { p.SetHeader(); DumpVkPhysicalDeviceFeatures(p, "VkPhysicalDeviceFeatures", gpu.features); p.AddNewline(); - if (p.Type() != OutputType::json) { - if (gpu.inst.CheckExtensionEnabled(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) { - void *place = gpu.features2.pNext; - chain_iterator_phys_device_features2(p, gpu, place, gpu.api_version); - } + if (gpu.inst.CheckExtensionEnabled(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) { + void *place = gpu.features2.pNext; + chain_iterator_phys_device_features2(p, gpu, place, gpu.api_version); } } void GpuDumpFormatProperty(Printer &p, VkFormat fmt, VkFormatProperties prop) { - if (p.Type() == OutputType::text) { - p.ObjectStart("Properties"); - } else if (p.Type() == OutputType::html) { - p.SetTitleAsType().ObjectStart(VkFormatString(fmt)); - } else if (p.Type() == OutputType::json) { - p.ObjectStart(""); - } - if (p.Type() == OutputType::html || p.Type() == OutputType::text) { - p.SetOpenDetails(); - DumpVkFormatFeatureFlags(p, "linearTiling", prop.linearTilingFeatures); - p.SetOpenDetails(); - DumpVkFormatFeatureFlags(p, "optimalTiling", prop.optimalTilingFeatures); - p.SetOpenDetails(); - DumpVkFormatFeatureFlags(p, "bufferFeatures", prop.bufferFeatures); - } else if (p.Type() == OutputType::json) { - p.PrintKeyValue("formatID", fmt); - p.PrintKeyValue("linearTilingFeatures", prop.linearTilingFeatures); - p.PrintKeyValue("optimalTilingFeatures", prop.optimalTilingFeatures); - p.PrintKeyValue("bufferFeatures", prop.bufferFeatures); - } - p.ObjectEnd(); + switch (p.Type()) { + case OutputType::text: { + ObjectWrapper obj(p, "Properties"); + DumpVkFormatFeatureFlags(p, "linearTiling", prop.linearTilingFeatures); + DumpVkFormatFeatureFlags(p, "optimalTiling", prop.optimalTilingFeatures); + DumpVkFormatFeatureFlags(p, "bufferFeatures", prop.bufferFeatures); + break; + } + case OutputType::html: { + p.SetTitleAsType(); + ObjectWrapper obj(p, VkFormatString(fmt)); + p.SetOpenDetails(); + DumpVkFormatFeatureFlags(p, "linearTiling", prop.linearTilingFeatures); + p.SetOpenDetails(); + DumpVkFormatFeatureFlags(p, "optimalTiling", prop.optimalTilingFeatures); + p.SetOpenDetails(); + DumpVkFormatFeatureFlags(p, "bufferFeatures", prop.bufferFeatures); + break; + } + case OutputType::json: { + ObjectWrapper obj(p, ""); + p.PrintKeyValue("formatID", fmt); + p.PrintKeyValue("linearTilingFeatures", prop.linearTilingFeatures); + p.PrintKeyValue("optimalTilingFeatures", prop.optimalTilingFeatures); + p.PrintKeyValue("bufferFeatures", prop.bufferFeatures); + break; + } + case OutputType::vkconfig_output: { + ObjectWrapper obj(p, VkFormatString(fmt)); + DumpVkFormatFeatureFlags(p, "linearTiling", prop.linearTilingFeatures); + DumpVkFormatFeatureFlags(p, "optimalTiling", prop.optimalTilingFeatures); + DumpVkFormatFeatureFlags(p, "bufferFeatures", prop.bufferFeatures); + break; + } + } } void GpuDumpToolingInfo(Printer &p, AppGpu &gpu) { auto tools = GetToolingInfo(gpu); if (tools.size() > 0) { - p.SetSubHeader().ObjectStart("Tooling Info"); + p.SetSubHeader(); + ObjectWrapper obj(p, "Tooling Info"); for (auto tool : tools) { DumpVkPhysicalDeviceToolPropertiesEXT(p, tool.name, tool); + p.AddNewline(); } - p.ObjectEnd(); } } void GpuDevDump(Printer &p, AppGpu &gpu) { - if (p.Type() == OutputType::json) { - p.ArrayStart("ArrayOfVkFormatProperties"); - } else { - p.SetHeader().ObjectStart("Format Properties"); - p.IndentDecrease(); - } + p.SetHeader(); + ObjectWrapper obj(p, "Format Properties"); + p.IndentDecrease(); if (p.Type() == OutputType::text) { auto fmtPropMap = FormatPropMap(gpu); @@ -587,27 +620,26 @@ void GpuDevDump(Printer &p, AppGpu &gpu) { continue; } - p.SetElementIndex(counter++).ObjectStart("Common Format Group"); + p.SetElementIndex(counter++); + ObjectWrapper obj(p, "Common Format Group"); p.IndentDecrease(); - p.ObjectStart("Formats"); - for (auto &fmt : prop.second) { - p.SetAsType().PrintElement(VkFormatString(fmt)); - } - p.ObjectEnd(); + { + ArrayWrapper arr(p, "Formats", prop.second.size()); + for (auto &fmt : prop.second) { + p.SetAsType().PrintString(VkFormatString(fmt)); + } + } GpuDumpFormatProperty(p, VK_FORMAT_UNDEFINED, props); p.IndentIncrease(); - p.ObjectEnd(); p.AddNewline(); } - p.ObjectStart("Unsupported Formats"); + ArrayWrapper arr(p, "Unsupported Formats", unsupported_formats.size()); for (auto &fmt : unsupported_formats) { - p.SetAsType().PrintElement(VkFormatString(fmt)); + p.SetAsType().PrintString(VkFormatString(fmt)); } - p.ObjectEnd(); - } else { for (auto &format : gpu.supported_format_ranges) { if (gpu.FormatRangeSupported(format)) { @@ -617,69 +649,78 @@ void GpuDevDump(Printer &p, AppGpu &gpu) { VkFormatProperties props; vkGetPhysicalDeviceFormatProperties(gpu.phys_device, fmt, &props); - // if json, don't print format properties that are unsupported - if (p.Type() == OutputType::json && - (props.linearTilingFeatures || props.optimalTilingFeatures || props.bufferFeatures) == 0) - continue; - GpuDumpFormatProperty(p, fmt, props); } } } } - if (p.Type() == OutputType::json) { - p.ArrayEnd(); - } else { - p.IndentIncrease(); - p.ObjectEnd(); - } - + p.IndentIncrease(); p.AddNewline(); } -void DumpGpu(Printer &p, AppGpu &gpu, bool show_formats) { - if (p.Type() != OutputType::json) { - p.ObjectStart("GPU" + std::to_string(gpu.id)); - p.IndentDecrease(); - } - GpuDumpProps(p, gpu); +void GpuDevDumpJson(Printer &p, AppGpu &gpu) { + ArrayWrapper arr(p, "ArrayOfVkFormatProperties"); + for (auto &format : gpu.supported_format_ranges) { + if (gpu.FormatRangeSupported(format)) { + for (int32_t fmt_counter = format.first_format; fmt_counter <= format.last_format; ++fmt_counter) { + VkFormat fmt = static_cast<VkFormat>(fmt_counter); - if (p.Type() != OutputType::json) { - DumpExtensions(p, "Device", gpu.device_extensions); - p.AddNewline(); - } + VkFormatProperties props; + vkGetPhysicalDeviceFormatProperties(gpu.phys_device, fmt, &props); - if (p.Type() == OutputType::json) { - p.ArrayStart("ArrayOfVkQueueFamilyProperties"); - } else { - p.SetHeader().ObjectStart("VkQueueFamilyProperties"); - } - for (uint32_t i = 0; i < gpu.queue_count; i++) { - AppQueueFamilyProperties queue_props = AppQueueFamilyProperties(gpu, i); - GpuDumpQueueProps(p, gpu.inst.surface_extensions, queue_props); + // don't print format properties that are unsupported + if ((props.linearTilingFeatures || props.optimalTilingFeatures || props.bufferFeatures) == 0) continue; + + GpuDumpFormatProperty(p, fmt, props); + } + } } - if (p.Type() == OutputType::json) { - p.ArrayEnd(); - } else { - p.ObjectEnd(); +} +// Print gpu info for text, html, & vkconfig_output +// Uses a seperate function than schema-json for clarity +void DumpGpu(Printer &p, AppGpu &gpu, bool show_formats) { + ObjectWrapper obj(p, "GPU" + std::to_string(gpu.id)); + p.IndentDecrease(); + + GpuDumpProps(p, gpu); + DumpExtensions(p, "Device", gpu.device_extensions); + p.AddNewline(); + { + p.SetHeader(); + ObjectWrapper obj(p, "VkQueueFamilyProperties"); + for (uint32_t i = 0; i < gpu.queue_count; i++) { + AppQueueFamilyProperties queue_props = AppQueueFamilyProperties(gpu, i); + GpuDumpQueueProps(p, gpu.inst.surface_extensions, queue_props); + } } GpuDumpMemoryProps(p, gpu); GpuDumpFeatures(p, gpu); - - if (p.Type() != OutputType::json) GpuDumpToolingInfo(p, gpu); + GpuDumpToolingInfo(p, gpu); if (p.Type() != OutputType::text || show_formats) { GpuDevDump(p, gpu); } - if (p.Type() != OutputType::json) { - p.IndentIncrease(); - p.ObjectEnd(); - } + p.IndentIncrease(); p.AddNewline(); } +// Print gpu info for json +void DumpGpuJson(Printer &p, AppGpu &gpu) { + GpuDumpPropsJson(p, gpu); + { + ArrayWrapper arr(p, "ArrayOfVkQueueFamilyProperties"); + for (uint32_t i = 0; i < gpu.queue_count; i++) { + AppQueueFamilyProperties queue_props = AppQueueFamilyProperties(gpu, i); + GpuDumpQueuePropsJson(p, gpu.inst.surface_extensions, queue_props); + } + } + GpuDumpMemoryPropsJson(p, gpu); + DumpVkPhysicalDeviceFeatures(p, "VkPhysicalDeviceFeatures", gpu.features); + GpuDevDumpJson(p, gpu); +} + // ============ Printing Logic ============= // #ifdef _WIN32 @@ -738,10 +779,18 @@ int main(int argc, char **argv) { uint32_t selected_gpu = 0; bool show_formats = false; + char *output_path = nullptr; // Combinations of output: html only, html AND json, json only, human readable only for (int i = 1; i < argc; ++i) { - if (strncmp("--json", argv[i], 6) == 0 || strcmp(argv[i], "-j") == 0) { + // 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)) { + human_readable_output = false; + vkconfig_output = true; + 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)); } @@ -799,6 +848,7 @@ int main(int argc, char **argv) { buf = std::cout.rdbuf(); std::ostream out(buf); std::ofstream html_out; + std::ofstream vkconfig_out; if (human_readable_output) { printers.push_back(std::unique_ptr<Printer>(new Printer(OutputType::text, out, selected_gpu, instance.vk_version))); @@ -810,36 +860,45 @@ int main(int argc, char **argv) { if (json_output) { printers.push_back(std::unique_ptr<Printer>(new Printer(OutputType::json, out, selected_gpu, instance.vk_version))); } + if (vkconfig_output) { +#ifdef WIN32 + vkconfig_out = std::ofstream(std::string(output_path) + "\\vulkaninfo.json"); +#else + vkconfig_out = std::ofstream(std::string(output_path) + "/vulkaninfo.json"); +#endif + printers.push_back( + std::unique_ptr<Printer>(new Printer(OutputType::vkconfig_output, vkconfig_out, selected_gpu, instance.vk_version))); + } for (auto &p : printers) { - if (p->Type() != OutputType::json) { + if (p->Type() == OutputType::json) { + DumpLayers(*p.get(), instance.global_layers, gpus); + DumpGpuJson(*p.get(), *gpus.at(selected_gpu).get()); + + } else { p->SetHeader(); DumpExtensions(*p.get(), "Instance", instance.global_extensions); p->AddNewline(); - } - DumpLayers(*p.get(), instance.global_layers, gpus); + DumpLayers(*p.get(), instance.global_layers, gpus); - if (p->Type() != OutputType::json) { #if defined(VK_USE_PLATFORM_XCB_KHR) || defined(VK_USE_PLATFORM_XLIB_KHR) || defined(VK_USE_PLATFORM_WIN32_KHR) || \ defined(VK_USE_PLATFORM_MACOS_MVK) || defined(VK_USE_PLATFORM_METAL_EXT) || defined(VK_USE_PLATFORM_WAYLAND_KHR) DumpPresentableSurfaces(*p.get(), instance, gpus, surfaces); #endif DumpGroups(*p.get(), instance); - p->SetHeader().ObjectStart("Device Properties and Extensions"); + p->SetHeader(); + ObjectWrapper obj(*p, "Device Properties and Extensions"); p->IndentDecrease(); - } - for (auto &gpu : gpus) { - if ((p->Type() == OutputType::json && gpu->id == selected_gpu) || p->Type() == OutputType::text || - p->Type() == OutputType::html) { + + for (auto &gpu : gpus) { DumpGpu(*p.get(), *gpu.get(), show_formats); } - } - if (p->Type() != OutputType::json) { + p->IndentIncrease(); - p->ObjectEnd(); } + p.reset(); } #if defined(VK_USE_PLATFORM_XCB_KHR) || defined(VK_USE_PLATFORM_XLIB_KHR) || defined(VK_USE_PLATFORM_WIN32_KHR) || \ |
