Vulkan-Docs/src/spec/pygenerator.py

243 lines
10 KiB
Python
Raw Normal View History

#!/usr/bin/python3 -i
#
Change log for January 5, 2018 Vulkan 1.0.67 spec update: * Bump API patch number and header version number to 67 for this update. * Update copyright dates to 2018 Github Issues: * Fix texture lookup functions in `GL_KHR_vulkan_glsl` specification (public pull request 363). * Clarify the state waited semaphores are left in when a call to flink:vkQueuePresentKHR fails (public issue 572). * Cleanup descriptions of slink:VkObjectTablePushConstantEntryNVX and slink:VkObjectTableDescriptorSetEntryNVX (public issue 583) * Remove redundant flink:vkCmdSetDiscardRectangleEXT valid usage statements (public pull 586). * Make dynamic state array length valid usage statements implicit for flink:vkCmdSetViewportWScalingNV, flink:vkCmdSetDiscardRectangleEXT, and flink:vkCmdSetViewport (public pull 589). * Clarify meaning of window extent (0,0) in slink:VkSwapchainKHR for the Windows and X11 platforms, in their respective extensions (public issue 590). * Allow flink:vkGetPastPresentationTimingGOOGLE to return ename:VK_INCOMPLETE (public issue 604). * Add synchronization valid usage statements to flink:vkAcquireNextImage (public pull 611). * Fix some broken external links and internal xrefs (public pull 613). * Clean up slink:VkViewport valid usage statements in the presence or absence of relevant extensions (public pull 623). * Remove ename:VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL_KHR token from VK_KHR_maintenance2 from the non-extension VU path for slink:VkGraphicsPipelineCreateInfo (public issue 628). * Miscellaneous minor markup fixes - extension name strings (public pull 631), Notes (pull 633), queue names emitted by generator scripts (pull 634), block formatting in slink:VkDescriptorUpdateTemplateEntryKHR (pull 635), ename:VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_IMG (pull 641), quotes and apostrophes (pull 643), * Miscellaneous minor grammar fixes (public pull 644). * Fix markup macros so usage like ptext:*Src* works (public pull 647). Internal Issues: * Clarify in the `VK_KHR_surface` and `VK_KHR_swapchain` extensions that parameter combinations which aren't supported for normal images are also unsupported for presentable images, even if the parameter values are individually supported as reported by the surface capability queries (internal issue 1029). * Fixed XML typo in the valid value field of the pname:sType member of slink:VkPhysicalDeviceExternalMemoryHostPropertiesEXT (internal issue 1100). Other Issues: * Add memory semantics validity rules to the <<spirvenv-module-validation, Validation Rules within a Module>> section of the SPIR-V environment appendix, and specify that sequentiality consistency is not supported. This forbids certain cases like "`Load+Release`" that we don't expect to ever be meaningful. * Document mapping of OpenGL Shading Language barriers to SPIR-V scope and semantics in the `GL_KHR_vulkan_glsl` specification. New Extensions: * `VK_EXT_conservative_rasterization`
2018-01-06 01:39:15 +00:00
# Copyright (c) 2013-2018 The Khronos Group Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import os,re,sys
from generator import *
# PyOutputGenerator - subclass of OutputGenerator.
# Generates Python data structures describing API names and relationships.
# Similar to DocOutputGenerator, but writes a single file.
#
# ---- methods ----
# PyOutputGenerator(errFile, warnFile, diagFile) - args as for
# OutputGenerator. Defines additional internal state.
# ---- methods overriding base class ----
# beginFile(genOpts)
# endFile()
# genType(typeinfo,name)
# genStruct(typeinfo,name)
# genGroup(groupinfo,name)
# genEnum(enuminfo, name)
# genCmd(cmdinfo)
class PyOutputGenerator(OutputGenerator):
"""Generate specified API interfaces in a specific style, such as a C header"""
def __init__(self,
errFile = sys.stderr,
warnFile = sys.stderr,
diagFile = sys.stdout):
OutputGenerator.__init__(self, errFile, warnFile, diagFile)
#
def beginFile(self, genOpts):
OutputGenerator.beginFile(self, genOpts)
#
# Dictionaries are keyed by the name of the entity (e.g.
# self.structs is keyed by structure names). Values are
# the names of related entities (e.g. structs contain
# a list of type names of members, enums contain a list
# of enumerants belong to the enumerated type, etc.), or
# just None if there are no directly related entities.
#
# Collect the mappings, then emit the Python script in endFile
self.basetypes = {}
self.consts = {}
self.enums = {}
self.flags = {}
self.funcpointers = {}
self.protos = {}
self.structs = {}
self.handles = {}
self.defines = {}
# Dictionary containing the type of a type name
# (e.g. the string name of the dictionary with its contents).
self.typeCategory = {}
self.mapDict = {}
def endFile(self):
# Print out all the dictionaries as Python strings.
# Could just print(dict) but that's not human-readable
dicts = [ [ self.basetypes, 'basetypes' ],
[ self.consts, 'consts' ],
[ self.enums, 'enums' ],
[ self.flags, 'flags' ],
[ self.funcpointers, 'funcpointers' ],
[ self.protos, 'protos' ],
[ self.structs, 'structs' ],
[ self.handles, 'handles' ],
[ self.defines, 'defines' ],
[ self.typeCategory, 'typeCategory' ] ]
for (dict, name) in dicts:
write(name + ' = {}', file=self.outFile)
for key in sorted(dict.keys()):
write(name + '[' + enquote(key) + '] = ', dict[key], file=self.outFile)
# Dictionary containing the relationships of a type
# (e.g. a dictionary with each related type as keys).
write('mapDict = {}', file=self.outFile)
# Could just print(self.mapDict), but prefer something human-readable
for baseType in sorted(self.mapDict.keys()):
write('mapDict[' + enquote(baseType) + '] = ', self.mapDict[baseType], file=self.outFile)
OutputGenerator.endFile(self)
# Add a string entry to the dictionary, quoting it so it gets printed
# out correctly in self.endFile()
def addName(self, dict, name, value):
dict[name] = enquote(value)
# Add a mapping between types to mapDict. Only include Vulkan types,
# so we don't end up with a lot of useless uint32_t and void types.
def addMapping(self, baseType, refType):
if (not apiName(baseType) or not apiName(refType)):
self.logMsg('diag', 'PyOutputGenerator::addMapping: IGNORE map from', baseType, '<->', refType)
return
else:
self.logMsg('diag', 'PyOutputGenerator::addMapping: map from', baseType, '<->', refType)
if (not baseType in self.mapDict.keys()):
baseDict = {}
self.mapDict[baseType] = baseDict
else:
baseDict = self.mapDict[baseType]
if (not refType in self.mapDict.keys()):
refDict = {}
self.mapDict[refType] = refDict
else:
refDict = self.mapDict[refType]
baseDict[refType] = None
refDict[baseType] = None
#
# Type generation
# For 'struct' or 'union' types, defer to genStruct() to
# add to the dictionary.
# For 'bitmask' types, add the type name to the 'flags' dictionary,
# with the value being the corresponding 'enums' name defining
# the acceptable flag bits.
# For 'enum' types, add the type name to the 'enums' dictionary,
# with the value being '@STOPHERE@' (because this case seems
# never to happen).
# For 'funcpointer' types, add the type name to the 'funcpointers'
# dictionary.
# For 'handle' and 'define' types, add the handle or #define name
# to the 'struct' dictionary, because that's how the spec sources
# tag these types even though they aren't structs.
def genType(self, typeinfo, name):
OutputGenerator.genType(self, typeinfo, name)
typeElem = typeinfo.elem
# If the type is a struct type, traverse the imbedded <member> tags
# generating a structure. Otherwise, emit the tag text.
category = typeElem.get('category')
# Add a typeCategory{} entry for the category of this type.
self.addName(self.typeCategory, name, category)
if (category == 'struct' or category == 'union'):
self.genStruct(typeinfo, name)
else:
# Extract the type name
# (from self.genOpts). Copy other text through unchanged.
# If the resulting text is an empty string, don't emit it.
count = len(noneStr(typeElem.text))
for elem in typeElem:
count += len(noneStr(elem.text)) + len(noneStr(elem.tail))
if (count > 0):
if (category == 'bitmask'):
requiredEnum = typeElem.get('requires')
self.addName(self.flags, name, requiredEnum)
# This happens when the Flags type is defined, but no
# FlagBits are defined yet.
if (requiredEnum != None):
self.addMapping(name, requiredEnum)
elif (category == 'enum'):
# This case does not seem to come up. It nominally would
# result from
# <type name="VkSomething" category="enum"/>,
# but the output generator doesn't emit them directly.
self.logMsg('warn', 'PyOutputGenerator::genType: invalid \'enum\' category for name:', name)
elif (category == 'funcpointer'):
self.funcpointers[name] = None
elif (category == 'handle'):
self.handles[name] = None
elif (category == 'define'):
self.defines[name] = None
elif (category == 'basetype'):
# Don't add an entry for base types that aren't Vulkan types
# e.g. VkBool32 gets one, uint32_t does not
if (apiName(name)):
self.basetypes[name] = None
self.addName(self.typeCategory, name, 'basetype')
else:
Change log for July 22, 2016 Vulkan 1.0.22 spec update: * Bump API patch number and header version number to 22 for this update. Github Issues: * Translate the subpass self-dependency language into concrete validity statements, and added a validity statement about the restrictions on layout parameters (public issue 267). * Add validity requirement that slink:VkAttachmentDescription::pname:finalLayout and slink:VkAttachmentReference::pname:layout must not be ename:VK_IMAGE_LAYOUT_UNDEFINED or ename:VK_IMAGE_LAYOUT_PREINITIALIZED (public issue 268). * Clarify that slink:VkSubpassDescription::pname:pResolveAttachments layouts are used. Make language consistent with other attachment arrays (public issue 270). * Changed 64-bit definition for dname:VK_DEFINE_NON_DISPATCHABLE_HANDLE to work for x32 platform in +vk.xml+ and the resulting +vulkan.h+ (public issue 282). * Add missing error return code for flink:vkEnumerateInstanceExtensionProperties and flink:vkEnumerateDeviceExtensionProperties (public issue 285) * Fix several cases of stext::VkStructName.memberName markup to stext::VkStructName::pname:memberName, to match other usage in the spec, and describe this markup in the style guide (public issue 286). * Modified validity language generation script to avoid redundant common ancestor language if covered by generic parent language, and used `Both' instead of `Each' when appropriate (public issue 288). Internal Issues: * Add language about behavior of flink:vkAllocateDescriptorSets when allocation fails due to fragmentation, a new error ename:VK_ERROR_FRAGMENTED_POOL, and a Note explaining the situation (internal issue 309). * For the features of code:PointSize, code:ClipDistance, and code:CullDistance, the SPIR-V capability is required to be declared on use (read or write) rather than on decoration (internal issue 359). * Have desktop versions of GLSL respect precision qualification (code:mediump and code:lowp) when compiling for Vulkan. These will get translated to SPIR-V's code:RelaxedPrecision decoration as they do with OpenGL ES versions of GLSL (ESSL). The default precision of all types is code:highp when using a desktop version (internal issue 360). * Add validity statement for slink:VkImageCreateInfo specifying that multisampled images must be two-dimensional, optimally tiled, and with a single mipmap level (internal issue 369). * Add validity statements to slink:VkImageViewCreateInfo disallowing creation of images or image views with no supported features. Made some slink:VkImageViewCreateInfo validity statements more precise and consistent. Added a Note to the <<features,features>> chapter about formats with no features (internal issue 371). * Remove +manpages+ from default build targets. Nroff outputs containing imbedded latexmath will not render properly. Fixing this is a lot of work for limited use cases (internal issue 401). Other Commits: * Fix flink:vkRenderPassBeginInfo::pname:clearValueCount validity statement to be based on attachment indices rather than the number of cleared attachments (Vulkan-LoaderAndValidationLayers/issues/601). * Convert registry documentation from LaTeX to asciidoc source and rename from +src/spec/readme.tex+ to +src/spec/registry.txt+. * Fix lack of Oxford commas in validity language. * Lots of cleanup of generator scripts and Makefiles to move extension list for generator into the script arguments instead of the body of genvk.py, and express better dependencies between XML, scripts, and generated files.
2016-07-23 10:15:48 +00:00
self.logMsg('diag', 'PyOutputGenerator::genType: unprocessed type:', name, 'category:', category)
else:
Change log for July 22, 2016 Vulkan 1.0.22 spec update: * Bump API patch number and header version number to 22 for this update. Github Issues: * Translate the subpass self-dependency language into concrete validity statements, and added a validity statement about the restrictions on layout parameters (public issue 267). * Add validity requirement that slink:VkAttachmentDescription::pname:finalLayout and slink:VkAttachmentReference::pname:layout must not be ename:VK_IMAGE_LAYOUT_UNDEFINED or ename:VK_IMAGE_LAYOUT_PREINITIALIZED (public issue 268). * Clarify that slink:VkSubpassDescription::pname:pResolveAttachments layouts are used. Make language consistent with other attachment arrays (public issue 270). * Changed 64-bit definition for dname:VK_DEFINE_NON_DISPATCHABLE_HANDLE to work for x32 platform in +vk.xml+ and the resulting +vulkan.h+ (public issue 282). * Add missing error return code for flink:vkEnumerateInstanceExtensionProperties and flink:vkEnumerateDeviceExtensionProperties (public issue 285) * Fix several cases of stext::VkStructName.memberName markup to stext::VkStructName::pname:memberName, to match other usage in the spec, and describe this markup in the style guide (public issue 286). * Modified validity language generation script to avoid redundant common ancestor language if covered by generic parent language, and used `Both' instead of `Each' when appropriate (public issue 288). Internal Issues: * Add language about behavior of flink:vkAllocateDescriptorSets when allocation fails due to fragmentation, a new error ename:VK_ERROR_FRAGMENTED_POOL, and a Note explaining the situation (internal issue 309). * For the features of code:PointSize, code:ClipDistance, and code:CullDistance, the SPIR-V capability is required to be declared on use (read or write) rather than on decoration (internal issue 359). * Have desktop versions of GLSL respect precision qualification (code:mediump and code:lowp) when compiling for Vulkan. These will get translated to SPIR-V's code:RelaxedPrecision decoration as they do with OpenGL ES versions of GLSL (ESSL). The default precision of all types is code:highp when using a desktop version (internal issue 360). * Add validity statement for slink:VkImageCreateInfo specifying that multisampled images must be two-dimensional, optimally tiled, and with a single mipmap level (internal issue 369). * Add validity statements to slink:VkImageViewCreateInfo disallowing creation of images or image views with no supported features. Made some slink:VkImageViewCreateInfo validity statements more precise and consistent. Added a Note to the <<features,features>> chapter about formats with no features (internal issue 371). * Remove +manpages+ from default build targets. Nroff outputs containing imbedded latexmath will not render properly. Fixing this is a lot of work for limited use cases (internal issue 401). Other Commits: * Fix flink:vkRenderPassBeginInfo::pname:clearValueCount validity statement to be based on attachment indices rather than the number of cleared attachments (Vulkan-LoaderAndValidationLayers/issues/601). * Convert registry documentation from LaTeX to asciidoc source and rename from +src/spec/readme.tex+ to +src/spec/registry.txt+. * Fix lack of Oxford commas in validity language. * Lots of cleanup of generator scripts and Makefiles to move extension list for generator into the script arguments instead of the body of genvk.py, and express better dependencies between XML, scripts, and generated files.
2016-07-23 10:15:48 +00:00
self.logMsg('diag', 'PyOutputGenerator::genType: unprocessed type:', name)
#
# Struct (e.g. C "struct" type) generation.
#
# Add the struct name to the 'structs' dictionary, with the
# value being an ordered list of the struct member names.
def genStruct(self, typeinfo, typeName):
OutputGenerator.genStruct(self, typeinfo, typeName)
members = [member.text for member in typeinfo.elem.findall('.//member/name')]
self.structs[typeName] = members
memberTypes = [member.text for member in typeinfo.elem.findall('.//member/type')]
for type in memberTypes:
self.addMapping(typeName, type)
#
# Group (e.g. C "enum" type) generation.
# These are concatenated together with other types.
#
# Add the enum type name to the 'enums' dictionary, with
# the value being an ordered list of the enumerant names.
# Add each enumerant name to the 'consts' dictionary, with
# the value being the enum type the enumerant is part of.
def genGroup(self, groupinfo, groupName):
OutputGenerator.genGroup(self, groupinfo, groupName)
groupElem = groupinfo.elem
# Loop over the nested 'enum' tags.
enumerants = [elem.get('name') for elem in groupElem.findall('enum')]
for name in enumerants:
self.addName(self.consts, name, groupName)
self.enums[groupName] = enumerants
# Enumerant generation (compile-time constants)
#
# Add the constant name to the 'consts' dictionary, with the
# value being None to indicate that the constant isn't
# an enumeration value.
def genEnum(self, enuminfo, name):
OutputGenerator.genEnum(self, enuminfo, name)
# Add a typeCategory{} entry for the category of this type.
self.addName(self.typeCategory, name, 'consts')
self.consts[name] = None
#
# Command generation
#
# Add the command name to the 'protos' dictionary, with the
# value being an ordered list of the parameter names.
def genCmd(self, cmdinfo, name):
OutputGenerator.genCmd(self, cmdinfo, name)
# Add a typeCategory{} entry for the category of this type.
self.addName(self.typeCategory, name, 'protos')
params = [param.text for param in cmdinfo.elem.findall('param/name')]
self.protos[name] = params
paramTypes = [param.text for param in cmdinfo.elem.findall('param/type')]
for type in paramTypes:
self.addMapping(name, type)