From 8e4661ea611dead664f1d22609a9df4601d1eecd Mon Sep 17 00:00:00 2001 From: Andrey Voroshilov Date: Mon, 6 Nov 2017 20:22:22 +0300 Subject: [PATCH 1/4] Modified genRef.py : seeAlsoList - to auto-match create/destroy and allocate/free functions --- doc/specs/vulkan/genRef.py | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/doc/specs/vulkan/genRef.py b/doc/specs/vulkan/genRef.py index 31d506aaef..d745d223de 100755 --- a/doc/specs/vulkan/genRef.py +++ b/doc/specs/vulkan/genRef.py @@ -86,7 +86,35 @@ def seeAlsoList(apiName, explicitRefs = None): for name in explicitRefs.split(): refs[name] = None - names = [macroPrefix(name) for name in sorted(refs.keys())] + # Check if the apiName belongs to one of the predefined pairs + # If it does, auto-generate matching pairApiName + def checkAddPair(apiName, srcApiPrefix, dstApiPrefix, refs): + srcApiPrefixLen = len(srcApiPrefix) + if apiName[:srcApiPrefixLen] == srcApiPrefix: + pairApiName = dstApiPrefix+apiName[srcApiPrefixLen:] + if pairApiName in mapDict.keys(): + refs[pairApiName] = None + + refPairs = [('vkCreate', 'vkDestroy'), ('vkAllocate','vkFree')] + for refPairF0, refPairF1 in refPairs: + checkAddPair(apiName, refPairF0, refPairF1, refs) + checkAddPair(apiName, refPairF1, refPairF0, refs) + + # Define prefixes that will be proiritized in the "See Also" list + priorityPrefixes = ['vkCreate', 'vkDestroy', 'vkAllocate','vkFree'] + def priorityKeyMod(key): + priorityPrefix_idx = -1 + for pPrefixIdx, pPrefix in enumerate(priorityPrefixes): + if key[:len(pPrefix)] == pPrefix: + priorityPrefix_idx = pPrefixIdx + + if (priorityPrefix_idx != -1): + key_mod = " %03d%s" % (priorityPrefix_idx, key) + return key_mod + else: + return key + + names = [macroPrefix(name) for name in sorted(refs.keys(), key=priorityKeyMod)] if len(names) > 0: return ', '.join(names) + '\n' else: From a405ac7290e05e14db6fe8c829cde93610fb01fe Mon Sep 17 00:00:00 2001 From: Andrey Voroshilov Date: Sat, 11 Nov 2017 21:30:24 +0300 Subject: [PATCH 2/4] Moving API tuples and sorting lists into separate text files, wiring settings dict into related functions, adding makefile dependency --- doc/specs/vulkan/Makefile | 2 +- .../vulkan/config/vulkan-api-sorting.txt | 12 ++ doc/specs/vulkan/config/vulkan-api-tuples.txt | 12 ++ doc/specs/vulkan/genRef.py | 119 +++++++++++------- 4 files changed, 102 insertions(+), 43 deletions(-) create mode 100644 doc/specs/vulkan/config/vulkan-api-sorting.txt create mode 100644 doc/specs/vulkan/config/vulkan-api-tuples.txt diff --git a/doc/specs/vulkan/Makefile b/doc/specs/vulkan/Makefile index b53abcbe7b..bd18694ad5 100644 --- a/doc/specs/vulkan/Makefile +++ b/doc/specs/vulkan/Makefile @@ -285,7 +285,7 @@ MANCOPYRIGHT = $(MANDIR)/copyright-ccby.txt $(MANDIR)/footer.txt # also generated, though they are not useable at present. LOGFILE = man/logfile -man/apispec.txt: $(SPECFILES) genRef.py reflib.py vkapi.py +man/apispec.txt: $(SPECFILES) genRef.py reflib.py vkapi.py config/vulkan-api-sorting.txt config/vulkan-api-tuples.txt $(PYTHON) genRef.py -log $(LOGFILE) $(SPECFILES) # These dependencies don't take into account include directives diff --git a/doc/specs/vulkan/config/vulkan-api-sorting.txt b/doc/specs/vulkan/config/vulkan-api-sorting.txt new file mode 100644 index 0000000000..aafdc298ad --- /dev/null +++ b/doc/specs/vulkan/config/vulkan-api-sorting.txt @@ -0,0 +1,12 @@ +// This file contains API prefixes sorting order. +// +// If a function with matching prefix is present in the references list, it +// will be sorted according to the prefixes order. Within the prefix, functions +// are sorted alphabetically. +// * means 'all other functions', i.e. function didn't match any prefixes +// listed. +vkCreate +vkDestroy +vkAllocate +vkFree +* diff --git a/doc/specs/vulkan/config/vulkan-api-tuples.txt b/doc/specs/vulkan/config/vulkan-api-tuples.txt new file mode 100644 index 0000000000..9122c5de59 --- /dev/null +++ b/doc/specs/vulkan/config/vulkan-api-tuples.txt @@ -0,0 +1,12 @@ +// This file contains related API tuples. +// +// For a function that has prefix that belongs to the tuple, function name +// will be transformed with all other members of the tuple will automatically +// be added to the 'See Also' list. +// Tuples separators are empty strings. +// Example: for vkCreateFence, vkDestroyFence will automatically be added. +vkCreate +vkDestroy + +vkAllocate +vkFree diff --git a/doc/specs/vulkan/genRef.py b/doc/specs/vulkan/genRef.py index d745d223de..271c4b1f46 100755 --- a/doc/specs/vulkan/genRef.py +++ b/doc/specs/vulkan/genRef.py @@ -73,7 +73,7 @@ def macroPrefix(name): # Vulkan entity 'name', based on the relationship mapping in vkapi.py and # the additional references in explicitRefs. If no relationships are # available, return None. -def seeAlsoList(apiName, explicitRefs = None): +def seeAlsoList(apiName, explicitRefs = None, refSettings = None): refs = {} # Add all the implicit references to refs @@ -86,32 +86,39 @@ def seeAlsoList(apiName, explicitRefs = None): for name in explicitRefs.split(): refs[name] = None - # Check if the apiName belongs to one of the predefined pairs - # If it does, auto-generate matching pairApiName - def checkAddPair(apiName, srcApiPrefix, dstApiPrefix, refs): - srcApiPrefixLen = len(srcApiPrefix) - if apiName[:srcApiPrefixLen] == srcApiPrefix: - pairApiName = dstApiPrefix+apiName[srcApiPrefixLen:] - if pairApiName in mapDict.keys(): - refs[pairApiName] = None - - refPairs = [('vkCreate', 'vkDestroy'), ('vkAllocate','vkFree')] - for refPairF0, refPairF1 in refPairs: - checkAddPair(apiName, refPairF0, refPairF1, refs) - checkAddPair(apiName, refPairF1, refPairF0, refs) - - # Define prefixes that will be proiritized in the "See Also" list - priorityPrefixes = ['vkCreate', 'vkDestroy', 'vkAllocate','vkFree'] - def priorityKeyMod(key): - priorityPrefix_idx = -1 - for pPrefixIdx, pPrefix in enumerate(priorityPrefixes): - if key[:len(pPrefix)] == pPrefix: - priorityPrefix_idx = pPrefixIdx - - if (priorityPrefix_idx != -1): - key_mod = " %03d%s" % (priorityPrefix_idx, key) - return key_mod - else: + if refSettings: + # Check if the apiName belongs to one of the predefined prefixes + # If it does, auto-generate matching pairApiName for every + # other prefix in dstApiPrefixes + def checkAddPairs(apiName, srcApiPrefix, dstApiPrefixes, refs): + srcApiPrefixLen = len(srcApiPrefix) + if apiName[:srcApiPrefixLen] == srcApiPrefix: + for dstApiPrefix in dstApiPrefixes: + if dstApiPrefix == srcApiPrefix: + continue + pairApiName = dstApiPrefix+apiName[srcApiPrefixLen:] + if pairApiName in mapDict.keys(): + refs[pairApiName] = None + + refTuples = refSettings['tuples'] + for refTuple in refTuples: + for refPrefix in refTuple: + checkAddPairs(apiName, refPrefix, refTuple, refs) + + # Define prefixes that will be proiritized in the "See Also" list + priorityPrefixes = refSettings['sorting'] + def priorityKeyMod(key): + priorityPrefix_idx = -1 + for pPrefixIdx, pPrefix in enumerate(priorityPrefixes): + if key[:len(pPrefix)] == pPrefix: + priorityPrefix_idx = pPrefixIdx + + if (priorityPrefix_idx == -1): + priorityPrefix_idx = priorityPrefixes.index('*') + + return "%03d%s" % (priorityPrefix_idx, key) + else: + def priorityKeyMod(key): return key names = [macroPrefix(name) for name in sorted(refs.keys(), key=priorityKeyMod)] @@ -246,7 +253,8 @@ def refPageTail(pageName, seeAlso, fp, auto = False): # specDir - directory extracted page source came from # pi - pageInfo for this page relative to file # file - list of strings making up the file, indexed by pi -def emitPage(baseDir, specDir, pi, file): +# refSettings - settings for the references section +def emitPage(baseDir, specDir, pi, file, refSettings): pageName = baseDir + '/' + pi.name + '.txt' fp = open(pageName, 'w', encoding='utf-8') @@ -295,7 +303,7 @@ def emitPage(baseDir, specDir, pi, file): field, fieldText, descText, fp) - refPageTail(pi.name, seeAlsoList(pi.name, pi.refs), fp, auto = False) + refPageTail(pi.name, seeAlsoList(pi.name, pi.refs, refSettings), fp, auto = False) fp.close() # Autogenerate a single reference page in baseDir @@ -303,7 +311,8 @@ def emitPage(baseDir, specDir, pi, file): # baseDir - base directory to emit page into # pi - pageInfo for this page relative to file # file - list of strings making up the file, indexed by pi -def autoGenEnumsPage(baseDir, pi, file): +# refSettings - settings for the references section +def autoGenEnumsPage(baseDir, pi, file, refSettings): pageName = baseDir + '/' + pi.name + '.txt' fp = open(pageName, 'w', encoding='utf-8') @@ -338,7 +347,7 @@ def autoGenEnumsPage(baseDir, pi, file): None, None, txt, fp) - refPageTail(pi.name, seeAlsoList(pi.name, pi.refs), fp, auto = True) + refPageTail(pi.name, seeAlsoList(pi.name, pi.refs, refSettings), fp, auto = True) fp.close() # Pattern to break apart a Vk*Flags{authorID} name, used in autoGenFlagsPage. @@ -347,7 +356,8 @@ def autoGenEnumsPage(baseDir, pi, file): # Autogenerate a single reference page in baseDir for a Vk*Flags type # baseDir - base directory to emit page into # flagName - Vk*Flags name -def autoGenFlagsPage(baseDir, flagName): +# refSettings - settings for the references section +def autoGenFlagsPage(baseDir, flagName, refSettings): pageName = baseDir + '/' + flagName + '.txt' fp = open(pageName, 'w', encoding='utf-8') @@ -387,15 +397,16 @@ def autoGenFlagsPage(baseDir, flagName): None, None, txt, fp) - refPageTail(flagName, seeAlsoList(flagName), fp, auto = True) + refPageTail(flagName, seeAlsoList(flagName, refSettings=refSettings), fp, auto = True) fp.close() # Autogenerate a single handle page in baseDir for a Vk* handle type # baseDir - base directory to emit page into # handleName - Vk* handle name +# refSettings - settings for the references section # @@ Need to determine creation function & add handles/ include for the # @@ interface in generator.py. -def autoGenHandlePage(baseDir, handleName): +def autoGenHandlePage(baseDir, handleName, refSettings): pageName = baseDir + '/' + handleName + '.txt' fp = open(pageName, 'w', encoding='utf-8') @@ -420,14 +431,14 @@ def autoGenHandlePage(baseDir, handleName): None, None, descText, fp) - refPageTail(handleName, seeAlsoList(handleName), fp, auto = True) + refPageTail(handleName, seeAlsoList(handleName, refSettings=refSettings), fp, auto = True) fp.close() # Extract reference pages from a spec asciidoc source file # specFile - filename to extract from # baseDir - output directory to generate page in -# -def genRef(specFile, baseDir): +# refSettings - settings for the references section +def genRef(specFile, baseDir, refSettings): file = loadFile(specFile) if file == None: return @@ -454,11 +465,11 @@ def genRef(specFile, baseDir): logDiag('genRef:', pi.name + ':', pi.Warning) if pi.extractPage: - emitPage(baseDir, specDir, pi, file) + emitPage(baseDir, specDir, pi, file, refSettings) elif pi.type == 'enums': - autoGenEnumsPage(baseDir, pi, file) + autoGenEnumsPage(baseDir, pi, file, refSettings) elif pi.type == 'flags': - autoGenFlagsPage(baseDir, pi.name) + autoGenFlagsPage(baseDir, pi.name, refSettings) else: # Don't extract this page logWarn('genRef: Cannot extract or autogenerate:', pi.name) @@ -536,6 +547,23 @@ def genSinglePageRef(baseDir): body.close() fp.close() +def purify_text_lines(lines): + # Remove comment lines starting with // + # Remove leading and trailing whitespaces along the way + pure_lines = [line.strip() for line in lines if line[:2] != '//'] + return pure_lines + +def get_api_touples_list(pure_content): + pairs = [] + pairs.append(()) + for line in pure_content: + if line: + pairs[-1] += (line,) + else: + # Empty line - new tuple should be started + pairs.append(()) + return pairs + if __name__ == '__main__': global genDict genDict = {} @@ -565,8 +593,15 @@ def genSinglePageRef(baseDir): baseDir = results.baseDir + # Read 'See Also ' section genRef settings: API tuples and sorting + vk_api_sorting = purify_text_lines(loadFile('config/vulkan-api-sorting.txt')) + if not vk_api_sorting: + vk_api_sorting = ['*'] + vk_api_tuples = get_api_touples_list(purify_text_lines(loadFile('config/vulkan-api-tuples.txt'))) + vk_api_settings = {'tuples': vk_api_tuples, 'sorting': vk_api_sorting} + for file in results.files: - genRef(file, baseDir) + genRef(file, baseDir, vk_api_settings) # Now figure out which pages *weren't* generated from the spec. # This relies on the dictionaries of API constructs in vkapi.py. @@ -577,7 +612,7 @@ def genSinglePageRef(baseDir): if not (page in genDict.keys()): logWarn('Autogenerating flags page:', page, 'which should be included in the spec') - autoGenFlagsPage(baseDir, page) + autoGenFlagsPage(baseDir, page, vk_api_settings) # autoGenHandlePage is no longer needed because they are added to # the spec sources now. From c3de6e2b69853c9b59721047875bc5b679b5a113 Mon Sep 17 00:00:00 2001 From: Andrey Voroshilov Date: Sat, 11 Nov 2017 22:23:32 +0300 Subject: [PATCH 3/4] Added explicit cross references for (vkCreateComputePipelines, vkCreateGraphicsPipelines) vs vkDestroyPipeline --- doc/specs/vulkan/chapters/pipelines.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/specs/vulkan/chapters/pipelines.txt b/doc/specs/vulkan/chapters/pipelines.txt index 9c5958e5e9..49cdb2b767 100644 --- a/doc/specs/vulkan/chapters/pipelines.txt +++ b/doc/specs/vulkan/chapters/pipelines.txt @@ -107,7 +107,7 @@ an entry point from a shader module, where that entry point defines a valid compute shader, in the sname:VkPipelineShaderStageCreateInfo structure contained within the sname:VkComputePipelineCreateInfo structure. -[open,refpage='vkCreateComputePipelines',desc='Creates a new compute pipeline object',type='protos'] +[open,refpage='vkCreateComputePipelines',desc='Creates a new compute pipeline object',type='protos',xrefs='vkDestroyPipeline'] -- To create compute pipelines, call: @@ -363,7 +363,7 @@ include::../api/enums/VkShaderStageFlagBits.txt[] Graphics pipelines consist of multiple shader stages, multiple fixed-function pipeline stages, and a pipeline layout. -[open,refpage='vkCreateGraphicsPipelines',desc='Create graphics pipelines',type='protos'] +[open,refpage='vkCreateGraphicsPipelines',desc='Create graphics pipelines',type='protos',xrefs='vkDestroyPipeline'] -- To create graphics pipelines, call: @@ -1020,7 +1020,7 @@ pipeline has valid Tessellation Control and Tessellation Evaluation shaders. [[pipelines-destruction]] == Pipeline destruction -[open,refpage='vkDestroyPipeline',desc='Destroy a pipeline object',type='protos'] +[open,refpage='vkDestroyPipeline',desc='Destroy a pipeline object',type='protos',xrefs='vkCreateComputePipelines vkCreateGraphicsPipelines'] -- To destroy a graphics or compute pipeline, call: From 1e37b7e666ec85bb0f8ea35dfa7056593efabc11 Mon Sep 17 00:00:00 2001 From: Andrey Voroshilov Date: Sat, 11 Nov 2017 22:24:53 +0300 Subject: [PATCH 4/4] More tuples for auto-references: (vkBegin, vkEnd), (vkCmdBegin, vkCmdEnd), (vkMap, vkUnmap) --- doc/specs/vulkan/config/vulkan-api-sorting.txt | 6 ++++++ doc/specs/vulkan/config/vulkan-api-tuples.txt | 9 +++++++++ 2 files changed, 15 insertions(+) diff --git a/doc/specs/vulkan/config/vulkan-api-sorting.txt b/doc/specs/vulkan/config/vulkan-api-sorting.txt index aafdc298ad..8e9186a26d 100644 --- a/doc/specs/vulkan/config/vulkan-api-sorting.txt +++ b/doc/specs/vulkan/config/vulkan-api-sorting.txt @@ -9,4 +9,10 @@ vkCreate vkDestroy vkAllocate vkFree +vkBegin +vkEnd +vkCmdBegin +vkCmdEnd +vkMap +vkUnmap * diff --git a/doc/specs/vulkan/config/vulkan-api-tuples.txt b/doc/specs/vulkan/config/vulkan-api-tuples.txt index 9122c5de59..cee4b89e66 100644 --- a/doc/specs/vulkan/config/vulkan-api-tuples.txt +++ b/doc/specs/vulkan/config/vulkan-api-tuples.txt @@ -10,3 +10,12 @@ vkDestroy vkAllocate vkFree + +vkBegin +vkEnd + +vkCmdBegin +vkCmdEnd + +vkMap +vkUnmap