summaryrefslogtreecommitdiff
path: root/codegen/vulkan/scripts/Retired/extensionStubSource.py
diff options
context:
space:
mode:
Diffstat (limited to 'codegen/vulkan/scripts/Retired/extensionStubSource.py')
-rw-r--r--codegen/vulkan/scripts/Retired/extensionStubSource.py327
1 files changed, 327 insertions, 0 deletions
diff --git a/codegen/vulkan/scripts/Retired/extensionStubSource.py b/codegen/vulkan/scripts/Retired/extensionStubSource.py
new file mode 100644
index 00000000..b9ff837e
--- /dev/null
+++ b/codegen/vulkan/scripts/Retired/extensionStubSource.py
@@ -0,0 +1,327 @@
+#!/usr/bin/python3 -i
+#
+# Copyright 2013-2021 The Khronos Group Inc.
+#
+# SPDX-License-Identifier: Apache-2.0
+
+import os,re,sys
+from generator import *
+
+doc = """
+/*
+** This target is no longer maintained and supported.
+** See README.adoc for discussion.
+**
+** This is a simple extension loader which provides the implementations for the
+** extension prototypes declared in vulkan header. It supports loading extensions either
+** for a single instance or a single device. Multiple instances are not yet supported.
+**
+** To use the loader add vulkan_ext.c to your solution and include <vulkan/vulkan_ext.h>.
+**
+** If your application is using a single instance, but multiple devices callParam
+**
+** vkExtInitInstance(instance);
+**
+** after initializing the instance. This way the extension loader will use the loaders
+** trampoline functions to call the correct driver for each call. This method is safe
+** if your application might use more than one device at the cost of one additional
+** indirection, the dispatch table of each dispatchable object.
+**
+** If your application uses only a single device it's better to use
+**
+** vkExtInitDevice(device);
+**
+** once the device has been initialized. This will resolve the function pointers
+** upfront and thus removes one indirection for each call into the driver. This *can*
+** result in slightly more performance for calling overhead limited cases.
+*/
+"""
+
+# StubExtGeneratorOptions - subclass of GeneratorOptions.
+#
+# Adds options used by COutputGenerator objects during C language header
+# generation.
+#
+# Additional members
+# prefixText - list of strings to prefix generated header with
+# (usually a copyright statement + calling convention macros).
+# alignFuncParam - if nonzero and parameters are being put on a
+# separate line, align parameter names at the specified column
+class StubExtGeneratorOptions(GeneratorOptions):
+ """Represents options during C interface generation for headers"""
+ def __init__(self,
+ filename = None,
+ directory = '.',
+ apiname = None,
+ profile = None,
+ versions = '.*',
+ emitversions = '.*',
+ defaultExtensions = None,
+ addExtensions = None,
+ removeExtensions = None,
+ emitExtensions = None,
+ sortProcedure = regSortFeatures,
+ prefixText = "",
+ alignFuncParam = 0):
+ GeneratorOptions.__init__(self, filename, directory, apiname, profile,
+ versions, emitversions, defaultExtensions,
+ addExtensions, removeExtensions,
+ emitExtensions, sortProcedure)
+ self.prefixText = prefixText
+ self.alignFuncParam = alignFuncParam
+
+# ExtensionStubSourceOutputGenerator - subclass of OutputGenerator.
+# Generates C-language extension wrapper interface sources.
+#
+# ---- methods ----
+# ExtensionStubSourceOutputGenerator(errFile, warnFile, diagFile) - args as for
+# OutputGenerator. Defines additional internal state.
+# ---- methods overriding base class ----
+# beginFile(genOpts)
+# endFile()
+# beginFeature(interface, emit)
+# endFeature()
+# genType(typeinfo,name)
+# genStruct(typeinfo,name)
+# genGroup(groupinfo,name)
+# genEnum(enuminfo, name)
+# genCmd(cmdinfo)
+class ExtensionStubSourceOutputGenerator(OutputGenerator):
+ """Generate specified API interfaces in a specific style, such as a C header"""
+ # This is an ordered list of sections in the header file.
+ TYPE_SECTIONS = ['include', 'define', 'basetype', 'handle', 'enum',
+ 'group', 'bitmask', 'funcpointer', 'struct']
+ ALL_SECTIONS = TYPE_SECTIONS + ['commandPointer', 'command']
+ 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)
+ # C-specific
+ #
+ # Multiple inclusion protection & C++ wrappers.
+
+ # Internal state - accumulators for function pointers and function
+ # pointer initializatoin
+ self.pointers = [];
+ self.pointerInitializersInstance = [];
+ self.pointerInitializersDevice = [];
+
+ #
+ # Write header protection
+ filename = self.genOpts.directory + '/' + 'vulkan_ext.h'
+ self.outFileHeader = open(filename, 'w', encoding='utf-8')
+
+ write('#ifndef VULKAN_EXT_H', file=self.outFileHeader)
+ write('#define VULKAN_EXT_H', file=self.outFileHeader)
+ write('', file=self.outFileHeader)
+ write('#ifdef __cplusplus', file=self.outFileHeader)
+ write('extern "C" {', file=self.outFileHeader)
+ write('#endif', file=self.outFileHeader)
+
+ #
+ # User-supplied prefix text, if any (list of strings)
+ if (genOpts.prefixText):
+ for s in genOpts.prefixText:
+ write(s, file=self.outFile)
+ write(s, file=self.outFileHeader)
+
+ write(doc, file=self.outFileHeader)
+
+ write('#include <vulkan/vulkan.h>', file=self.outFile)
+ self.newline()
+
+ write('#include <vulkan/vulkan_core.h>', file=self.outFileHeader)
+ write('', file=self.outFileHeader)
+
+ write('void vkExtInitInstance(VkInstance instance);', file=self.outFileHeader)
+ write('void vkExtInitDevice(VkDevice device);', file=self.outFileHeader)
+ write('', file=self.outFileHeader)
+
+ def endFile(self):
+ for pointer in self.pointers:
+ write(pointer, file=self.outFile)
+
+ self.newline()
+
+ write('void vkExtInitInstance(VkInstance instance)\n{', file=self.outFile)
+ for pointerInitializer in self.pointerInitializersInstance:
+ write(pointerInitializer, file=self.outFile)
+ write('}', file=self.outFile)
+
+ self.newline()
+
+ write('void vkExtInitDevice(VkDevice device)\n{', file=self.outFile)
+ for pointerInitializer in self.pointerInitializersDevice:
+ write(pointerInitializer, file=self.outFile)
+ write('}', file=self.outFile)
+
+ self.newline()
+
+ #Finish header file
+ write('#ifdef __cplusplus', file=self.outFileHeader)
+ write('}', file=self.outFileHeader)
+ write('#endif', file=self.outFileHeader)
+ write('', file=self.outFileHeader)
+ write('#endif', file=self.outFileHeader)
+ self.outFileHeader.close()
+
+ # Finish processing in superclass
+ OutputGenerator.endFile(self)
+
+ def beginFeature(self, interface, emit):
+ # Start processing in superclass
+ OutputGenerator.beginFeature(self, interface, emit)
+
+ # Accumulate function pointers and function pointer initialization
+ self.featurePointers = []
+ self.featurePointerInitializersInstance = []
+ self.featurePointerInitializersDevice = []
+
+ def endFeature(self):
+ # Add feature to global list with protectFeature
+ if (self.emit and self.featurePointers):
+ if (self.genOpts.protectFeature):
+ self.pointers.append('#ifdef ' + self.featureName)
+ self.pointerInitializersInstance.append('#ifdef ' + self.featureName)
+ self.pointerInitializersDevice.append('#ifdef ' + self.featureName)
+
+ if (self.featureExtraProtect != None):
+ self.pointers.append('#ifdef ' + self.featureExtraProtect)
+ self.pointerInitializersInstance.append('#ifndef ' + self.featureName)
+ self.pointerInitializersDevice.append('#ifndef ' + self.featureName)
+
+ self.pointers += self.featurePointers;
+ self.pointerInitializersInstance += self.featurePointerInitializersInstance;
+ self.pointerInitializersDevice += self.featurePointerInitializersDevice;
+
+ if (self.featureExtraProtect != None):
+ self.pointers.append('#endif /* ' + self.featureExtraProtect + ' */')
+ self.pointerInitializersInstance.append('#endif /* ' + self.featureExtraProtect + ' */')
+ self.pointerInitializersDevice.append('#endif /* ' + self.featureExtraProtect + ' */')
+ if (self.genOpts.protectFeature):
+ self.pointers.append('#endif /* ' + self.featureName + ' */')
+ self.pointerInitializersInstance.append('#endif /* ' + self.featureName + ' */')
+ self.pointerInitializersDevice.append('#endif /* ' + self.featureName + ' */')
+
+ # Finish processing in superclass
+ OutputGenerator.endFeature(self)
+ #
+ # Type generation
+ def genType(self, typeinfo, name, alias):
+ pass
+
+ def genStruct(self, typeinfo, typeName, alias):
+ pass
+
+ def genGroup(self, groupinfo, groupName, alias):
+ pass
+
+ def genEnum(self, enuminfo, name, alias):
+ pass
+
+ #
+ # Command generation
+ def genCmd(self, cmdinfo, name, alias):
+ OutputGenerator.genCmd(self, cmdinfo, name, alias)
+
+ #
+ decls = self.makeStub(cmdinfo.elem)
+ self.featurePointerInitializersInstance.append(decls[0])
+ self.featurePointerInitializersDevice.append(decls[1])
+ self.featurePointers.append(decls[2])
+
+ #
+ # makeStub - return static declaration for function pointer and initialization of function pointer
+ # as a two-element list of strings.
+ # cmd - Element containing a <command> tag
+ def makeStub(self, cmd):
+ """Generate a stub function pointer <command> Element"""
+ proto = cmd.find('proto')
+ params = cmd.findall('param')
+ name = cmd.find('name')
+
+ # Begin accumulating prototype and typedef strings
+ pfnDecl = 'static '
+ pfnDecl += noneStr(proto.text)
+
+ # Find the name tag and generate the function pointer and function pointer initialization code
+ nameTag = proto.find('name')
+ tail = noneStr(nameTag.tail)
+ returnType = noneStr(proto.find('type').text)
+
+ type = self.makeFunctionPointerType(nameTag.text, tail)
+
+ # For each child element, if it's a <name> wrap in appropriate
+ # declaration. Otherwise append its contents and tail con#tents.
+ stubDecl = ''
+ for elem in proto:
+ text = noneStr(elem.text)
+ tail = noneStr(elem.tail)
+ if (elem.tag == 'name'):
+ name = self.makeProtoName(text, tail)
+ stubDecl += name
+ else:
+ stubDecl += text + tail
+
+ pfnName = self.makeFunctionPointerName(nameTag.text, noneStr(tail));
+ pfnDecl += type + ' ' + pfnName + ';'
+
+ # Now generate the stub function
+ pfnDecl += '\n'
+
+ # Now add the parameter declaration list, which is identical
+ # for prototypes and typedefs. Concatenate all the text from
+ # a <param> node without the tags. No tree walking required
+ # since all tags are ignored.
+ n = len(params)
+ paramdecl = '(\n'
+
+ pfnCall = '\n{\n ' + ('return ', '')[returnType == 'void'] + pfnName + '(\n'
+ # Indented parameters
+ if n > 0:
+ indentCallParam = '(\n'
+ indentdecl = '(\n'
+ for i in range(0,n):
+ callParam = ''
+
+ paramdecl += self.makeCParamDecl(params[i], self.genOpts.alignFuncParam)
+ pfnCall += self.makeCCallParam(params[i], self.genOpts.alignFuncParam)
+ if (i < n - 1):
+ paramdecl += ',\n'
+ pfnCall += ',\n'
+ else:
+ paramdecl += ')'
+ pfnCall += '\n );\n'
+ indentdecl += paramdecl
+ indentCallParam += pfnCall
+ else:
+ indentdecl = '(void);'
+
+ pfnCall += '}\n'
+
+ featureInstance = ' ' + pfnName + ' = ('+type+')vkGetInstanceProcAddr(instance, "' + name + '");'
+ featureDevice = ' ' + pfnName + ' = ('+type+')vkGetDeviceProcAddr(device, "' + name + '");'
+ return [featureInstance, featureDevice , pfnDecl + stubDecl + paramdecl + pfnCall]
+
+ # Return function pointer type for given function
+ def makeFunctionPointerType(self, name, tail):
+ return 'PFN_' + name + tail
+
+ # Return name of static variable which stores the function pointer for the given function
+ def makeFunctionPointerName(self, name, tail):
+ return 'pfn_' + name + tail
+
+ #
+ # makeCParamDecl - return a string which is an indented, formatted
+ # declaration for a <param> or <member> block (e.g. function parameter
+ # or structure/union member).
+ # param - Element (<param> or <member>) to format
+ # aligncol - if non-zero, attempt to align the nested <name> element
+ # at this column
+ def makeCCallParam(self, param, aligncol):
+ return ' ' + param.find('name').text
+