vk/util: Generate defines to help casting structs with vk_find_struct

C++ doesn't like implicit casts from void *.

Signed-off-by: Danylo Piliaiev <dpiliaiev@igalia.com>
Reviewed-by: Jesse Natalie <jenatali@microsoft.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/21931>
This commit is contained in:
Danylo Piliaiev 2023-03-14 14:44:17 +01:00 committed by Marge Bot
parent de5c3900ca
commit 1600b310bc
5 changed files with 144 additions and 6 deletions

View file

@ -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 */

View file

@ -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('.')
)

View file

@ -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 <vulkan/vulkan.h>
#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()

View file

@ -29,6 +29,8 @@
#include <stdlib.h>
#include <string.h>
#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)

View file

@ -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.