diff options
author | Lionel Landwerlin <[email protected]> | 2019-03-05 10:38:14 +0000 |
---|---|---|
committer | Lionel Landwerlin <[email protected]> | 2019-03-06 22:46:37 +0000 |
commit | 530927d3f6a303d9ef1eb1e839566ccb0e813036 (patch) | |
tree | b841f6a3c8e8b727c4d68e16c235c9ab69191103 /src/vulkan/util | |
parent | ee491a4987d0b1698971343dce9f5460b1521e9a (diff) |
vulkan/util: generate instance/device dispatch tables
This will be used by the overlay instead of system installed
validation layers helpers.
Signed-off-by: Lionel Landwerlin <[email protected]>
Acked-by: Eric Engestrom <[email protected]>
Diffstat (limited to 'src/vulkan/util')
-rw-r--r-- | src/vulkan/util/gen_enum_to_str.py | 118 | ||||
-rw-r--r-- | src/vulkan/util/meson.build | 2 |
2 files changed, 114 insertions, 6 deletions
diff --git a/src/vulkan/util/gen_enum_to_str.py b/src/vulkan/util/gen_enum_to_str.py index 06f74eb487c..cf031670ff7 100644 --- a/src/vulkan/util/gen_enum_to_str.py +++ b/src/vulkan/util/gen_enum_to_str.py @@ -57,6 +57,7 @@ C_TEMPLATE = Template(textwrap.dedent(u"""\ ${copyright} */ + #include <string.h> #include <vulkan/vulkan.h> #include <vulkan/vk_android_native_buffer.h> #include "util/macros.h" @@ -85,7 +86,46 @@ C_TEMPLATE = Template(textwrap.dedent(u"""\ unreachable("Undefined enum value."); } } - %endfor"""), + %endfor + + void vk_load_instance_commands(VkInstance instance, + PFN_vkGetInstanceProcAddr gpa, + struct vk_instance_dispatch_table *table) + { + memset(table, 0, sizeof(*table)); + table->GetInstanceProcAddr = gpa; + % for cmd in commands: + % if not cmd.device_entrypoint and cmd.name != 'vkGetInstanceProcAddr': + % if cmd.extension is not None and cmd.extension.define is not None: + #ifdef ${cmd.extension.define} + table->${cmd.name[2:]} = (PFN_${cmd.name}) gpa(instance, "${cmd.name}"); + #endif + % else: + table->${cmd.name[2:]} = (PFN_${cmd.name}) gpa(instance, "${cmd.name}"); + % endif + % endif + %endfor + } + + void vk_load_device_commands(VkDevice device, + PFN_vkGetDeviceProcAddr gpa, + struct vk_device_dispatch_table *table) + { + memset(table, 0, sizeof(*table)); + table->GetDeviceProcAddr = gpa; + % for cmd in commands: + % if cmd.device_entrypoint and cmd.name != 'vkGetDeviceProcAddr': + % if cmd.extension is not None and cmd.extension.define is not None: + #ifdef ${cmd.extension.define} + table->${cmd.name[2:]} = (PFN_${cmd.name}) gpa(device, "${cmd.name}"); + #endif + % else: + table->${cmd.name[2:]} = (PFN_${cmd.name}) gpa(device, "${cmd.name}"); + % endif + % endif + %endfor + } + """), output_encoding='utf-8') H_TEMPLATE = Template(textwrap.dedent(u"""\ @@ -113,6 +153,39 @@ H_TEMPLATE = Template(textwrap.dedent(u"""\ const char * vk_${enum.name[2:]}_to_str(${enum.name} input); % endfor + struct vk_instance_dispatch_table { + PFN_vkGetInstanceProcAddr GetInstanceProcAddr; + % for cmd in commands: + % if not cmd.device_entrypoint and cmd.name != 'vkGetInstanceProcAddr': + % if cmd.extension is not None and cmd.extension.define is not None: + #ifdef ${cmd.extension.define} + PFN_${cmd.name} ${cmd.name[2:]}; + #endif + % else: + PFN_${cmd.name} ${cmd.name[2:]}; + % endif + % endif + %endfor + }; + + struct vk_device_dispatch_table { + PFN_vkGetDeviceProcAddr GetDeviceProcAddr; + % for cmd in commands: + % if cmd.device_entrypoint and cmd.name != 'vkGetDeviceProcAddr': + % if cmd.extension is not None and cmd.extension.define is not None: + #ifdef ${cmd.extension.define} + PFN_${cmd.name} ${cmd.name[2:]}; + #endif + % else: + PFN_${cmd.name} ${cmd.name[2:]}; + % endif + % endif + %endfor + }; + + void vk_load_instance_commands(VkInstance instance, PFN_vkGetInstanceProcAddr gpa, struct vk_instance_dispatch_table *table); + void vk_load_device_commands(VkDevice device, PFN_vkGetDeviceProcAddr gpa, struct vk_device_dispatch_table *table); + #ifdef __cplusplus } /* extern "C" */ #endif @@ -148,9 +221,15 @@ class NamedFactory(object): class VkExtension(object): """Simple struct-like class representing extensions""" - def __init__(self, name, number=None): + def __init__(self, name, number=None, platform=None): self.name = name self.number = number + self.define = None + if platform is not None: + ext = '_KHR' + if platform.upper() == 'XLIB_XRANDR': + ext = '_EXT' + self.define = 'VK_USE_PLATFORM_' + platform.upper() + ext class VkEnum(object): @@ -196,7 +275,16 @@ class VkEnum(object): error=error) -def parse_xml(enum_factory, ext_factory, filename): +class VkCommand(object): + """Simple struct-like class representing a single Vulkan command""" + + def __init__(self, name, device_entrypoint=False): + self.name = name + self.device_entrypoint = device_entrypoint + self.extension = None + + +def parse_xml(cmd_factory, enum_factory, ext_factory, filename): """Parse the XML file. Accumulate results into the factories. This parser is a memory efficient iterative XML parser that returns a list @@ -215,15 +303,32 @@ def parse_xml(enum_factory, ext_factory, filename): if enum is not None: enum.add_value_from_xml(value) + for command in xml.findall('./commands/command'): + name = command.find('./proto/name') + first_arg = command.find('./param/type') + # Some commands are alias KHR -> nonKHR, ignore those + if name is not None: + cmd_factory(name.text, + device_entrypoint=(first_arg.text in ('VkDevice', 'VkCommandBuffer', 'VkQueue'))) + for ext_elem in xml.findall('./extensions/extension[@supported="vulkan"]'): + platform = None + if "platform" in ext_elem.attrib: + platform = ext_elem.attrib['platform'] extension = ext_factory(ext_elem.attrib['name'], - number=int(ext_elem.attrib['number'])) + number=int(ext_elem.attrib['number']), + platform=platform) for value in ext_elem.findall('./require/enum[@extends]'): enum = enum_factory.get(value.attrib['extends']) if enum is not None: enum.add_value_from_xml(value, extension) + for t in ext_elem.findall('./require/command'): + command = cmd_factory.get(t.attrib['name']) + if command is not None: + command.extension = extension + def main(): parser = argparse.ArgumentParser() @@ -237,10 +342,12 @@ def main(): args = parser.parse_args() + command_factory = NamedFactory(VkCommand) enum_factory = NamedFactory(VkEnum) ext_factory = NamedFactory(VkExtension) for filename in args.xml_files: - parse_xml(enum_factory, ext_factory, filename) + parse_xml(command_factory, enum_factory, ext_factory, filename) + commands = sorted(command_factory.registry.values(), key=lambda e: e.name) enums = sorted(enum_factory.registry.values(), key=lambda e: e.name) extensions = sorted(ext_factory.registry.values(), key=lambda e: e.name) @@ -249,6 +356,7 @@ def main(): with open(file_, 'wb') as f: f.write(template.render( file=os.path.basename(__file__), + commands=commands, enums=enums, extensions=extensions, copyright=COPYRIGHT, diff --git a/src/vulkan/util/meson.build b/src/vulkan/util/meson.build index df09dd35f85..6aba265cc81 100644 --- a/src/vulkan/util/meson.build +++ b/src/vulkan/util/meson.build @@ -40,6 +40,6 @@ libvulkan_util = static_library( 'vulkan_util', [files_vulkan_util, vk_enum_to_str], include_directories : inc_common, - c_args : [c_vis_args], + c_args : [c_vis_args, vulkan_wsi_args], build_by_default : false, ) |