diff --git a/src/vulkan/runtime/vk_render_pass.h b/src/vulkan/runtime/vk_render_pass.h index e041f44ab34..36e5d0270c7 100644 --- a/src/vulkan/runtime/vk_render_pass.h +++ b/src/vulkan/runtime/vk_render_pass.h @@ -37,6 +37,7 @@ extern "C" { typedef struct VkRenderingSelfDependencyInfoMESA { VkStructureType sType; #define VK_STRUCTURE_TYPE_RENDERING_SELF_DEPENDENCY_INFO_MESA (VkStructureType)1000044900 +#define VK_STRUCTURE_TYPE_RENDERING_SELF_DEPENDENCY_INFO_MESA_cast VkRenderingSelfDependencyInfoMESA const void* pNext; /** Bitset of which color attachments have self-dependencies */ @@ -73,6 +74,7 @@ typedef struct VkRenderingSelfDependencyInfoMESA { typedef struct VkRenderingAttachmentInitialLayoutInfoMESA { VkStructureType sType; #define VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INITIAL_LAYOUT_INFO_MESA (VkStructureType)1000044901 +#define VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INITIAL_LAYOUT_INFO_MESA_cast VkRenderingAttachmentInitialLayoutInfoMESA const void* pNext; /** Initial layout of the attachment */ diff --git a/src/vulkan/util/meson.build b/src/vulkan/util/meson.build index 589b4f9a396..9d12380cfdf 100644 --- a/src/vulkan/util/meson.build +++ b/src/vulkan/util/meson.build @@ -86,6 +86,16 @@ vk_enum_to_str = custom_target( ], ) +vk_struct_type_cast = custom_target( + 'vk_struct_type_cast', + input : ['vk_struct_type_cast_gen.py', vk_api_xml], + output : ['vk_struct_type_cast.h'], + command : [ + prog_python, '@INPUT0@', '--xml', '@INPUT1@', + '--outdir', meson.current_build_dir() + ], +) + vk_extensions = custom_target( 'vk_extensions', input : ['vk_extensions_gen.py', vk_api_xml], @@ -99,7 +109,8 @@ vk_extensions = custom_target( libvulkan_util = static_library( 'vulkan_util', - [files_vulkan_util, vk_dispatch_table, vk_enum_to_str, vk_extensions], + [files_vulkan_util, vk_dispatch_table, vk_enum_to_str, + vk_struct_type_cast, vk_extensions], include_directories : [inc_include, inc_src, inc_gallium], dependencies : [vulkan_wsi_deps, idep_mesautil, idep_nir_headers], c_args : [c_msvc_compat_args], @@ -108,7 +119,8 @@ libvulkan_util = static_library( ) idep_vulkan_util_headers = declare_dependency( - sources : [vk_dispatch_table[1], vk_enum_to_str[1], vk_extensions[1]], + sources : [vk_dispatch_table[1], vk_enum_to_str[1], + vk_struct_type_cast[0], vk_extensions[1]], include_directories : include_directories('.') ) diff --git a/src/vulkan/util/vk_struct_type_cast_gen.py b/src/vulkan/util/vk_struct_type_cast_gen.py new file mode 100644 index 00000000000..b5df1819007 --- /dev/null +++ b/src/vulkan/util/vk_struct_type_cast_gen.py @@ -0,0 +1,115 @@ +# Copyright © 2023 Igalia S.L. +# SPDX-License-Identifier: MIT + +"""Create shortcuts for casting Vulkan structs when knowing their stype.""" + +import argparse +import functools +import os +import re +import textwrap +import xml.etree.ElementTree as et + +from mako.template import Template +from vk_extensions import Extension, filter_api, get_all_required + +COPYRIGHT = textwrap.dedent(u"""\ + * Copyright © 2023 Igalia S.L. + * SPDX-License-Identifier: MIT + """) + +H_TEMPLATE = Template(textwrap.dedent(u"""\ + /* Autogenerated file -- do not edit + * generated by ${file} + * + ${copyright} + */ + + #ifndef MESA_VK_STRUCT_CASTS_H + #define MESA_VK_STRUCT_CASTS_H + + #include + + #ifdef __cplusplus + extern "C" { + #endif + + % for s in structs: + #define ${s.stype}_cast ${s.name} + % endfor + + #ifdef __cplusplus + } /* extern "C" */ + #endif + + #endif""")) + + +class VkStruct(object): + """Simple struct-like class representing a single Vulkan struct identified with a VkStructureType""" + def __init__(self, name, stype): + self.name = name + self.stype = stype + + +def struct_get_stype(xml_node): + for member in xml_node.findall('./member'): + name = member.findall('./name') + if len(name) > 0 and name[0].text == "sType": + return member.get('values') + return None + + +def parse_xml(filename, structs): + xml = et.parse(filename) + api = 'vulkan' + + required_types = get_all_required(xml, 'type', api) + + for struct_type in xml.findall('./types/type[@category="struct"]'): + if not filter_api(struct_type, api): + continue + + name = struct_type.attrib['name'] + if name not in required_types: + continue + + stype = struct_get_stype(struct_type) + if stype is not None: + structs.append(VkStruct(name, stype)) + + for struct_type in xml.findall('.//enum[@alias][@extends=\'VkStructureType\']'): + name = struct_type.attrib['name'] + alias = struct_type.attrib['alias'] + structs.append(VkStruct(alias + "_cast", name)) + + +def main(): + parser = argparse.ArgumentParser() + parser.add_argument('--xml', required=True, + help='Vulkan API XML files', + action='append', + dest='xml_files') + parser.add_argument('--outdir', + help='Directory to put the generated files in', + required=True) + + args = parser.parse_args() + + structs = [] + + for filename in args.xml_files: + parse_xml(filename, structs) + + structs = sorted(structs, key=lambda s: s.name) + + for template, file_ in [(H_TEMPLATE, os.path.join(args.outdir, 'vk_struct_type_cast.h'))]: + with open(file_, 'w', encoding='utf-8') as f: + f.write(template.render( + file=os.path.basename(__file__), + structs=structs, + copyright=COPYRIGHT)) + + +if __name__ == '__main__': + main() diff --git a/src/vulkan/util/vk_util.h b/src/vulkan/util/vk_util.h index 77dfa291c63..b1a65c1b8b7 100644 --- a/src/vulkan/util/vk_util.h +++ b/src/vulkan/util/vk_util.h @@ -29,6 +29,8 @@ #include #include +#include "vk_struct_type_cast.h" + #ifdef __cplusplus extern "C" { #endif @@ -269,11 +271,13 @@ __vk_find_struct(void *start, VkStructureType sType) return NULL; } -#define vk_find_struct(__start, __sType) \ - __vk_find_struct((__start), VK_STRUCTURE_TYPE_##__sType) +#define vk_find_struct(__start, __sType) \ + (VK_STRUCTURE_TYPE_##__sType##_cast *)__vk_find_struct( \ + (__start), VK_STRUCTURE_TYPE_##__sType) -#define vk_find_struct_const(__start, __sType) \ - (const void *)__vk_find_struct((void *)(__start), VK_STRUCTURE_TYPE_##__sType) +#define vk_find_struct_const(__start, __sType) \ + (const VK_STRUCTURE_TYPE_##__sType##_cast *)__vk_find_struct( \ + (void *)(__start), VK_STRUCTURE_TYPE_##__sType) static inline void __vk_append_struct(void *start, void *element) diff --git a/src/vulkan/wsi/wsi_common.h b/src/vulkan/wsi/wsi_common.h index 8a8138e91e5..346025602b9 100644 --- a/src/vulkan/wsi/wsi_common.h +++ b/src/vulkan/wsi/wsi_common.h @@ -51,6 +51,11 @@ extern const struct vk_device_entrypoint_table wsi_device_entrypoints; #define VK_STRUCTURE_TYPE_WSI_SURFACE_SUPPORTED_COUNTERS_MESA (VkStructureType)1000001005 #define VK_STRUCTURE_TYPE_WSI_MEMORY_SIGNAL_SUBMIT_INFO_MESA (VkStructureType)1000001006 +#define VK_STRUCTURE_TYPE_WSI_IMAGE_CREATE_INFO_MESA_cast struct wsi_image_create_info +#define VK_STRUCTURE_TYPE_WSI_MEMORY_ALLOCATE_INFO_MESA_cast struct wsi_memory_allocate_info +#define VK_STRUCTURE_TYPE_WSI_SURFACE_SUPPORTED_COUNTERS_MESA_cast struct wsi_surface_supported_counters +#define VK_STRUCTURE_TYPE_WSI_MEMORY_SIGNAL_SUBMIT_INFO_MESA_cast struct wsi_memory_signal_submit_info + /* This is always chained to VkImageCreateInfo when a wsi image is created. * It indicates that the image can be transitioned to/from * VK_IMAGE_LAYOUT_PRESENT_SRC_KHR.