mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-17 13:58:05 +02:00
This is for fixes the following error:
FAILED: src/vulkan/runtime/vk_synchronization_helpers.c src/vulkan/runtime/vk_synchronization_helpers.h
"C:\CI-Tools\msys64\mingw64\bin/python3.EXE" "../../src/vulkan/util/vk_synchronization_helpers_gen.py" "--xml" "../../src/vulkan/registry/vk.xml" "--out-c" "src/vulkan/runtime/vk_synchronization_helpers.c" "--beta" "false"
Traceback (most recent call last):
File "C:/work/xemu/mesa/src/vulkan/util/vk_synchronization_helpers_gen.py", line 213, in main
f.write(TEMPLATE_C.render(**environment))
UnicodeEncodeError: 'gbk' codec can't encode character '\xa9' in position 15: illegal multibyte sequence
Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>
Acked-by: Eric Engestrom <eric@igalia.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/26515>
245 lines
7.3 KiB
Python
245 lines
7.3 KiB
Python
COPYRIGHT=u"""
|
|
/* Copyright © 2022 Collabora, Ltd.
|
|
*
|
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
* copy of this software and associated documentation files (the "Software"),
|
|
* to deal in the Software without restriction, including without limitation
|
|
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
* and/or sell copies of the Software, and to permit persons to whom the
|
|
* Software is furnished to do so, subject to the following conditions:
|
|
*
|
|
* The above copyright notice and this permission notice (including the next
|
|
* paragraph) shall be included in all copies or substantial portions of the
|
|
* Software.
|
|
*
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
|
* IN THE SOFTWARE.
|
|
*/
|
|
"""
|
|
|
|
import argparse
|
|
import os
|
|
import re
|
|
from collections import namedtuple
|
|
import xml.etree.ElementTree as et
|
|
|
|
from mako.template import Template
|
|
|
|
TEMPLATE_H = Template(COPYRIGHT + """\
|
|
/* This file generated from ${filename}, don't edit directly. */
|
|
|
|
#ifndef VK_FORMAT_INFO_H
|
|
#define VK_FORMAT_INFO_H
|
|
|
|
#include <vulkan/vulkan_core.h>
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
enum vk_format_class {
|
|
MESA_VK_FORMAT_CLASS_UNKNOWN,
|
|
% for name in format_classes:
|
|
${to_enum_name('MESA_VK_FORMAT_CLASS_', name)},
|
|
% endfor
|
|
};
|
|
|
|
struct vk_format_class_info {
|
|
const VkFormat *formats;
|
|
uint32_t format_count;
|
|
};
|
|
|
|
const struct vk_format_class_info *
|
|
vk_format_class_get_info(enum vk_format_class class);
|
|
|
|
const struct vk_format_class_info *
|
|
vk_format_get_class_info(VkFormat format);
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif
|
|
""")
|
|
|
|
TEMPLATE_C = Template(COPYRIGHT + """
|
|
/* This file generated from ${filename}, don't edit directly. */
|
|
|
|
#include "${header}"
|
|
|
|
#include "util/macros.h"
|
|
|
|
#include "vk_format.h"
|
|
|
|
struct vk_format_info {
|
|
enum vk_format_class class;
|
|
};
|
|
|
|
% for id, ext in extensions.items():
|
|
static const struct vk_format_info ext${id}_format_infos[] = {
|
|
% for name, format in ext.formats.items():
|
|
[${format.offset}] = {
|
|
.class = ${to_enum_name('MESA_VK_FORMAT_CLASS_', format.cls)},
|
|
},
|
|
% endfor
|
|
};
|
|
|
|
% endfor
|
|
static const struct vk_format_info *
|
|
vk_format_get_info(VkFormat format)
|
|
{
|
|
uint32_t extnumber =
|
|
format < 1000000000 ? 0 : (((format % 1000000000) / 1000) + 1);
|
|
uint32_t offset = format % 1000;
|
|
|
|
switch (extnumber) {
|
|
% for id, ext in extensions.items():
|
|
case ${id}:
|
|
assert(offset < ARRAY_SIZE(ext${id}_format_infos));
|
|
return &ext${id}_format_infos[offset];
|
|
% endfor
|
|
default:
|
|
unreachable("Invalid extension");
|
|
}
|
|
}
|
|
|
|
% for clsname, cls in format_classes.items():
|
|
% if len(cls.formats) > 0:
|
|
static const VkFormat ${to_enum_name('MESA_VK_FORMAT_CLASS_', clsname).lower() + '_formats'}[] = {
|
|
% for fname in cls.formats:
|
|
${fname},
|
|
% endfor
|
|
% endif
|
|
};
|
|
|
|
% endfor
|
|
static const struct vk_format_class_info class_infos[] = {
|
|
% for clsname, cls in format_classes.items():
|
|
[${to_enum_name('MESA_VK_FORMAT_CLASS_', clsname)}] = {
|
|
% if len(cls.formats) > 0:
|
|
.formats = ${to_enum_name('MESA_VK_FORMAT_CLASS_', clsname).lower() + '_formats'},
|
|
.format_count = ARRAY_SIZE(${to_enum_name('MESA_VK_FORMAT_CLASS_', clsname).lower() + '_formats'}),
|
|
% else:
|
|
0
|
|
% endif
|
|
},
|
|
% endfor
|
|
};
|
|
|
|
const struct vk_format_class_info *
|
|
vk_format_class_get_info(enum vk_format_class class)
|
|
{
|
|
assert(class < ARRAY_SIZE(class_infos));
|
|
return &class_infos[class];
|
|
}
|
|
|
|
const struct vk_format_class_info *
|
|
vk_format_get_class_info(VkFormat format)
|
|
{
|
|
const struct vk_format_info *format_info = vk_format_get_info(format);
|
|
return &class_infos[format_info->class];
|
|
}
|
|
""")
|
|
|
|
def to_enum_name(prefix, name):
|
|
return "%s" % prefix + re.sub('([^A-Za-z0-9_])', '_', name).upper()
|
|
|
|
Format = namedtuple('Format', ['name', 'cls', 'ext', 'offset'])
|
|
FormatClass = namedtuple('FormatClass', ['name', 'formats'])
|
|
Extension = namedtuple('Extension', ['id', 'formats'])
|
|
|
|
def get_formats(doc):
|
|
"""Extract the formats from the registry."""
|
|
formats = {}
|
|
|
|
for fmt in doc.findall('./formats/format'):
|
|
xpath = './/enum[@name="{}"]'.format(fmt.attrib['name'])
|
|
enum = doc.find(xpath)
|
|
ext = None
|
|
if 'extends' in enum.attrib:
|
|
assert(enum.attrib['extends'] == 'VkFormat')
|
|
if 'extnumber' in enum.attrib:
|
|
ext = int(enum.attrib['extnumber'])
|
|
else:
|
|
xpath = xpath + '/..'
|
|
parent = doc.find(xpath)
|
|
while parent != None and ext == None:
|
|
if parent.tag == 'extension':
|
|
assert('number' in parent.attrib)
|
|
ext = parent.attrib['number']
|
|
xpath = xpath + '/..'
|
|
parent = doc.find(xpath)
|
|
offset = int(enum.attrib['offset'])
|
|
else:
|
|
ext = 0
|
|
offset = int(enum.attrib['value'])
|
|
|
|
assert(ext != None)
|
|
format = Format(fmt.attrib['name'], fmt.attrib['class'], ext, offset)
|
|
formats[format.name] = format
|
|
|
|
return formats
|
|
|
|
def get_formats_from_xml(xml_files):
|
|
formats = {}
|
|
|
|
for filename in xml_files:
|
|
doc = et.parse(filename)
|
|
formats.update(get_formats(doc))
|
|
|
|
return formats
|
|
|
|
def main():
|
|
parser = argparse.ArgumentParser()
|
|
parser.add_argument('--out-c', required=True, help='Output C file.')
|
|
parser.add_argument('--out-h', required=True, help='Output H file.')
|
|
parser.add_argument('--xml',
|
|
help='Vulkan API XML file.',
|
|
required=True, action='append', dest='xml_files')
|
|
args = parser.parse_args()
|
|
|
|
formats = get_formats_from_xml(args.xml_files)
|
|
classes = {}
|
|
extensions = {}
|
|
for n, f in formats.items():
|
|
if f.cls not in classes:
|
|
classes[f.cls] = FormatClass(f.cls, {})
|
|
classes[f.cls].formats[f.name] = f
|
|
if f.ext not in extensions:
|
|
extensions[f.ext] = Extension(f.cls, {})
|
|
extensions[f.ext].formats[f.name] = f
|
|
|
|
assert os.path.dirname(args.out_c) == os.path.dirname(args.out_h)
|
|
|
|
environment = {
|
|
'header': os.path.basename(args.out_h),
|
|
'formats': formats,
|
|
'format_classes': classes,
|
|
'extensions': extensions,
|
|
'filename': os.path.basename(__file__),
|
|
'to_enum_name': to_enum_name,
|
|
}
|
|
|
|
try:
|
|
with open(args.out_h, 'w', encoding='utf-8') as f:
|
|
guard = os.path.basename(args.out_h).replace('.', '_').upper()
|
|
f.write(TEMPLATE_H.render(guard=guard, **environment))
|
|
with open(args.out_c, 'w', encoding='utf-8') as f:
|
|
f.write(TEMPLATE_C.render(**environment))
|
|
except Exception:
|
|
# In the event there's an error, this imports some helpers from mako
|
|
# to print a useful stack trace and prints it, then exits with
|
|
# status 1, if python is run with debug; otherwise it just raises
|
|
# the exception
|
|
import sys
|
|
from mako import exceptions
|
|
print(exceptions.text_error_template().render(), file=sys.stderr)
|
|
sys.exit(1)
|
|
|
|
if __name__ == '__main__':
|
|
main()
|