diff options
| -rw-r--r-- | scripts/vulkaninfo_generator.py | 84 | ||||
| -rw-r--r-- | vulkaninfo/generated/vulkaninfo.hpp | 14 | ||||
| -rw-r--r-- | vulkaninfo/vulkaninfo.cpp | 51 | ||||
| -rw-r--r-- | vulkaninfo/vulkaninfo.h | 58 |
4 files changed, 138 insertions, 69 deletions
diff --git a/scripts/vulkaninfo_generator.py b/scripts/vulkaninfo_generator.py index 2062115d..71a2aed2 100644 --- a/scripts/vulkaninfo_generator.py +++ b/scripts/vulkaninfo_generator.py @@ -225,6 +225,7 @@ class VulkanInfoGenerator(OutputGenerator): self.enums = [] self.flags = [] self.bitmasks = [] + self.format_ranges = [] self.all_structures = [] self.aliases = OrderedDict() @@ -260,6 +261,8 @@ class VulkanInfoGenerator(OutputGenerator): self.vulkan_versions.append(VulkanVersion(ver)) def endFile(self): + self.findFormatRanges() + # gather the types that are needed to generate types_to_gen = set() for s in enums_to_gen: @@ -340,6 +343,13 @@ class VulkanInfoGenerator(OutputGenerator): for s in (x for x in self.all_structures if x.name in struct_short_versions_to_gen): out += PrintStructShort(s) + out += 'auto format_ranges = std::array{\n' + for f in self.format_ranges: + out += f' FormatRange{{{f.minimum_instance_version}, {f.extension_name if f.extension_name is not None else "nullptr"}, ' + out += f'static_cast<VkFormat>({f.first_format}), static_cast<VkFormat>({f.last_format})}},\n' + out += '};\n' + + gen.write(out, file=self.outFile) gen.OutputGenerator.endFile(self) @@ -395,6 +405,62 @@ class VulkanInfoGenerator(OutputGenerator): if value.get('exclude') is None or name not in value.get('exclude'): self.extension_sets[key].add(name) + # finds all the ranges of formats from core (1.0), core versions (1.1+), and extensions + def findFormatRanges(self): + for enums in self.registry.reg.findall('enums'): + if enums.get('name') == 'VkFormat': + min_val = 2**32 + max_val = 0 + for enum in enums.findall('enum'): + if enum.get('value') is None: + continue + value = int(enum.get('value')) + min_val = min(min_val, value) + max_val = max(max_val, value) + if min_val < 2**32 and max_val > 0: + self.format_ranges.append(VulkanFormatRange(0,None, min_val, max_val)) + + for feature in self.registry.reg.findall('feature'): + for require in feature.findall('require'): + comment = require.get('comment') + original_ext = None + if comment is not None and comment.find('Promoted from') >= 0: + # may need tweaking in the future - some ext names aren't just the upper case version + original_ext = comment.split(' ')[2].upper() + '_EXTENSION_NAME' + min_val = 2**32 + max_val = 0 + for enum in require.findall('enum'): + if enum.get('extends') == 'VkFormat': + value = CalcEnumValue(int(enum.get('extnumber')), int(enum.get('offset'))) + min_val = min(min_val, value) + max_val = max(max_val, value) + if min_val < 2**32 and max_val > 0: + self.format_ranges.append(VulkanFormatRange(feature.get('number').split('.')[1],None, min_val, max_val)) + # If the formats came from an extension, add a format range for that extension so it'll be printed if the ext is supported but not the core version + if original_ext is not None: + self.format_ranges.append(VulkanFormatRange(0,original_ext, min_val, max_val)) + + for extension in self.registry.reg.find('extensions').findall('extension'): + if extension.get('supported') in ['disabled', 'vulkansc']: + continue + + min_val = 2**32 + max_val = 0 + enum_name_string = '' + for require in extension.findall('require'): + for enum in require.findall('enum'): + if enum.get('value') is not None and enum.get('value').find(extension.get('name')): + enum_name_string = enum.get('name') + if enum.get('extends') == 'VkFormat': + if enum.get('offset') is None: + continue + value = CalcEnumValue(int(extension.get('number')), int(enum.get('offset'))) + min_val = min(min_val, value) + max_val = max(max_val, value) + if min_val < 2**32 and max_val > 0: + self.format_ranges.append(VulkanFormatRange(0, enum_name_string, min_val, max_val)) + + def GatherTypesToGen(structure_list, structures, exclude = []): if exclude == None: @@ -438,6 +504,10 @@ def AddGuardFooter(obj): else: return "" +def CalcEnumValue(num, offset): + base = 1000000000 + block_size = 1000 + return base + (num - 1) * block_size + offset def PrintEnumToString(enum, gen): out = '' @@ -871,12 +941,7 @@ class VulkanEnum: continue if childExtends is not None and childExtNum is not None and childOffset is not None: - enumNegative = False - extNum = int(childExtNum) - extOffset = int(childOffset) - extBase = 1000000000 - extBlockSize = 1000 - childValue = extBase + (extNum - 1) * extBlockSize + extOffset + childValue = CalcEnumValue(int(childExtNum), int(childOffset)) if ('dir' in child.keys()): childValue = -childValue duplicate = False @@ -1079,3 +1144,10 @@ class VulkanVersion: for enum in req.findall('enum'): self.names.add(enum.get('name')) self.names = sorted(self.names) + +class VulkanFormatRange: + def __init__(self, min_inst_version, ext_name, first, last): + self.minimum_instance_version = min_inst_version + self.extension_name = ext_name + self.first_format = first + self.last_format = last diff --git a/vulkaninfo/generated/vulkaninfo.hpp b/vulkaninfo/generated/vulkaninfo.hpp index e32a57cb..cb2ec147 100644 --- a/vulkaninfo/generated/vulkaninfo.hpp +++ b/vulkaninfo/generated/vulkaninfo.hpp @@ -5212,4 +5212,18 @@ bool operator==(const VkSurfaceFormatKHR & a, const VkSurfaceFormatKHR b) { std::ostream &operator<<(std::ostream &o, VkExtent3D &obj) { return o << "(" << obj.width << ',' << obj.height << ',' << obj.depth << ")"; } +auto format_ranges = std::array{ + FormatRange{0, nullptr, static_cast<VkFormat>(0), static_cast<VkFormat>(184)}, + FormatRange{1, nullptr, static_cast<VkFormat>(1000156000), static_cast<VkFormat>(1000156033)}, + FormatRange{0, VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME, static_cast<VkFormat>(1000156000), static_cast<VkFormat>(1000156033)}, + FormatRange{3, nullptr, static_cast<VkFormat>(1000330000), static_cast<VkFormat>(1000330003)}, + FormatRange{0, VK_EXT_YCBCR_2PLANE_444_FORMATS_EXTENSION_NAME, static_cast<VkFormat>(1000330000), static_cast<VkFormat>(1000330003)}, + FormatRange{3, nullptr, static_cast<VkFormat>(1000340000), static_cast<VkFormat>(1000340001)}, + FormatRange{0, VK_EXT_4444_FORMATS_EXTENSION_NAME, static_cast<VkFormat>(1000340000), static_cast<VkFormat>(1000340001)}, + FormatRange{3, nullptr, static_cast<VkFormat>(1000066000), static_cast<VkFormat>(1000066013)}, + FormatRange{0, VK_EXT_TEXTURE_COMPRESSION_ASTC_HDR_EXTENSION_NAME, static_cast<VkFormat>(1000066000), static_cast<VkFormat>(1000066013)}, + FormatRange{0, VK_IMG_FORMAT_PVRTC_EXTENSION_NAME, static_cast<VkFormat>(1000054000), static_cast<VkFormat>(1000054007)}, + FormatRange{0, VK_NV_OPTICAL_FLOW_EXTENSION_NAME, static_cast<VkFormat>(1000464000), static_cast<VkFormat>(1000464000)}, + FormatRange{0, VK_KHR_MAINTENANCE_5_EXTENSION_NAME, static_cast<VkFormat>(1000470000), static_cast<VkFormat>(1000470001)}, +}; diff --git a/vulkaninfo/vulkaninfo.cpp b/vulkaninfo/vulkaninfo.cpp index daa7c9dd..4ebe3514 100644 --- a/vulkaninfo/vulkaninfo.cpp +++ b/vulkaninfo/vulkaninfo.cpp @@ -32,6 +32,20 @@ #endif #include "vulkaninfo.hpp" +// Used to sort the formats into buckets by their properties. +std::unordered_map<PropFlags, std::set<VkFormat>> FormatPropMap(AppGpu &gpu) { + std::unordered_map<PropFlags, std::set<VkFormat>> map; + for (const auto fmtRange : format_ranges) { + if (gpu.FormatRangeSupported(fmtRange)) { + for (int32_t fmt = fmtRange.first_format; fmt <= fmtRange.last_format; ++fmt) { + PropFlags pf = get_format_properties(gpu, static_cast<VkFormat>(fmt)); + map[pf].insert(static_cast<VkFormat>(fmt)); + } + } + } + return map; +} + // =========== Dump Functions ========= // void DumpExtensions(Printer &p, std::string section_name, std::vector<VkExtensionProperties> extensions, bool do_indent = false) { @@ -533,7 +547,7 @@ void GpuDumpFeatures(Printer &p, AppGpu &gpu) { } } -void GpuDumpTextFormatProperty(Printer &p, const AppGpu &gpu, PropFlags formats, std::vector<VkFormat> format_list, +void GpuDumpTextFormatProperty(Printer &p, const AppGpu &gpu, PropFlags formats, const std::set<VkFormat> &format_list, uint32_t counter) { p.SetElementIndex(counter); ObjectWrapper obj_common_group(p, "Common Format Group"); @@ -576,9 +590,8 @@ void GpuDevDump(Printer &p, AppGpu &gpu) { if (p.Type() == OutputType::text) { auto fmtPropMap = FormatPropMap(gpu); - int counter = 0; - std::vector<VkFormat> unsupported_formats; + std::set<VkFormat> unsupported_formats; for (auto &prop : fmtPropMap) { VkFormatProperties props = prop.first.props; VkFormatProperties3 props3 = prop.first.props3; @@ -595,20 +608,23 @@ void GpuDevDump(Printer &p, AppGpu &gpu) { p.SetAsType().PrintString(VkFormatString(fmt)); } } else { - 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); - auto formats = get_format_properties(gpu, fmt); - p.SetTitleAsType(); - if (gpu.CheckPhysicalDeviceExtensionIncluded(VK_KHR_FORMAT_FEATURE_FLAGS_2_EXTENSION_NAME)) { - DumpVkFormatProperties3(p, VkFormatString(fmt), formats.props3); - } else { - DumpVkFormatProperties(p, VkFormatString(fmt), formats.props); - } + std::set<VkFormat> formats_to_print; + for (auto &format_range : format_ranges) { + if (gpu.FormatRangeSupported(format_range)) { + for (int32_t fmt_counter = format_range.first_format; fmt_counter <= format_range.last_format; ++fmt_counter) { + formats_to_print.insert(static_cast<VkFormat>(fmt_counter)); } } } + for (const auto &fmt : formats_to_print) { + auto formats = get_format_properties(gpu, fmt); + p.SetTitleAsType(); + if (gpu.CheckPhysicalDeviceExtensionIncluded(VK_KHR_FORMAT_FEATURE_FLAGS_2_EXTENSION_NAME)) { + DumpVkFormatProperties3(p, VkFormatString(fmt), formats.props3); + } else { + DumpVkFormatProperties(p, VkFormatString(fmt), formats.props); + } + } } p.AddNewline(); @@ -680,10 +696,14 @@ void DumpGpuProfileCapabilities(Printer &p, AppGpu &gpu) { } { ObjectWrapper obj(p, "formats"); - for (auto &format : gpu.supported_format_ranges) { + std::set<VkFormat> already_printed_formats; + for (const auto &format : 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 (already_printed_formats.count(fmt) > 0) { + continue; + } auto formats = get_format_properties(gpu, fmt); // don't print format properties that are unsupported @@ -704,6 +724,7 @@ void DumpGpuProfileCapabilities(Printer &p, AppGpu &gpu) { gpu.inst.ext_funcs.vkGetPhysicalDeviceFormatProperties2KHR(gpu.phys_device, fmt, &format_props2); chain_iterator_format_properties2(p, gpu, format_props2.pNext); } + already_printed_formats.insert(fmt); } } } diff --git a/vulkaninfo/vulkaninfo.h b/vulkaninfo/vulkaninfo.h index 1390863b..13d3b1e9 100644 --- a/vulkaninfo/vulkaninfo.h +++ b/vulkaninfo/vulkaninfo.h @@ -36,6 +36,7 @@ #include <set> #include <string> #include <unordered_map> +#include <set> #include <vector> #include <utility> @@ -1673,8 +1674,6 @@ struct AppGpu { std::array<VkDeviceSize, VK_MAX_MEMORY_HEAPS> heapBudget; std::array<VkDeviceSize, VK_MAX_MEMORY_HEAPS> heapUsage; - std::vector<FormatRange> supported_format_ranges; - std::unique_ptr<phys_device_props2_chain> chain_for_phys_device_props2; std::unique_ptr<phys_device_mem_props2_chain> chain_for_phys_device_mem_props2; std::unique_ptr<phys_device_features2_chain> chain_for_phys_device_features2; @@ -1873,36 +1872,6 @@ struct AppGpu { } } // TODO buffer - memory type compatibility - - supported_format_ranges = { - { - // Standard formats in Vulkan 1.0 - VK_MAKE_VERSION(1, 0, 0), NULL, - static_cast<VkFormat>(0), // first core VkFormat - static_cast<VkFormat>(184) // last core VkFormat - }, - { - // YCBCR extension, standard in Vulkan 1.1 - VK_MAKE_VERSION(1, 1, 0), - VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME, - VK_FORMAT_G8B8G8R8_422_UNORM, - VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM, - }, - { - // PVRTC extension, not standardized - 0, - VK_IMG_FORMAT_PVRTC_EXTENSION_NAME, - VK_FORMAT_PVRTC1_2BPP_UNORM_BLOCK_IMG, - VK_FORMAT_PVRTC2_4BPP_SRGB_BLOCK_IMG, - }, - { - // ASTC extension, not standardized - 0, - VK_EXT_TEXTURE_COMPRESSION_ASTC_HDR_EXTENSION_NAME, - VK_FORMAT_ASTC_4x4_SFLOAT_BLOCK_EXT, - VK_FORMAT_ASTC_12x12_SFLOAT_BLOCK_EXT, - }, - }; } ~AppGpu() { inst.dll.fp_vkDestroyDevice(dev, nullptr); } @@ -1916,10 +1885,9 @@ struct AppGpu { } // Helper function to determine whether a format range is currently supported. - bool FormatRangeSupported(FormatRange &format_range) const { - // True if standard and supported by both this instance and this GPU - if (format_range.minimum_instance_version > 0 && inst.instance_version >= format_range.minimum_instance_version && - props.apiVersion >= format_range.minimum_instance_version) { + bool FormatRangeSupported(const FormatRange &format_range) const { + // Formats from base vulkan spec + if (format_range.minimum_instance_version == 0 && format_range.extension_name == nullptr) { return true; } @@ -1928,6 +1896,12 @@ struct AppGpu { return inst.CheckExtensionEnabled(format_range.extension_name); } + // True if standard and supported by both this instance and this GPU + if (inst.instance_version >= VK_MAKE_API_VERSION(0, 1, format_range.minimum_instance_version, 0) && + props.apiVersion >= VK_MAKE_API_VERSION(0, 1, format_range.minimum_instance_version, 0)) { + return true; + } + // Otherwise, not supported. return false; } @@ -2025,15 +1999,3 @@ struct hash<PropFlags> { } }; } // namespace std - -// Used to sort the formats into buckets by their properties. -std::unordered_map<PropFlags, std::vector<VkFormat>> FormatPropMap(AppGpu &gpu) { - std::unordered_map<PropFlags, std::vector<VkFormat>> map; - for (auto fmtRange : gpu.supported_format_ranges) { - for (int32_t fmt = fmtRange.first_format; fmt <= fmtRange.last_format; ++fmt) { - PropFlags pf = get_format_properties(gpu, static_cast<VkFormat>(fmt)); - map[pf].push_back(static_cast<VkFormat>(fmt)); - } - } - return map; -} |
