Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PR for automatic paired functions cross-referencing #615

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion doc/specs/vulkan/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
6 changes: 3 additions & 3 deletions doc/specs/vulkan/chapters/pipelines.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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:
Expand Down
18 changes: 18 additions & 0 deletions doc/specs/vulkan/config/vulkan-api-sorting.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// 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
vkBegin
vkEnd
vkCmdBegin
vkCmdEnd
vkMap
vkUnmap
*
21 changes: 21 additions & 0 deletions doc/specs/vulkan/config/vulkan-api-tuples.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// 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

vkBegin
vkEnd

vkCmdBegin
vkCmdEnd

vkMap
vkUnmap
97 changes: 80 additions & 17 deletions doc/specs/vulkan/genRef.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -86,7 +86,42 @@ def seeAlsoList(apiName, explicitRefs = None):
for name in explicitRefs.split():
refs[name] = None

names = [macroPrefix(name) for name in sorted(refs.keys())]
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)]
if len(names) > 0:
return ', '.join(names) + '\n'
else:
Expand Down Expand Up @@ -218,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')

Expand Down Expand Up @@ -267,15 +303,16 @@ 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
# Script only knows how to do this for /enums/ pages, at present
# 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')

Expand Down Expand Up @@ -310,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.
Expand All @@ -319,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')

Expand Down Expand Up @@ -359,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')

Expand All @@ -392,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
Expand All @@ -426,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)
Expand Down Expand Up @@ -508,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 = {}
Expand Down Expand Up @@ -537,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.
Expand All @@ -549,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.
Expand Down