diff options
| author | Charles Giessen <charles@lunarg.com> | 2022-02-01 13:23:00 -0700 |
|---|---|---|
| committer | Charles Giessen <46324611+charles-lunarg@users.noreply.github.com> | 2022-02-02 13:49:13 -0700 |
| commit | 93a695c53ed3d66b0bc5eca3ad43de53f9681a16 (patch) | |
| tree | a284ecd1d535b5cac653b2794318aaa9f6ad3ae6 /scripts | |
| parent | 48ebdbba491fa2d2a5bc27eee7b1a25fcec2ed83 (diff) | |
| download | usermoji-93a695c53ed3d66b0bc5eca3ad43de53f9681a16.tar.xz | |
vulkaninfo: Generate pNext chain properly
Generate a structure that contains all the structures in the pNext chain as
members rather than relying on malloc to allocate memory for them.
Diffstat (limited to 'scripts')
| -rw-r--r-- | scripts/vulkaninfo_generator.py | 85 |
1 files changed, 58 insertions, 27 deletions
diff --git a/scripts/vulkaninfo_generator.py b/scripts/vulkaninfo_generator.py index 1997e0ed..b0b40006 100644 --- a/scripts/vulkaninfo_generator.py +++ b/scripts/vulkaninfo_generator.py @@ -105,11 +105,12 @@ predefined_types = ['char', 'VkBool32', 'uint32_t', 'uint8_t', 'int32_t', 'float', 'uint64_t', 'size_t', 'VkDeviceSize', 'int64_t'] # Types that need pNext Chains built. 'extends' is the xml tag used in the structextends member. 'type' can be device, instance, or both -EXTENSION_CATEGORIES = OrderedDict((('phys_device_props2', {'extends': 'VkPhysicalDeviceProperties2', 'type': 'both'}), - ('phys_device_mem_props2', {'extends': 'VkPhysicalDeviceMemoryProperties2', 'type': 'device'}), - ('phys_device_features2', {'extends': 'VkPhysicalDeviceFeatures2,VkDeviceCreateInfo', 'type': 'device'}), - ('surface_capabilities2', {'extends': 'VkSurfaceCapabilities2KHR', 'type': 'both'}), - ('format_properties2', {'extends': 'VkFormatProperties2', 'type': 'device'}) +EXTENSION_CATEGORIES = OrderedDict(( + ('phys_device_props2', {'extends': 'VkPhysicalDeviceProperties2', 'type': 'both', 'holder_type': 'VkPhysicalDeviceProperties2'}), + ('phys_device_mem_props2', {'extends': 'VkPhysicalDeviceMemoryProperties2', 'type': 'device', 'holder_type':'VkPhysicalDeviceMemoryProperties2'}), + ('phys_device_features2', {'extends': 'VkPhysicalDeviceFeatures2,VkDeviceCreateInfo', 'type': 'device', 'holder_type':'VkPhysicalDeviceFeatures2'}), + ('surface_capabilities2', {'extends': 'VkSurfaceCapabilities2KHR', 'type': 'both', 'holder_type':'VkSurfaceCapabilities2KHR'}), + ('format_properties2', {'extends': 'VkFormatProperties2', 'type': 'device', 'holder_type':'VkFormatProperties2'}) )) class VulkanInfoGeneratorOptions(GeneratorOptions): def __init__(self, @@ -290,12 +291,8 @@ class VulkanInfoGenerator(OutputGenerator): for s in (x for x in self.all_structures if x.name in types_to_gen and x.name not in struct_blacklist): out += PrintStructure(s, types_to_gen, names_of_structures_to_gen, self.aliases) - out += "pNextChainInfos get_chain_infos() {\n" - out += " pNextChainInfos infos;\n" - for key in EXTENSION_CATEGORIES.keys(): - out += PrintChainBuilders(key, - self.extension_sets[key], self.all_structures) - out += " return infos;\n}\n" + for key, value in EXTENSION_CATEGORIES.items(): + out += PrintChainStruct(key, self.extension_sets[key], self.all_structures, value) for key, value in EXTENSION_CATEGORIES.items(): out += PrintChainIterator(key, @@ -595,26 +592,60 @@ def PrintStructShort(struct): return out -def PrintChainBuilders(listName, structures, all_structures): +def PrintChainStruct(listName, structures, all_structures, chain_details): + out = '' sorted_structures = sorted( all_structures, key=operator.attrgetter('name')) - - out = '' - out += f" infos.{listName} = {{\n" + structs_to_print = [] for s in sorted_structures: if s.name in structures: - out += AddGuardHeader(s) - if s.sTypeName is not None: - out += f" {{{s.sTypeName}, sizeof({s.name})" - # Specific versions of drivers have an incorrect definition of the size of this struct. - # We need to artificially increase it just so the driver doesn't write 'out of bounds' and cause - # difficult to debug crashes. This bug comes from the in-development version of the extension having - # a larger size than the final version, so older drivers try to writ to members which don't exist. - if s.sTypeName == "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INTEGER_DOT_PRODUCT_FEATURES": - out += " + 256" # Really make sure a driver wont write out of bounds - out += f"}},\n" - out += AddGuardFooter(s) + structs_to_print.append(s) + out += f"struct {listName}_chain {{\n" + # delete copy & move operators + out += f" {listName}_chain() = default;\n" + out += f" {listName}_chain(const {listName}_chain &) = delete;\n" + out += f" {listName}_chain& operator=(const {listName}_chain &) = delete;\n" + out += f" {listName}_chain({listName}_chain &&) = delete;\n" + out += f" {listName}_chain& operator=({listName}_chain &&) = delete;\n" + + out += f" void* start_of_chain = nullptr;\n" + for s in structs_to_print: + out += AddGuardHeader(s) + if s.sTypeName is not None: + out += f" {s.name} {s.name[2:]}{{}};\n" + # Specific versions of drivers have an incorrect definition of the size of this struct. + # We need to artificially pad the structure it just so the driver doesn't write out of bounds and + # into other structures that are adjacent. This bug comes from the in-development version of + # the extension having a larger size than the final version, so older drivers try to write to + # members which don't exist. + if s.sTypeName == "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INTEGER_DOT_PRODUCT_FEATURES": + out += " char padding[64];\n" + out += AddGuardFooter(s) + out += f" void initialize_chain() noexcept {{\n" + for s in structs_to_print: + out += AddGuardHeader(s) + out += f" {s.name[2:]}.sType = {s.sTypeName};\n" + out += AddGuardFooter(s) + + + out += f" std::vector<VkBaseOutStructure*> chain_members;\n" + for s in structs_to_print: + out += AddGuardHeader(s) + out += f" chain_members.push_back(reinterpret_cast<VkBaseOutStructure*>(&{s.name[2:]}));\n" + out += AddGuardFooter(s) + out += f"\n" + out += f" for(size_t i = 0; i < chain_members.size() - 1; i++){{\n" + out += f" chain_members[i]->pNext = chain_members[i + 1];\n" + out += f" }}\n" + out += f" if (chain_members.size() > 0) start_of_chain = chain_members[0];\n" out += f" }};\n" + out += f"}};\n" + + out += f"void setup_{listName}_chain({chain_details['holder_type']}& start, std::unique_ptr<{listName}_chain>& chain){{\n" + out += f" chain = std::unique_ptr<{listName}_chain>(new {listName}_chain());\n" + out += f" chain->initialize_chain();\n" + out += f" start.pNext = chain->start_of_chain;\n" + out += f"}};\n" return out @@ -629,7 +660,7 @@ def PrintChainIterator(listName, structures, all_structures, checkExtLoc, extTyp out += f"AppInstance &inst, AppGpu &gpu" out += f", void * place, VulkanVersion version) {{\n" out += f" while (place) {{\n" - out += f" struct VkStructureHeader *structure = (struct VkStructureHeader *)place;\n" + out += f" struct VkBaseOutStructure *structure = (struct VkBaseOutStructure *)place;\n" out += f" p.SetSubHeader();\n" sorted_structures = sorted( all_structures, key=operator.attrgetter('name')) |
