diff options
| author | John Zulauf <jzulauf@lunarg.com> | 2017-10-26 12:07:05 -0600 |
|---|---|---|
| committer | jzulauf-lunarg <32470354+jzulauf-lunarg@users.noreply.github.com> | 2017-11-03 09:31:30 -0600 |
| commit | 5d0a751c3c980e086ef70f92da96e64509ba02f1 (patch) | |
| tree | 58be72e65f46ffe32e8fd9b3037b21e7f25bb7ab /scripts | |
| parent | 9ef531dfcde2c23bd3d8008c36439ad4f6aa79ce (diff) | |
| download | usermoji-5d0a751c3c980e086ef70f92da96e64509ba02f1.tar.xz | |
layers: Refactored pNext chain walks to template
The while loops for the walking the pNext chains were implemented by
repeated code. These were refactored into a common template. Added
autogenerated 'traits' objects for the pNext linked structs.
Delete cut and paste duplicate pNext chain walk.
Change-Id: I46457bb5432219c74f9356e5230c70e4a9ef16df
Diffstat (limited to 'scripts')
| -rw-r--r-- | scripts/helper_file_generator.py | 109 | ||||
| -rw-r--r-- | scripts/lvl_genvk.py | 22 |
2 files changed, 131 insertions, 0 deletions
diff --git a/scripts/helper_file_generator.py b/scripts/helper_file_generator.py index 3d4ef463..a8e9f134 100644 --- a/scripts/helper_file_generator.py +++ b/scripts/helper_file_generator.py @@ -130,6 +130,7 @@ class HelperFileOutputGenerator(OutputGenerator): copyright += ' * Author: Courtney Goeltzenleuchter <courtneygo@google.com>\n' copyright += ' * Author: Tobin Ehlis <tobine@google.com>\n' copyright += ' * Author: Chris Forbes <chrisforbes@google.com>\n' + copyright += ' * Author: John Zulauf<jzulauf@lunarg.com>\n' copyright += ' *\n' copyright += ' ****************************************************************************/\n' write(copyright, file=self.outFile) @@ -919,6 +920,112 @@ class HelperFileOutputGenerator(OutputGenerator): safe_struct_body.append("#endif // %s\n" % item.ifdef_protect) return "\n".join(safe_struct_body) # + # Generate the type map + def GenerateTypeMapHelperHeader(self): + prefix = 'Lvl' + fprefix = 'lvl_' + typemap = prefix + 'TypeMap' + idmap = prefix + 'STypeMap' + name_member = 'kName' + type_member = 'Type' + id_member = 'kSType' + decl_prefix ='constexpr static' + char_decl = decl_prefix + ' const char *' + id_decl = decl_prefix + ' const VkStructureType ' + generic_header = prefix + 'GenericHeader' + typename_func = fprefix + 'typename' + idname_func = fprefix + 'stype_name' + find_func = fprefix + 'find_in_chain' + + explanatory_comment = '\n'.join(( + '// These empty generic templates are specialized for each type with sType', + '// members and for each sType -- providing a two way map between structure', + '// types and sTypes as well as a kName stringification for convenience')) + + empty_typemap = 'template <typename T> struct ' + typemap + ' {};' + typemap_format = 'template <> struct {template}<{typename}> {{\n' + typemap_format += ' {char_decl}{name} = "{typename}";\n' + typemap_format += ' {id_decl}{id_member} = {id_value};\n' + typemap_format += '}};\n' + + empty_idmap = 'template <VkStructureType id> struct ' + idmap + ' {};' + idmap_format = ''.join(( + 'template <> struct {template}<{id_value}> {{\n', + ' typedef {typename} {typedef};\n', + ' {char_decl}{name} = "{id_value}";\n', + '}};\n')) + + # Define the utilities (here so any renaming stays consistent), if this grows large, refactor to a fixed .h file + utilities_format = '\n'.join(( + '// Header "base class" for pNext chain traversal', + 'struct {header} {{', + ' VkStructureType sType;', + ' const {header} *pNext;', + '}};', + '', + '// Find an entry of the given type in the pNext chain', + 'template <typename T> const T *{find_func}(const void *next) {{', + ' const {header} *current = reinterpret_cast<const {header} *>(next);', + ' const T *found = nullptr;', + ' while (current) {{', + ' if ({type_map}<T>::{id_member} == current->sType) {{', + ' found = reinterpret_cast<const T*>(current);', + ' current = nullptr;', + ' }} else {{', + ' current = current->pNext;', + ' }}', + ' }}', + ' return found;', + '}}', + '', + '// Convenience functions for accessing the other mapped objects name field', + 'template <typename T> constexpr const char *{idname_func}() {{', + ' return {id_map}<{type_map}<T>::{id_member}>::{name_member};', + '}}', + 'template <VkStructureType s_type> constexpr const char *{typename_func}() {{', + ' return {type_map}<typename {id_map}<s_type>::{type_member}>::{name_member};', + '}}')) + + code = [] + code.append('\n'.join(( + '#pragma once', + '#include <vulkan/vulkan.h>\n', + explanatory_comment, '', + empty_idmap, + empty_typemap, '', + utilities_format.format(name_member=name_member, id_member=id_member, id_map=idmap, type_map=typemap, + type_member=type_member, header=generic_header, typename_func=typename_func, idname_func=idname_func, + find_func=find_func), '' + ))) + + # Generate the specializations for each type and stype + + for item in self.structMembers: + typename = item.name + info = self.structTypes.get(typename) + if not info: + continue + + if item.ifdef_protect != None: + code.append('#ifdef %s' % item.ifdef_protect) + + code.append('// Map type {} to id {}'.format(typename, info.value)) + code.append(typemap_format.format(template=typemap, typename=typename, id_value=info.value, + char_decl=char_decl, id_decl=id_decl, name=name_member, id_member=id_member)) + code.append(idmap_format.format(template=idmap, typename=typename, id_value=info.value, char_decl=char_decl, typedef=type_member, name=name_member)) + + if item.ifdef_protect != None: + code.append('#endif // %s' % item.ifdef_protect) + + #for typename, info in self.structTypes.items(): + # code.append("// Map type {} to id {}".format(typename, info.value)) + # code.append(typemap_format.format(template=typemap, typename=typename, id_value=info.value, + # char_decl=char_decl, id_decl=id_decl, name=name_member, id_member=id_member)) + # code.append(idmap_format.format(template=idmap, typename=typename, id_value=info.value, char_decl=char_decl, typedef=type_member, name=name_member)) + + return "\n".join(code) + + # # Create a helper file and return it as a string def OutputDestFile(self): if self.helper_file_type == 'enum_string_header': @@ -935,6 +1042,8 @@ class HelperFileOutputGenerator(OutputGenerator): return self.GenerateObjectTypesHelperHeader() elif self.helper_file_type == 'extension_helper_header': return self.GenerateExtensionHelperHeader() + elif self.helper_file_type == 'typemap_helper_header': + return self.GenerateTypeMapHelperHeader() else: return 'Bad Helper File Generator Option %s' % self.helper_file_type diff --git a/scripts/lvl_genvk.py b/scripts/lvl_genvk.py index 09554db6..7c81f51d 100644 --- a/scripts/lvl_genvk.py +++ b/scripts/lvl_genvk.py @@ -424,6 +424,28 @@ def makeGenOpts(extensions = [], removeExtensions = [], protect = True, director helper_file_type = 'extension_helper_header') ] + # Helper file generator options for typemap_helper.h + genOpts['vk_typemap_helper.h'] = [ + HelperFileOutputGenerator, + HelperFileOutputGeneratorOptions( + filename = 'vk_typemap_helper.h', + directory = directory, + apiname = 'vulkan', + profile = None, + versions = allVersions, + emitversions = allVersions, + defaultExtensions = 'vulkan', + addExtensions = addExtensions, + removeExtensions = removeExtensions, + prefixText = prefixStrings + vkPrefixStrings, + protectFeature = False, + apicall = 'VKAPI_ATTR ', + apientry = 'VKAPI_CALL ', + apientryp = 'VKAPI_PTR *', + alignFuncParam = 48, + helper_file_type = 'typemap_helper_header') + ] + # Options for mock ICD header genOpts['mock_icd.h'] = [ MockICDOutputGenerator, |
