diff options
Diffstat (limited to 'src/kosmickrisp/util/vk_entrypoints.py')
| -rw-r--r-- | src/kosmickrisp/util/vk_entrypoints.py | 147 |
1 files changed, 147 insertions, 0 deletions
diff --git a/src/kosmickrisp/util/vk_entrypoints.py b/src/kosmickrisp/util/vk_entrypoints.py new file mode 100644 index 00000000000..a8280bae2ff --- /dev/null +++ b/src/kosmickrisp/util/vk_entrypoints.py @@ -0,0 +1,147 @@ +# Copyright 2020 Intel Corporation +# +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sub license, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice (including the +# next paragraph) shall be included in all copies or substantial portions +# of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. +# IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR +# ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +import xml.etree.ElementTree as et + +from collections import OrderedDict, namedtuple + +# Mesa-local imports must be declared in meson variable +# '{file_without_suffix}_depend_files'. +from vk_extensions import get_all_required, filter_api + +EntrypointParam = namedtuple('EntrypointParam', 'type name decl len') + +class EntrypointBase: + def __init__(self, name): + assert name.startswith('vk') + self.name = name[2:] + self.alias = None + self.guard = None + self.entry_table_index = None + # Extensions which require this entrypoint + self.core_version = None + self.extensions = [] + + def prefixed_name(self, prefix): + return prefix + '_' + self.name + +class Entrypoint(EntrypointBase): + def __init__(self, name, return_type, params): + super(Entrypoint, self).__init__(name) + self.return_type = return_type + self.params = params + self.guard = None + self.aliases = [] + self.disp_table_index = None + + def is_physical_device_entrypoint(self): + return self.params[0].type in ('VkPhysicalDevice', ) + + def is_device_entrypoint(self): + return self.params[0].type in ('VkDevice', 'VkCommandBuffer', 'VkQueue') + + def decl_params(self, start=0): + return ', '.join(p.decl for p in self.params[start:]) + + def call_params(self, start=0): + return ', '.join(p.name for p in self.params[start:]) + +class EntrypointAlias(EntrypointBase): + def __init__(self, name, entrypoint): + super(EntrypointAlias, self).__init__(name) + self.alias = entrypoint + entrypoint.aliases.append(self) + + def is_physical_device_entrypoint(self): + return self.alias.is_physical_device_entrypoint() + + def is_device_entrypoint(self): + return self.alias.is_device_entrypoint() + + def prefixed_name(self, prefix): + return self.alias.prefixed_name(prefix) + + @property + def params(self): + return self.alias.params + + @property + def return_type(self): + return self.alias.return_type + + @property + def disp_table_index(self): + return self.alias.disp_table_index + + def decl_params(self): + return self.alias.decl_params() + + def call_params(self): + return self.alias.call_params() + +def get_entrypoints(doc, api, beta): + """Extract the entry points from the registry.""" + entrypoints = OrderedDict() + + required = get_all_required(doc, 'command', api, beta) + + for command in doc.findall('./commands/command'): + if not filter_api(command, api): + continue + + if 'alias' in command.attrib: + name = command.attrib['name'] + target = command.attrib['alias'] + e = EntrypointAlias(name, entrypoints[target]) + else: + name = command.find('./proto/name').text + ret_type = command.find('./proto/type').text + params = [EntrypointParam( + type=p.find('./type').text, + name=p.find('./name').text, + decl=''.join(p.itertext()), + len=p.attrib.get('altlen', p.attrib.get('len', None)) + ) for p in command.findall('./param') if filter_api(p, api)] + # They really need to be unique + e = Entrypoint(name, ret_type, params) + + if name not in required: + continue + + r = required[name] + e.core_version = r.core_version + e.extensions = r.extensions + e.guard = r.guard + + assert name not in entrypoints, name + entrypoints[name] = e + + return entrypoints.values() + +def get_entrypoints_from_xml(xml_files, beta, api='vulkan'): + entrypoints = [] + + for filename in xml_files: + doc = et.parse(filename) + entrypoints += get_entrypoints(doc, api, beta) + + return entrypoints |