• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
28import copy
29import re
30import xml.etree.cElementTree as et
31
32from mako.template import Template
33
34MAX_API_VERSION = '1.0.57'
35
36class Extension:
37    def __init__(self, name, ext_version, enable):
38        self.name = name
39        self.ext_version = int(ext_version)
40        if enable is True:
41            self.enable = 'true';
42        elif enable is False:
43            self.enable = 'false';
44        else:
45            self.enable = enable;
46
47# On Android, we disable all surface and swapchain extensions. Android's Vulkan
48# loader implements VK_KHR_surface and VK_KHR_swapchain, and applications
49# cannot access the driver's implementation. Moreoever, if the driver exposes
50# the those extension strings, then tests dEQP-VK.api.info.instance.extensions
51# and dEQP-VK.api.info.device fail due to the duplicated strings.
52EXTENSIONS = [
53    Extension('VK_ANDROID_native_buffer',                 5, 'ANDROID && device->rad_info.has_syncobj_wait_for_submit'),
54    Extension('VK_KHR_bind_memory2',                      1, True),
55    Extension('VK_KHR_dedicated_allocation',              1, True),
56    Extension('VK_KHR_descriptor_update_template',        1, True),
57    Extension('VK_KHR_external_fence',                    1, 'device->rad_info.has_syncobj_wait_for_submit'),
58    Extension('VK_KHR_external_fence_capabilities',       1, True),
59    Extension('VK_KHR_external_fence_fd',                 1, 'device->rad_info.has_syncobj_wait_for_submit'),
60    Extension('VK_KHR_external_memory',                   1, True),
61    Extension('VK_KHR_external_memory_capabilities',      1, True),
62    Extension('VK_KHR_external_memory_fd',                1, True),
63    Extension('VK_KHR_external_semaphore',                1, 'device->rad_info.has_syncobj'),
64    Extension('VK_KHR_external_semaphore_capabilities',   1, True),
65    Extension('VK_KHR_external_semaphore_fd',             1, 'device->rad_info.has_syncobj'),
66    Extension('VK_KHR_get_memory_requirements2',          1, True),
67    Extension('VK_KHR_get_physical_device_properties2',   1, True),
68    Extension('VK_KHR_get_surface_capabilities2',         1, True),
69    Extension('VK_KHR_image_format_list',                 1, True),
70    Extension('VK_KHR_incremental_present',               1, True),
71    Extension('VK_KHR_maintenance1',                      1, True),
72    Extension('VK_KHR_maintenance2',                      1, True),
73    Extension('VK_KHR_push_descriptor',                   1, True),
74    Extension('VK_KHR_relaxed_block_layout',              1, True),
75    Extension('VK_KHR_sampler_mirror_clamp_to_edge',      1, True),
76    Extension('VK_KHR_shader_draw_parameters',            1, True),
77    Extension('VK_KHR_storage_buffer_storage_class',      1, True),
78    Extension('VK_KHR_surface',                          25, 'RADV_HAS_SURFACE'),
79    Extension('VK_KHR_swapchain',                        68, 'RADV_HAS_SURFACE'),
80    Extension('VK_KHR_variable_pointers',                 1, True),
81    Extension('VK_KHR_wayland_surface',                   6, 'VK_USE_PLATFORM_WAYLAND_KHR'),
82    Extension('VK_KHR_xcb_surface',                       6, 'VK_USE_PLATFORM_XCB_KHR'),
83    Extension('VK_KHR_xlib_surface',                      6, 'VK_USE_PLATFORM_XLIB_KHR'),
84    Extension('VK_KHX_multiview',                         1, False),
85    Extension('VK_EXT_debug_report',                      9, True),
86    Extension('VK_EXT_discard_rectangles',                1, True),
87    Extension('VK_EXT_external_memory_dma_buf',           1, True),
88    Extension('VK_EXT_global_priority',                   1, 'device->rad_info.has_ctx_priority'),
89    Extension('VK_AMD_draw_indirect_count',               1, True),
90    Extension('VK_AMD_rasterization_order',               1, 'device->rad_info.chip_class >= VI && device->rad_info.max_se >= 2'),
91    Extension('VK_AMD_shader_info',                       1, True),
92]
93
94class VkVersion:
95    def __init__(self, string):
96        split = string.split('.')
97        self.major = int(split[0])
98        self.minor = int(split[1])
99        if len(split) > 2:
100            assert len(split) == 3
101            self.patch = int(split[2])
102        else:
103            self.patch = None
104
105        # Sanity check.  The range bits are required by the definition of the
106        # VK_MAKE_VERSION macro
107        assert self.major < 1024 and self.minor < 1024
108        assert self.patch is None or self.patch < 4096
109        assert(str(self) == string)
110
111    def __str__(self):
112        ver_list = [str(self.major), str(self.minor)]
113        if self.patch is not None:
114            ver_list.append(str(self.patch))
115        return '.'.join(ver_list)
116
117    def c_vk_version(self):
118        ver_list = [str(self.major), str(self.minor), str(self.patch)]
119        return 'VK_MAKE_VERSION(' + ', '.join(ver_list) + ')'
120
121    def __int_ver(self):
122        # This is just an expansion of VK_VERSION
123        patch = self.patch if self.patch is not None else 0
124        return (self.major << 22) | (self.minor << 12) | patch
125
126    def __cmp__(self, other):
127        # If only one of them has a patch version, "ignore" it by making
128        # other's patch version match self.
129        if (self.patch is None) != (other.patch is None):
130            other = copy.copy(other)
131            other.patch = self.patch
132
133        return self.__int_ver().__cmp__(other.__int_ver())
134
135MAX_API_VERSION = VkVersion(MAX_API_VERSION)
136
137def _init_exts_from_xml(xml):
138    """ Walk the Vulkan XML and fill out extra extension information. """
139
140    xml = et.parse(xml)
141
142    ext_name_map = {}
143    for ext in EXTENSIONS:
144        ext_name_map[ext.name] = ext
145
146    for ext_elem in xml.findall('.extensions/extension'):
147        ext_name = ext_elem.attrib['name']
148        if ext_name not in ext_name_map:
149            continue
150
151        # Workaround for VK_ANDROID_native_buffer. Its <extension> element in
152        # vk.xml lists it as supported="disabled" and provides only a stub
153        # definition.  Its <extension> element in Mesa's custom
154        # vk_android_native_buffer.xml, though, lists it as
155        # supported='android-vendor' and fully defines the extension. We want
156        # to skip the <extension> element in vk.xml.
157        if ext_elem.attrib['supported'] == 'disabled':
158            assert ext_name == 'VK_ANDROID_native_buffer'
159            continue
160
161        ext = ext_name_map[ext_name]
162        ext.type = ext_elem.attrib['type']
163
164_TEMPLATE = Template(COPYRIGHT + """
165#include "radv_private.h"
166
167#include "vk_util.h"
168
169/* Convert the VK_USE_PLATFORM_* defines to booleans */
170%for platform in ['ANDROID', 'WAYLAND', 'XCB', 'XLIB']:
171#ifdef VK_USE_PLATFORM_${platform}_KHR
172#   undef VK_USE_PLATFORM_${platform}_KHR
173#   define VK_USE_PLATFORM_${platform}_KHR true
174#else
175#   define VK_USE_PLATFORM_${platform}_KHR false
176#endif
177%endfor
178
179/* And ANDROID too */
180#ifdef ANDROID
181#   undef ANDROID
182#   define ANDROID true
183#else
184#   define ANDROID false
185#endif
186
187#define RADV_HAS_SURFACE (VK_USE_PLATFORM_WAYLAND_KHR || \\
188                         VK_USE_PLATFORM_XCB_KHR || \\
189                         VK_USE_PLATFORM_XLIB_KHR)
190
191bool
192radv_instance_extension_supported(const char *name)
193{
194%for ext in instance_extensions:
195    if (strcmp(name, "${ext.name}") == 0)
196        return ${ext.enable};
197%endfor
198    return false;
199}
200
201VkResult radv_EnumerateInstanceExtensionProperties(
202    const char*                                 pLayerName,
203    uint32_t*                                   pPropertyCount,
204    VkExtensionProperties*                      pProperties)
205{
206    VK_OUTARRAY_MAKE(out, pProperties, pPropertyCount);
207
208%for ext in instance_extensions:
209    if (${ext.enable}) {
210        vk_outarray_append(&out, prop) {
211            *prop = (VkExtensionProperties) {
212                .extensionName = "${ext.name}",
213                .specVersion = ${ext.ext_version},
214            };
215        }
216    }
217%endfor
218
219    return vk_outarray_status(&out);
220}
221
222uint32_t
223radv_physical_device_api_version(struct radv_physical_device *dev)
224{
225    return ${MAX_API_VERSION.c_vk_version()};
226}
227
228bool
229radv_physical_device_extension_supported(struct radv_physical_device *device,
230                                        const char *name)
231{
232%for ext in device_extensions:
233    if (strcmp(name, "${ext.name}") == 0)
234        return ${ext.enable};
235%endfor
236    return false;
237}
238
239VkResult radv_EnumerateDeviceExtensionProperties(
240    VkPhysicalDevice                            physicalDevice,
241    const char*                                 pLayerName,
242    uint32_t*                                   pPropertyCount,
243    VkExtensionProperties*                      pProperties)
244{
245    RADV_FROM_HANDLE(radv_physical_device, device, physicalDevice);
246    VK_OUTARRAY_MAKE(out, pProperties, pPropertyCount);
247    (void)device;
248
249%for ext in device_extensions:
250    if (${ext.enable}) {
251        vk_outarray_append(&out, prop) {
252            *prop = (VkExtensionProperties) {
253                .extensionName = "${ext.name}",
254                .specVersion = ${ext.ext_version},
255            };
256        }
257    }
258%endfor
259
260    return vk_outarray_status(&out);
261}
262""")
263
264if __name__ == '__main__':
265    parser = argparse.ArgumentParser()
266    parser.add_argument('--out', help='Output C file.', required=True)
267    parser.add_argument('--xml',
268                        help='Vulkan API XML file.',
269                        required=True,
270                        action='append',
271                        dest='xml_files')
272    args = parser.parse_args()
273
274    for filename in args.xml_files:
275        _init_exts_from_xml(filename)
276
277    for ext in EXTENSIONS:
278        assert ext.type == 'instance' or ext.type == 'device'
279
280    template_env = {
281        'MAX_API_VERSION': MAX_API_VERSION,
282        'instance_extensions': [e for e in EXTENSIONS if e.type == 'instance'],
283        'device_extensions': [e for e in EXTENSIONS if e.type == 'device'],
284    }
285
286    with open(args.out, 'w') as f:
287        f.write(_TEMPLATE.render(**template_env))
288