Update for Vulkan-Docs 1.2.140

This commit is contained in:
Jon Leech 2020-05-04 03:42:53 -07:00 committed by Jon Leech
parent 4c19ae6b95
commit 0c5351f5e9
11 changed files with 2096 additions and 905 deletions

View file

@ -20,7 +20,7 @@ import re
import sys
import xml.etree.ElementTree as etree
from collections import defaultdict, namedtuple
from generator import OutputGenerator, write
from generator import OutputGenerator, GeneratorOptions, write
def matchAPIProfile(api, profile, elem):
@ -129,12 +129,14 @@ class BaseInfo:
# If both specify the same value or bit position,
# they're equal
return True
elif (self.compareKeys(info, 'extends') and
self.compareKeys(info, 'extnumber') and
elif (self.compareKeys(info, 'extnumber') and
self.compareKeys(info, 'offset') and
self.compareKeys(info, 'dir')):
# If both specify the same relative offset, they're equal
return True
elif (self.compareKeys(info, 'alias')):
# If both are aliases of the same value
return True
else:
return False
else:
@ -254,7 +256,24 @@ class FeatureInfo(BaseInfo):
class Registry:
"""Object representing an API registry, loaded from an XML file."""
def __init__(self):
def __init__(self, gen=None, genOpts=None):
if gen is None:
# If not specified, give a default object so messaging will work
self.gen = OutputGenerator()
else:
self.gen = gen
"Output generator used to write headers / messages"
if genOpts is None:
self.genOpts = GeneratorOptions()
else:
self.genOpts = genOpts
"Options controlling features to write and how to format them"
self.gen.registry = self
self.gen.genOpts = self.genOpts
self.gen.genOpts.registry = self
self.tree = None
"ElementTree containing the root `<registry>`"
@ -279,15 +298,6 @@ class Registry:
self.extdict = {}
"dictionary of FeatureInfo objects for `<extension>` elements keyed by extension name"
# A default output generator, so commands prior to apiGen can report
# errors via the generator object.
self.gen = OutputGenerator()
"OutputGenerator object used to write headers / messages"
self.genOpts = None
"""GeneratorOptions object used to control which
features to write and how to format them"""
self.emitFeatures = False
"""True to actually emit features for a version / extension,
or False to just treat them as emitted"""
@ -516,13 +526,16 @@ class Registry:
# groupName, 'found, adding element...')
gi = self.groupdict[groupName]
gi.elem.append(enum)
# Remove element from parent <require> tag
# This should be a no-op in lxml.etree
try:
elem.remove(enum)
except ValueError:
# Must be lxml.etree
pass
if self.genOpts.reparentEnums:
# Remove element from parent <require> tag
# This is already done by lxml.etree, so
# allow for it to fail.
try:
elem.remove(enum)
except ValueError:
# Must be lxml.etree
pass
else:
self.gen.logMsg('warn', 'NO matching group',
groupName, 'for enum', enum.get('name'), 'found.')
@ -570,13 +583,16 @@ class Registry:
# groupName, 'found, adding element...')
gi = self.groupdict[groupName]
gi.elem.append(enum)
# Remove element from parent <require> tag
# This should be a no-op in lxml.etree
try:
elem.remove(enum)
except ValueError:
# Must be lxml.etree
pass
if self.genOpts.reparentEnums:
# Remove element from parent <require> tag
# This is already done by lxml.etree, so
# allow for it to fail.
try:
elem.remove(enum)
except ValueError:
# Must be lxml.etree
pass
else:
self.gen.logMsg('warn', 'NO matching group',
groupName, 'for enum', enum.get('name'), 'found.')
@ -780,6 +796,112 @@ class Registry:
else:
self.gen.logMsg('warn', 'extend type:', extendType, 'IS NOT SUPPORTED')
def getAlias(self, elem, dict):
"""Check for an alias in the same require block.
- elem - Element to check for an alias"""
# Try to find an alias
alias = elem.get('alias')
if alias is None:
name = elem.get('name')
typeinfo = self.lookupElementInfo(name, dict)
alias = typeinfo.elem.get('alias')
return alias
def checkForCorrectionAliases(self, alias, require, tag):
"""Check for an alias in the same require block.
- alias - String name of the alias
- require - `<require>` block from the registry
- tag - tag to look for in the require block"""
if alias and require.findall(tag + "[@name='" + alias + "']"):
return True
return False
def fillFeatureDictionary(self, interface, featurename, api, profile):
"""Capture added interfaces for a `<version>` or `<extension>`.
- interface - Element for `<version>` or `<extension>`, containing
`<require>` and `<remove>` tags
- featurename - name of the feature
- api - string specifying API name being generated
- profile - string specifying API profile being generated"""
# Explicitly initialize known types - errors for unhandled categories
self.gen.featureDictionary[featurename] = {
"enumconstant": {},
"command": {},
"enum": {},
"struct": {},
"handle": {},
"basetype": {},
"include": {},
"define": {},
"bitmask": {},
"union": {},
"funcpointer": {},
}
# <require> marks things that are required by this version/profile
for require in interface.findall('require'):
if matchAPIProfile(api, profile, require):
# Determine the required extension or version needed for a require block
# Assumes that only one of these is specified
required_key = require.get('feature')
if required_key is None:
required_key = require.get('extension')
# Loop over types, enums, and commands in the tag
for typeElem in require.findall('type'):
typename = typeElem.get('name')
typeinfo = self.lookupElementInfo(typename, self.typedict)
if typeinfo:
# Remove aliases in the same extension/feature; these are always added as a correction. Don't need the original to be visible.
alias = self.getAlias(typeElem, self.typedict)
if not self.checkForCorrectionAliases(alias, require, 'type'):
# Resolve the type info to the actual type, so we get an accurate read for 'structextends'
while alias:
typeinfo = self.lookupElementInfo(alias, self.typedict)
alias = typeinfo.elem.get('alias')
typecat = typeinfo.elem.get('category')
typeextends = typeinfo.elem.get('structextends')
if not required_key in self.gen.featureDictionary[featurename][typecat]:
self.gen.featureDictionary[featurename][typecat][required_key] = {}
if not typeextends in self.gen.featureDictionary[featurename][typecat][required_key]:
self.gen.featureDictionary[featurename][typecat][required_key][typeextends] = []
self.gen.featureDictionary[featurename][typecat][required_key][typeextends].append(typename)
for enumElem in require.findall('enum'):
enumname = enumElem.get('name')
typeinfo = self.lookupElementInfo(enumname, self.enumdict)
# Remove aliases in the same extension/feature; these are always added as a correction. Don't need the original to be visible.
alias = self.getAlias(enumElem, self.enumdict)
if not self.checkForCorrectionAliases(alias, require, 'enum'):
enumextends = enumElem.get('extends')
if not required_key in self.gen.featureDictionary[featurename]['enumconstant']:
self.gen.featureDictionary[featurename]['enumconstant'][required_key] = {}
if not enumextends in self.gen.featureDictionary[featurename]['enumconstant'][required_key]:
self.gen.featureDictionary[featurename]['enumconstant'][required_key][enumextends] = []
self.gen.featureDictionary[featurename]['enumconstant'][required_key][enumextends].append(enumname)
for cmdElem in require.findall('command'):
# Remove aliases in the same extension/feature; these are always added as a correction. Don't need the original to be visible.
alias = self.getAlias(cmdElem, self.cmddict)
if not self.checkForCorrectionAliases(alias, require, 'command'):
if not required_key in self.gen.featureDictionary[featurename]['command']:
self.gen.featureDictionary[featurename]['command'][required_key] = []
self.gen.featureDictionary[featurename]['command'][required_key].append(cmdElem.get('name'))
def requireAndRemoveFeatures(self, interface, featurename, api, profile):
"""Process `<require>` and `<remove>` tags for a `<version>` or `<extension>`.
@ -1005,18 +1127,16 @@ class Registry:
for c in features.findall('command'):
self.generateFeature(c.get('name'), 'command', self.cmddict)
def apiGen(self, genOpts):
"""Generate interface for specified versions
def apiGen(self):
"""Generate interface for specified versions using the current
generator and generator options"""
- genOpts - GeneratorOptions object with parameters used
by the Generator object."""
self.gen.logMsg('diag', '*******************************************')
self.gen.logMsg('diag', ' Registry.apiGen file:', genOpts.filename,
'api:', genOpts.apiname,
'profile:', genOpts.profile)
self.gen.logMsg('diag', ' Registry.apiGen file:', self.genOpts.filename,
'api:', self.genOpts.apiname,
'profile:', self.genOpts.profile)
self.gen.logMsg('diag', '*******************************************')
self.genOpts = genOpts
# Reset required/declared flags for all features
self.apiReset()
@ -1134,6 +1254,7 @@ class Registry:
for f in features:
self.gen.logMsg('diag', 'PASS 1: Tagging required and removed features for',
f.name)
self.fillFeatureDictionary(f.elem, f.name, self.genOpts.apiname, self.genOpts.profile)
self.requireAndRemoveFeatures(f.elem, f.name, self.genOpts.apiname, self.genOpts.profile)
self.assignAdditionalValidity(f.elem, self.genOpts.apiname, self.genOpts.profile)