xref: /aosp_15_r20/external/mesa3d/src/vulkan/util/vk_extensions_gen.py (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1COPYRIGHT = """\
2/*
3 * Copyright 2017 Intel Corporation
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the
7 * "Software"), to deal in the Software without restriction, including
8 * without limitation the rights to use, copy, modify, merge, publish,
9 * distribute, sub license, and/or sell copies of the Software, and to
10 * permit persons to whom the Software is furnished to do so, subject to
11 * the following conditions:
12 *
13 * The above copyright notice and this permission notice (including the
14 * next paragraph) shall be included in all copies or substantial portions
15 * of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
20 * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
21 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
22 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
23 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 */
25"""
26
27import argparse
28
29from mako.template import Template
30
31# Mesa-local imports must be declared in meson variable
32# '{file_without_suffix}_depend_files'.
33from vk_extensions import get_all_exts_from_xml, init_exts_from_xml
34
35_TEMPLATE_H = Template(COPYRIGHT + """
36
37#ifndef VK_EXTENSIONS_H
38#define VK_EXTENSIONS_H
39
40#include <stdbool.h>
41
42<%def name="extension_table(type, extensions)">
43#define VK_${type.upper()}_EXTENSION_COUNT ${len(extensions)}
44
45extern const VkExtensionProperties vk_${type}_extensions[];
46
47struct vk_${type}_extension_table {
48   union {
49      bool extensions[VK_${type.upper()}_EXTENSION_COUNT];
50      struct {
51%for ext in extensions:
52         bool ${ext.name[3:]};
53%endfor
54      };
55
56      /* Workaround for "error: too many initializers for vk_${type}_extension_table" */
57      struct {
58%for ext in extensions:
59         bool ${ext.name[3:]};
60%endfor
61      } table;
62   };
63};
64</%def>
65
66${extension_table('instance', instance_extensions)}
67${extension_table('device', device_extensions)}
68
69struct vk_physical_device;
70
71#ifdef ANDROID_STRICT
72extern const struct vk_instance_extension_table vk_android_allowed_instance_extensions;
73extern const struct vk_device_extension_table vk_android_allowed_device_extensions;
74#endif
75
76#endif /* VK_EXTENSIONS_H */
77""")
78
79_TEMPLATE_C = Template(COPYRIGHT + """
80#include "vulkan/vulkan_core.h"
81
82#include "vk_extensions.h"
83
84const VkExtensionProperties vk_instance_extensions[VK_INSTANCE_EXTENSION_COUNT] = {
85%for ext in instance_extensions:
86   {"${ext.name}", ${ext.ext_version}},
87%endfor
88};
89
90const VkExtensionProperties vk_device_extensions[VK_DEVICE_EXTENSION_COUNT] = {
91%for ext in device_extensions:
92   {"${ext.name}", ${ext.ext_version}},
93%endfor
94};
95
96#ifdef ANDROID_STRICT
97const struct vk_instance_extension_table vk_android_allowed_instance_extensions = {
98%for ext in instance_extensions:
99   .${ext.name[3:]} = ${ext.c_android_condition()},
100%endfor
101};
102
103const struct vk_device_extension_table vk_android_allowed_device_extensions = {
104%for ext in device_extensions:
105   .${ext.name[3:]} = ${ext.c_android_condition()},
106%endfor
107};
108#endif
109""")
110
111def gen_extensions(xml_files, extensions, out_c, out_h):
112    platform_defines = []
113    for filename in xml_files:
114        init_exts_from_xml(filename, extensions, platform_defines)
115
116    for ext in extensions:
117        assert ext.type in {'instance', 'device'}
118
119    template_env = {
120        'instance_extensions': [e for e in extensions if e.type == 'instance'],
121        'device_extensions': [e for e in extensions if e.type == 'device'],
122        'platform_defines': platform_defines,
123    }
124
125    if out_h:
126        with open(out_h, 'w', encoding='utf-8') as f:
127            f.write(_TEMPLATE_H.render(**template_env))
128
129    if out_c:
130        with open(out_c, 'w', encoding='utf-8') as f:
131            f.write(_TEMPLATE_C.render(**template_env))
132
133
134def main():
135    parser = argparse.ArgumentParser()
136    parser.add_argument('--out-c', help='Output C file.')
137    parser.add_argument('--out-h', help='Output H file.')
138    parser.add_argument('--xml',
139                        help='Vulkan API XML file.',
140                        required=True,
141                        action='append',
142                        dest='xml_files')
143    args = parser.parse_args()
144
145    extensions = []
146    for filename in args.xml_files:
147        extensions += get_all_exts_from_xml(filename)
148
149    gen_extensions(args.xml_files, extensions, args.out_c, args.out_h)
150
151if __name__ == '__main__':
152    main()
153