[PATCH 0/5] MR9931: winevulkan: Cleanups and simplifications for make_vulkan.
From: Rémi Bernon <rbernon@codeweavers.com> --- dlls/winevulkan/make_vulkan | 114 ++++++++++++++---------------------- include/wine/vulkan.h | 18 +++--- 2 files changed, 54 insertions(+), 78 deletions(-) diff --git a/dlls/winevulkan/make_vulkan b/dlls/winevulkan/make_vulkan index 0a8b324e508..e2e7fa35e0b 100755 --- a/dlls/winevulkan/make_vulkan +++ b/dlls/winevulkan/make_vulkan @@ -417,6 +417,7 @@ class VkBaseType(object): requires (:obj:'str', optional): Other types required. Often bitmask values pull in a *FlagBits type. """ + self.extensions = set() self.name = name self.type = _type self.alias = alias @@ -435,6 +436,17 @@ class VkBaseType(object): return bool(self.alias) +class Extension(object): + def __init__(self, name, type=None, platform=None, **kwargs): + self.name = name + self.type = type + + self.is_supported = name not in UNSUPPORTED_EXTENSIONS + self.is_exposed = platform not in UNEXPOSED_PLATFORMS and \ + name not in UNEXPOSED_EXTENSIONS + self.is_core = name in CORE_EXTENSIONS + + class VkConstant(object): def __init__(self, name, value): self.name = name @@ -447,6 +459,7 @@ class VkConstant(object): class VkDefine(object): def __init__(self, value): + self.extensions = set() self.value = value @staticmethod @@ -567,6 +580,7 @@ class EnumValue(object): class VkFunction(object): def __init__(self, _type, name, params, alias=None): self.extensions = set() + self.platforms = set() self.name = name self.type = _type self.params = params @@ -605,15 +619,7 @@ class VkFunction(object): return bool(self.alias) def is_core_func(self): - """ Returns whether the function is a Vulkan core function. - Core functions are APIs defined by the Vulkan spec to be part of the - Core API as well as several KHR WSI extensions. - """ - - if not self.extensions: - return True - - return any(ext in self.extensions for ext in CORE_EXTENSIONS) + return not self.extensions or any(ext.is_core for ext in self.extensions) def is_device_func(self): # If none of the other, it must be a device function @@ -660,7 +666,7 @@ class VkFunction(object): def needs_exposing(self): # The function needs exposed if at-least one extension isn't both UNSUPPORTED and UNEXPOSED - return self.is_required() and (not self.extensions or not self.extensions.issubset(UNEXPOSED_EXTENSIONS)) + return self.is_required() and (not self.extensions or any(ext.is_exposed for ext in self.extensions)) def is_perf_critical(self): # vkCmd* functions are frequently called, do not trace for performance @@ -937,6 +943,7 @@ class VkFunction(object): class VkFunctionPointer(object): def __init__(self, value): + self.extensions = set() self.value = value self.required = False @@ -958,6 +965,7 @@ class VkFunctionPointer(object): class VkHandle(object): def __init__(self, name, _type, parent, alias=None): + self.extensions = set() self.name = name self.type = _type self.parent = parent @@ -1816,6 +1824,7 @@ class VkStruct(Sequence): def __init__(self, registry, name, members, returnedonly, structextends, alias=None, union=False): self.registry = registry + self.extensions = set() self.name = name self.members = members self.returnedonly = returnedonly @@ -1824,7 +1833,7 @@ class VkStruct(Sequence): self.alias = alias self.union = union self.type_info = None # To be set later. - self._extensions = None + self._struct_extensions = None self.aliased_by = [] self.order = 0 @@ -1888,25 +1897,21 @@ class VkStruct(Sequence): structs[member.type].alias.set_order(self.order, structs) structs[member.type].set_order(self.order, structs) - @property - def extension(self): - return self.registry.types[self.name]["extension"] - @property def struct_extensions(self): - if self._extensions is None: - self._extensions = [] + if self._struct_extensions is None: + self._struct_extensions = [] - def is_struct_extension(s): - if s.extension in UNEXPOSED_EXTENSIONS: - return False - return not s.alias and self.name in s.structextends + def is_struct_extension(struct): + if not struct.extensions or any(ext.is_exposed for ext in struct.extensions): + return not struct.alias and self.name in struct.structextends + return False structs = sorted(self.registry.structs, key=lambda s: s.name) for struct in filter(is_struct_extension, structs): - self._extensions.append(struct) + self._struct_extensions.append(struct) - return self._extensions + return self._struct_extensions def definition(self, align=False, conv=False): """ Convert structure to textual definition. @@ -2872,16 +2877,14 @@ class VkGenerator(object): f.write("#define ALL_VK_CLIENT_DEVICE_EXTS") for ext in self.registry.extensions: - type, name = ext["type"], ext["name"] - if type == "device" and name not in UNEXPOSED_EXTENSIONS: - f.write(f" \\\n USE_VK_EXT({name})") + if ext.type == "device" and ext.is_exposed: + f.write(f" \\\n USE_VK_EXT({ext.name})") f.write("\n\n") f.write("#define ALL_VK_DEVICE_EXTS ALL_VK_CLIENT_DEVICE_EXTS") for ext in self.registry.extensions: - type, name = ext["type"], ext["name"] - if type == "device" and name in UNEXPOSED_EXTENSIONS: - f.write(f" \\\n USE_VK_EXT({name})") + if ext.type == "device" and not ext.is_exposed: + f.write(f" \\\n USE_VK_EXT({ext.name})") f.write("\n\n") f.write("#define ALL_VK_INSTANCE_FUNCS") @@ -2895,16 +2898,14 @@ class VkGenerator(object): f.write("#define ALL_VK_CLIENT_INSTANCE_EXTS") for ext in self.registry.extensions: - type, name = ext["type"], ext["name"] - if type == "instance" and name not in UNEXPOSED_EXTENSIONS: - f.write(f" \\\n USE_VK_EXT({name})") + if ext.type == "instance" and ext.is_exposed: + f.write(f" \\\n USE_VK_EXT({ext.name})") f.write("\n\n") f.write("#define ALL_VK_INSTANCE_EXTS ALL_VK_CLIENT_INSTANCE_EXTS") for ext in self.registry.extensions: - type, name = ext["type"], ext["name"] - if type == "instance" and name in UNEXPOSED_EXTENSIONS: - f.write(f" \\\n USE_VK_EXT({name})") + if ext.type == "instance" and not ext.is_exposed: + f.write(f" \\\n USE_VK_EXT({ext.name})") f.write("\n\n") f.write("#endif /* __WINE_VULKAN_H */\n") @@ -3240,30 +3241,16 @@ class VkRegistry(object): extensions = [] - deferred_exts = [] - def process_ext(ext, deferred=False): - ext_name = ext.attrib["name"] + def process_ext(ext): + extension = Extension(**ext.attrib) # Set extension name on any functions calls part of this extension as we # were not aware of the name during initial parsing. - commands = ext.findall("require/command") - for command in commands: - cmd_name = command.attrib["name"] - # Need to verify that the command is defined, and otherwise skip it. - # vkCreateScreenSurfaceQNX is declared in <extensions> but not defined in - # <commands>. A command without a definition cannot be enabled, so it's valid for - # the XML file to handle this, but because of the manner in which we parse the XML - # file we pre-populate from <commands> before we check if a command is enabled. - if cmd_name in self.funcs: - self.funcs[cmd_name].extensions.add(ext_name) - - if ext_name in UNSUPPORTED_EXTENSIONS: - return + for command in ext.findall("require/command"): + self.funcs[command.attrib["name"]].extensions.add(extension) - # Defer extensions with 'sortorder' as they are order-dependent for spec-parsing. - if not deferred and "sortorder" in ext.attrib: - deferred_exts.append(ext) + if not extension.is_supported: return # Extensions can define EnumValues which alias to provisional extensions. Pre-process @@ -3273,7 +3260,7 @@ class VkRegistry(object): for enum_elem in require.findall("enum"): self._process_require_enum(enum_elem, ext, only_aliased=True) - LOGGER.debug("Loading extension: {0}".format(ext_name)) + LOGGER.debug("Loading extension: {0}".format(extension.name)) # Extensions can define one or more require sections each requiring # different features (e.g. Vulkan 1.1). Parse each require section @@ -3291,7 +3278,7 @@ class VkRegistry(object): # Therefore just skip any types that aren't found. if t.attrib["name"] in self.types: type_info = self.types[t.attrib["name"]] - type_info["extension"] = ext_name + type_info["data"].extensions.add(extension) self._require_type(type_info["data"]) # Pull in any commands we need. We infer types to pull in from the command @@ -3312,22 +3299,13 @@ class VkRegistry(object): # don't want to add the extension as a real extension here. # Checking for the existence of "type" seems to achieve this. if "type" in ext.attrib: - ext_info = {"name" : ext_name, "type" : ext.attrib["type"]} - extensions.append(ext_info) - + extensions.append(extension) - # Process extensions, allowing for sortorder to defer extension processing for ext in exts.values(): process_ext(ext) - deferred_exts.sort(key=lambda ext: ext.attrib["sortorder"]) - - # Respect sortorder - for ext in deferred_exts: - process_ext(ext, deferred=True) - # Sort in alphabetical order. - self.extensions = sorted(extensions, key=lambda ext: ext["name"]) + self.extensions = sorted(extensions, key=lambda ext: ext.name) def _parse_features(self, root): """ Parse the feature section, which describes Core commands and types needed. """ @@ -3369,7 +3347,6 @@ class VkRegistry(object): type_info = {} type_info["category"] = t.attrib.get("category", None) type_info["requires"] = t.attrib.get("requires", None) - type_info["extension"] = None # We parse aliases in a second pass when we know more. alias = t.attrib.get("alias") @@ -3465,7 +3442,6 @@ class VkRegistry(object): type_info = {} type_info["category"] = t.attrib.get("category") type_info["name"] = t.attrib.get("name") - type_info["extension"] = None alias = t.attrib.get("alias") diff --git a/include/wine/vulkan.h b/include/wine/vulkan.h index 63b6ce54d58..9842d035c1f 100644 --- a/include/wine/vulkan.h +++ b/include/wine/vulkan.h @@ -287,6 +287,12 @@ typedef struct _XDisplay Display; #define VK_EXT_BLEND_OPERATION_ADVANCED_EXTENSION_NAME "VK_EXT_blend_operation_advanced" #define VK_NV_FRAGMENT_COVERAGE_TO_COLOR_SPEC_VERSION 1 #define VK_NV_FRAGMENT_COVERAGE_TO_COLOR_EXTENSION_NAME "VK_NV_fragment_coverage_to_color" +#define VK_KHR_ACCELERATION_STRUCTURE_SPEC_VERSION 13 +#define VK_KHR_ACCELERATION_STRUCTURE_EXTENSION_NAME "VK_KHR_acceleration_structure" +#define VK_KHR_RAY_TRACING_PIPELINE_SPEC_VERSION 1 +#define VK_KHR_RAY_TRACING_PIPELINE_EXTENSION_NAME "VK_KHR_ray_tracing_pipeline" +#define VK_KHR_RAY_QUERY_SPEC_VERSION 1 +#define VK_KHR_RAY_QUERY_EXTENSION_NAME "VK_KHR_ray_query" #define VK_NV_FRAMEBUFFER_MIXED_SAMPLES_SPEC_VERSION 1 #define VK_NV_FRAMEBUFFER_MIXED_SAMPLES_EXTENSION_NAME "VK_NV_framebuffer_mixed_samples" #define VK_NV_FILL_RECTANGLE_SPEC_VERSION 1 @@ -537,6 +543,8 @@ typedef struct _XDisplay Display; #define VK_NV_FRAGMENT_SHADING_RATE_ENUMS_EXTENSION_NAME "VK_NV_fragment_shading_rate_enums" #define VK_NV_RAY_TRACING_MOTION_BLUR_SPEC_VERSION 1 #define VK_NV_RAY_TRACING_MOTION_BLUR_EXTENSION_NAME "VK_NV_ray_tracing_motion_blur" +#define VK_EXT_MESH_SHADER_SPEC_VERSION 1 +#define VK_EXT_MESH_SHADER_EXTENSION_NAME "VK_EXT_mesh_shader" #define VK_EXT_YCBCR_2PLANE_444_FORMATS_SPEC_VERSION 1 #define VK_EXT_YCBCR_2PLANE_444_FORMATS_EXTENSION_NAME "VK_EXT_ycbcr_2plane_444_formats" #define VK_EXT_FRAGMENT_DENSITY_MAP_2_SPEC_VERSION 1 @@ -926,14 +934,6 @@ typedef struct _XDisplay Display; #define VK_STD_VULKAN_VIDEO_CODEC_AV1_DECODE_EXTENSION_NAME "VK_STD_vulkan_video_codec_av1_decode" #define VK_STD_VULKAN_VIDEO_CODEC_AV1_ENCODE_SPEC_VERSION VK_STD_VULKAN_VIDEO_CODEC_AV1_ENCODE_API_VERSION_1_0_0 #define VK_STD_VULKAN_VIDEO_CODEC_AV1_ENCODE_EXTENSION_NAME "VK_STD_vulkan_video_codec_av1_encode" -#define VK_KHR_ACCELERATION_STRUCTURE_SPEC_VERSION 13 -#define VK_KHR_ACCELERATION_STRUCTURE_EXTENSION_NAME "VK_KHR_acceleration_structure" -#define VK_KHR_RAY_TRACING_PIPELINE_SPEC_VERSION 1 -#define VK_KHR_RAY_TRACING_PIPELINE_EXTENSION_NAME "VK_KHR_ray_tracing_pipeline" -#define VK_KHR_RAY_QUERY_SPEC_VERSION 1 -#define VK_KHR_RAY_QUERY_EXTENSION_NAME "VK_KHR_ray_query" -#define VK_EXT_MESH_SHADER_SPEC_VERSION 1 -#define VK_EXT_MESH_SHADER_EXTENSION_NAME "VK_EXT_mesh_shader" #define VK_MAKE_VERSION(major, minor, patch) \ ((((uint32_t)(major)) << 22U) | (((uint32_t)(minor)) << 12U) | ((uint32_t)(patch))) @@ -4537,8 +4537,8 @@ static const VkPipelineCreateFlagBits2 VK_PIPELINE_CREATE_2_EARLY_RETURN_ON_FAIL static const VkPipelineCreateFlagBits2 VK_PIPELINE_CREATE_2_EARLY_RETURN_ON_FAILURE_BIT_KHR = 0x00000200ull; static const VkPipelineCreateFlagBits2 VK_PIPELINE_CREATE_2_LINK_TIME_OPTIMIZATION_BIT_EXT = 0x00000400ull; static const VkPipelineCreateFlagBits2 VK_PIPELINE_CREATE_2_LIBRARY_BIT_KHR = 0x00000800ull; -static const VkPipelineCreateFlagBits2 VK_PIPELINE_CREATE_2_RAY_TRACING_SKIP_TRIANGLES_BIT_KHR = 0x00001000ull; static const VkPipelineCreateFlagBits2 VK_PIPELINE_CREATE_2_RAY_TRACING_SKIP_BUILT_IN_PRIMITIVES_BIT_KHR = 0x00001000ull; +static const VkPipelineCreateFlagBits2 VK_PIPELINE_CREATE_2_RAY_TRACING_SKIP_TRIANGLES_BIT_KHR = 0x00001000ull; static const VkPipelineCreateFlagBits2 VK_PIPELINE_CREATE_2_RAY_TRACING_SKIP_AABBS_BIT_KHR = 0x00002000ull; static const VkPipelineCreateFlagBits2 VK_PIPELINE_CREATE_2_RAY_TRACING_NO_NULL_ANY_HIT_SHADERS_BIT_KHR = 0x00004000ull; static const VkPipelineCreateFlagBits2 VK_PIPELINE_CREATE_2_RAY_TRACING_NO_NULL_CLOSEST_HIT_SHADERS_BIT_KHR = 0x00008000ull; -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/9931
From: Rémi Bernon <rbernon@codeweavers.com> --- dlls/winevulkan/make_vulkan | 265 +++++++++++++++++------------------- 1 file changed, 128 insertions(+), 137 deletions(-) diff --git a/dlls/winevulkan/make_vulkan b/dlls/winevulkan/make_vulkan index e2e7fa35e0b..5e6f0ff8a80 100755 --- a/dlls/winevulkan/make_vulkan +++ b/dlls/winevulkan/make_vulkan @@ -344,6 +344,19 @@ MEMBER_LENGTH_EXPRESSIONS = { "{prefix}descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC ? {length} : 0", } + +class Context(object): + base_types = [] + bitmasks = [] + consts = [] + defines = [] + enums = [] + func_ptrs = [] + handles = [] + structs = [] + funcs = [] + + class Direction(Enum): """ Parameter direction: input, output, input_output. """ INPUT = 1 @@ -463,7 +476,7 @@ class VkDefine(object): self.value = value @staticmethod - def from_xml(registry, define): + def from_xml(define): value = innertext(define) value = re.sub(r'\s*//.*$', '', value, flags=re.M) value = value.strip() @@ -601,18 +614,18 @@ class VkFunction(object): self.unwrap = Unwrap.HOST @staticmethod - def from_alias(registry, command, alias): + def from_alias(command, alias): func_name = command.attrib.get("name") return VkFunction(alias.type, func_name, alias.params, alias=alias) @staticmethod - def from_xml(registry, command, types): + def from_xml(command, types): proto = command.find("proto") func_name = proto.find("name").text func_type = proto.find("type").text params = filter(is_api_supported, command.findall("param")) - params = [VkParam.from_xml(registry, param, types) for param in params] + params = [VkParam.from_xml(param, types) for param in params] return VkFunction(func_type, func_name, params) def is_alias(self): @@ -948,7 +961,7 @@ class VkFunctionPointer(object): self.required = False @staticmethod - def from_xml(registry, funcpointer): + def from_xml(funcpointer): value = innertext(funcpointer).replace('\n', '') value = re.sub(r'\s*//.*$', '', value, flags=re.M) value = re.sub(r'\s+', ' ', value, flags=re.M) @@ -974,12 +987,12 @@ class VkHandle(object): self.object_type = None @staticmethod - def from_alias(registry, handle, alias): + def from_alias(handle, alias): name = handle.attrib.get("name") return VkHandle(name, alias.type, alias.parent, alias=alias) @staticmethod - def from_xml(registry, handle): + def from_xml(handle): name = handle.find("name").text _type = handle.find("type").text parent = handle.attrib.get("parent") # Most objects have a parent e.g. VkQueue has VkDevice. @@ -1265,7 +1278,7 @@ class VkMember(VkVariable): self.name, self.array_lens, self.dyn_array_len) @staticmethod - def from_xml(registry, member, returnedonly): + def from_xml(member, returnedonly): """ Helper function for parsing a member tag within a struct or union. """ name_elem = member.find("name") type_elem = member.find("type") @@ -1515,7 +1528,7 @@ class VkParam(VkVariable): return "{0} {1} {2} {3} {4} {5}".format(self.const, self.type, self.pointer, self.name, self.array_lens, self.dyn_array_len) @staticmethod - def from_xml(registry, param, types): + def from_xml(param, types): # Parameter parsing is slightly tricky. All the data is contained within # a param tag, but some data is within subtags while others are text # before or after the type tag. @@ -1822,8 +1835,7 @@ class VkParam(VkVariable): class VkStruct(Sequence): """ Class which represents the type union and struct. """ - def __init__(self, registry, name, members, returnedonly, structextends, alias=None, union=False): - self.registry = registry + def __init__(self, name, members, returnedonly, structextends, alias=None, union=False): self.extensions = set() self.name = name self.members = members @@ -1848,15 +1860,15 @@ class VkStruct(Sequence): return len(self.members) @staticmethod - def from_alias(registry, struct, alias): + def from_alias(struct, alias): name = struct.attrib.get("name") - aliasee = VkStruct(registry, name, alias.members, alias.returnedonly, alias.structextends, alias=alias) + aliasee = VkStruct(name, alias.members, alias.returnedonly, alias.structextends, alias=alias) alias.add_aliased_by(aliasee) return aliasee @staticmethod - def from_xml(registry, struct): + def from_xml(struct): # Unions and structs are the same parsing wise, but we need to # know which one we are dealing with later on for code generation. union = True if struct.attrib["category"] == "union" else False @@ -1880,8 +1892,8 @@ class VkStruct(Sequence): structextends = structextends.split(",") if structextends else [] members = filter(is_api_supported, struct.findall("member")) - members = [VkMember.from_xml(registry, member, returnedonly) for member in members] - return VkStruct(registry, name, members, returnedonly, structextends, union=union) + members = [VkMember.from_xml(member, returnedonly) for member in members] + return VkStruct(name, members, returnedonly, structextends, union=union) def set_order(self, order, structs): if order < self.order: @@ -1907,7 +1919,7 @@ class VkStruct(Sequence): return not struct.alias and self.name in struct.structextends return False - structs = sorted(self.registry.structs, key=lambda s: s.name) + structs = sorted(Context.structs, key=lambda s: s.name) for struct in filter(is_struct_extension, structs): self._struct_extensions.append(struct) @@ -2464,23 +2476,53 @@ class ArrayConversionFunction(object): return body -class VkGenerator(object): - def __init__(self, registry): - self.registry = registry +class Generator(object): + def __init__(self, vk_xml, video_xml): + # We aggregate all types in here for cross-referencing. + self.types = {} + self.surface_extensions = [] - # Build a list conversion functions for struct conversion. - self.conversions = [] - self.win32_structs = [] + # Overall strategy for parsing the registry is to first + # parse all type / function definitions. Then parse + # features and extensions to decide which types / functions + # to actually 'pull in' for code generation. For each type or + # function call we want we set a member 'required' to True. + tree = ET.parse(vk_xml) + root = tree.getroot() + # The video XML currently only has enums, types, and part of the + # extension data in it. + # All of the relevant extensions and commands are in vk.xml. + video_tree = ET.parse(video_xml) + video_root = video_tree.getroot() + + self.copyright = root.find('./comment').text + self.video_copyright = video_root.find('./comment').text + + root.extend(video_root) + root.extend(ET.parse("winevk.xml").getroot()) + + self._parse_enums(root) + self._parse_types(root) + self._parse_commands(root) + + # Pull in any required types and functions. + self._parse_features(root) + self._parse_extensions(root) + + for enum in Context.enums.values(): + enum.fixup_64bit_aliases() + + self._match_object_types() def _generate_copyright(self, f, spec_file=False): f.write("# " if spec_file else "/* ") f.write("Automatically generated from Vulkan vk.xml and video.xml; DO NOT EDIT!\n") lines = ["", "This file is generated from Vulkan vk.xml file covered", "by the following copyright and permission notice:"] - lines.extend([l.rstrip(" ") for l in self.registry.copyright.splitlines()]) + lines.extend([l.rstrip(" ") for l in self.copyright.splitlines()]) lines.extend(["and from Vulkan video.xml file covered", "by the following copyright and permission notice:"]) - lines.extend([l.rstrip(" ") for l in self.registry.video_copyright.splitlines()]) + lines.extend([l.rstrip(" ") for l in self.video_copyright.splitlines()]) for line in lines: f.write("{0}{1}".format("# " if spec_file else " * ", line).rstrip(" ") + "\n") f.write("\n" if spec_file else " */\n\n") @@ -2504,7 +2546,7 @@ class VkGenerator(object): # Global functions don't go through the thunks. thunks = "" conversions = [] - for vk_func in self.registry.funcs.values(): + for vk_func in Context.funcs.values(): if not vk_func.needs_exposing(): continue if vk_func.name in MANUAL_LOADER_FUNCTIONS: @@ -2544,7 +2586,7 @@ class VkGenerator(object): f.write("{\n") f.write(" switch(type)\n") f.write(" {\n") - for handle in self.registry.handles: + for handle in Context.handles: if not handle.is_required() or not handle.is_wrapped() or handle.is_alias(): continue f.write(" case {}:\n".format(handle.object_type)) @@ -2566,7 +2608,7 @@ class VkGenerator(object): f.write("BOOL wine_vk_is_type_wrapped(VkObjectType type)\n") f.write("{\n") f.write(" return FALSE") - for handle in self.registry.handles: + for handle in Context.handles: if not handle.is_required() or not handle.is_wrapped() or handle.is_alias(): continue f.write(" ||\n type == {}".format(handle.object_type)) @@ -2581,7 +2623,7 @@ class VkGenerator(object): f.write(" init_vulkan,\n") f.write(" vk_is_available_instance_function,\n") f.write(" vk_is_available_device_function,\n") - for vk_func in self.registry.funcs.values(): + for vk_func in Context.funcs.values(): if not vk_func.needs_exposing(): continue if vk_func.name in MANUAL_LOADER_FUNCTIONS: @@ -2605,7 +2647,7 @@ class VkGenerator(object): f.write(" wow64_init_vulkan,\n") f.write(" vk_is_available_instance_function32,\n") f.write(" vk_is_available_device_function32,\n") - for vk_func in self.registry.funcs.values(): + for vk_func in Context.funcs.values(): if not vk_func.needs_exposing(): continue if vk_func.name in MANUAL_LOADER_FUNCTIONS: @@ -2629,7 +2671,7 @@ class VkGenerator(object): # Generate prototypes for device and instance functions requiring a custom implementation. f.write("/* Functions for which we have custom implementations outside of the thunks. */\n") - for vk_func in self.registry.funcs.values(): + for vk_func in Context.funcs.values(): if not vk_func.needs_private_thunk(): continue @@ -2645,7 +2687,7 @@ class VkGenerator(object): f.write("WINE_DEFAULT_DEBUG_CHANNEL(vulkan);\n\n") - for vk_func in self.registry.funcs.values(): + for vk_func in Context.funcs.values(): if not vk_func.needs_exposing(): continue if vk_func.name in MANUAL_LOADER_THUNKS | MANUAL_LOADER_FUNCTIONS: @@ -2654,7 +2696,7 @@ class VkGenerator(object): f.write(vk_func.loader_thunk()) f.write("static const struct vulkan_func vk_device_dispatch_table[] =\n{\n") - for vk_func in self.registry.device_funcs: + for vk_func in self.device_funcs: if not vk_func.needs_exposing(): continue @@ -2662,7 +2704,7 @@ class VkGenerator(object): f.write("};\n\n") f.write("static const struct vulkan_func vk_phys_dev_dispatch_table[] =\n{\n") - for vk_func in self.registry.phys_dev_funcs: + for vk_func in self.phys_dev_funcs: if not vk_func.needs_exposing(): continue @@ -2670,7 +2712,7 @@ class VkGenerator(object): f.write("};\n\n") f.write("static const struct vulkan_func vk_instance_dispatch_table[] =\n{\n") - for vk_func in self.registry.instance_funcs: + for vk_func in self.instance_funcs: if not vk_func.needs_exposing(): continue @@ -2730,7 +2772,7 @@ class VkGenerator(object): f.write(" unix_init,\n") f.write(" unix_is_available_instance_function,\n") f.write(" unix_is_available_device_function,\n") - for vk_func in self.registry.funcs.values(): + for vk_func in Context.funcs.values(): if not vk_func.needs_exposing(): continue if vk_func.name in MANUAL_LOADER_FUNCTIONS: @@ -2740,7 +2782,7 @@ class VkGenerator(object): f.write(" unix_count,\n") f.write("};\n\n") - for vk_func in self.registry.funcs.values(): + for vk_func in Context.funcs.values(): if not vk_func.needs_exposing(): continue if vk_func.name in MANUAL_LOADER_FUNCTIONS: @@ -2792,17 +2834,17 @@ class VkGenerator(object): # The overall strategy is to define independent constants and datatypes, # prior to complex structures and function calls to avoid forward declarations. - for const in self.registry.consts: + for const in Context.consts: # For now just generate things we may not need. The amount of parsing needed # to get some of the info is tricky as you need to figure out which structure # references a certain constant. f.write(const.definition()) f.write("\n") - for define in self.registry.defines: + for define in Context.defines: f.write(define.definition()) - for handle in self.registry.handles: + for handle in Context.handles: # For backward compatibility also create definitions for aliases. # These types normally don't get pulled in as we use the new types # even in legacy functions if they are aliases. @@ -2810,12 +2852,12 @@ class VkGenerator(object): f.write(handle.definition()) f.write("\n") - for base_type in self.registry.base_types: + for base_type in Context.base_types: f.write(base_type.definition()) f.write("\n") # Reorder bitmasks to handle aliases correctly. - remaining_bitmasks = list(self.registry.bitmasks) + remaining_bitmasks = list(Context.bitmasks) while len(remaining_bitmasks) > 0: for bitmask in remaining_bitmasks: if bitmask.is_alias() and bitmask.alias in remaining_bitmasks: @@ -2826,13 +2868,13 @@ class VkGenerator(object): f.write("\n") # Define enums, this includes values for some of the bitmask types as well. - for enum in self.registry.enums.values(): + for enum in Context.enums.values(): if enum.required: f.write(enum.definition()) f.write("typedef struct VkDebugUtilsMessengerCallbackDataEXT VkDebugUtilsMessengerCallbackDataEXT;\n") - for fp in self.registry.funcpointers: + for fp in Context.func_ptrs: if fp.required: f.write(fp.definition()) f.write("\n") @@ -2842,13 +2884,13 @@ class VkGenerator(object): # decoupled structs. # Note: unions are stored in structs for dependency reasons, # see comment in parsing section. - for struct in self.registry.structs: + for struct in Context.structs: if struct.required and struct.name != "SECURITY_ATTRIBUTES": LOGGER.debug("Generating struct: {0}".format(struct.name)) f.write(struct.definition(align=True)) f.write("\n") - for func in self.registry.funcs.values(): + for func in Context.funcs.values(): if not func.is_required(): LOGGER.debug("Skipping PFN definition for: {0}".format(func.name)) continue @@ -2857,7 +2899,7 @@ class VkGenerator(object): f.write("\n") f.write("#ifndef VK_NO_PROTOTYPES\n") - for func in self.registry.funcs.values(): + for func in Context.funcs.values(): if not func.is_required(): LOGGER.debug("Skipping API definition for: {0}".format(func.name)) continue @@ -2867,7 +2909,7 @@ class VkGenerator(object): f.write("#endif /* VK_NO_PROTOTYPES */\n\n") f.write("#define ALL_VK_DEVICE_FUNCS") - for vk_func in self.registry.device_funcs: + for vk_func in self.device_funcs: if not vk_func.is_required(): continue if not vk_func.needs_dispatch(): @@ -2876,19 +2918,19 @@ class VkGenerator(object): f.write("\n\n") f.write("#define ALL_VK_CLIENT_DEVICE_EXTS") - for ext in self.registry.extensions: + for ext in self.extensions: if ext.type == "device" and ext.is_exposed: f.write(f" \\\n USE_VK_EXT({ext.name})") f.write("\n\n") f.write("#define ALL_VK_DEVICE_EXTS ALL_VK_CLIENT_DEVICE_EXTS") - for ext in self.registry.extensions: + for ext in self.extensions: if ext.type == "device" and not ext.is_exposed: f.write(f" \\\n USE_VK_EXT({ext.name})") f.write("\n\n") f.write("#define ALL_VK_INSTANCE_FUNCS") - for vk_func in self.registry.instance_funcs + self.registry.phys_dev_funcs: + for vk_func in self.instance_funcs + self.phys_dev_funcs: if not vk_func.is_required(): continue if not vk_func.needs_dispatch(): @@ -2897,13 +2939,13 @@ class VkGenerator(object): f.write("\n\n") f.write("#define ALL_VK_CLIENT_INSTANCE_EXTS") - for ext in self.registry.extensions: + for ext in self.extensions: if ext.type == "instance" and ext.is_exposed: f.write(f" \\\n USE_VK_EXT({ext.name})") f.write("\n\n") f.write("#define ALL_VK_INSTANCE_EXTS ALL_VK_CLIENT_INSTANCE_EXTS") - for ext in self.registry.extensions: + for ext in self.extensions: if ext.type == "instance" and not ext.is_exposed: f.write(f" \\\n USE_VK_EXT({ext.name})") f.write("\n\n") @@ -2917,7 +2959,7 @@ class VkGenerator(object): f.write("@ stdcall -private vk_icdNegotiateLoaderICDInterfaceVersion(ptr)\n") # Export symbols for all Vulkan Core functions. - for func in self.registry.funcs.values(): + for func in Context.funcs.values(): if not func.is_core_func(): continue @@ -2935,7 +2977,7 @@ class VkGenerator(object): self._generate_copyright(f, spec_file=True) # Export symbols for all Vulkan Core functions. - for func in self.registry.funcs.values(): + for func in Context.funcs.values(): if not func.is_core_func(): continue @@ -2946,55 +2988,6 @@ class VkGenerator(object): else: f.write("@ stub {0}\n".format(func.name)) - -class VkRegistry(object): - def __init__(self, vk_xml, video_xml): - # Used for storage of type information. - self.base_types = None - self.bitmasks = None - self.consts = None - self.defines = None - self.enums = None - self.funcpointers = None - self.handles = None - self.structs = None - - # We aggregate all types in here for cross-referencing. - self.funcs = {} - self.types = {} - - # Overall strategy for parsing the registry is to first - # parse all type / function definitions. Then parse - # features and extensions to decide which types / functions - # to actually 'pull in' for code generation. For each type or - # function call we want we set a member 'required' to True. - tree = ET.parse(vk_xml) - root = tree.getroot() - # The video XML currently only has enums, types, and part of the - # extension data in it. - # All of the relevant extensions and commands are in vk.xml. - video_tree = ET.parse(video_xml) - video_root = video_tree.getroot() - - self.copyright = root.find('./comment').text - self.video_copyright = video_root.find('./comment').text - - root.extend(video_root) - root.extend(ET.parse("winevk.xml").getroot()) - - self._parse_enums(root) - self._parse_types(root) - self._parse_commands(root) - - # Pull in any required types and functions. - self._parse_features(root) - self._parse_extensions(root) - - for enum in self.enums.values(): - enum.fixup_64bit_aliases() - - self._match_object_types() - def _mark_command_required(self, command): """ Helper function to mark a certain command and the datatypes it needs as required.""" def mark_bitmask_dependencies(bitmask, types): @@ -3016,7 +3009,7 @@ class VkRegistry(object): elif type_info["category"] == "bitmask": mark_bitmask_dependencies(type_info["data"], types) - func = self.funcs[command] + func = Context.funcs[command] func.required = True # Pull in return type @@ -3043,11 +3036,11 @@ class VkRegistry(object): """ Matches each handle with the correct object type. """ # Use upper case comparison for simplicity. object_types = {} - for value in self.enums["VkObjectType"].values: + for value in Context.enums["VkObjectType"].values: object_name = "VK" + value.name[len("VK_OBJECT_TYPE"):].replace("_", "") object_types[object_name] = value.name - for handle in self.handles: + for handle in Context.handles: if not handle.is_required(): continue handle.object_type = object_types.get(handle.name.upper()) @@ -3072,13 +3065,13 @@ class VkRegistry(object): alias_commands.append(command) continue - func = VkFunction.from_xml(self, command, self.types) + func = VkFunction.from_xml(command, self.types) funcs[func.name] = func for command in alias_commands: alias_name = command.attrib.get("alias") alias = funcs[alias_name] - func = VkFunction.from_alias(self, command, alias) + func = VkFunction.from_alias(command, alias) funcs[func.name] = func # To make life easy for the code generation, separate all function @@ -3106,12 +3099,11 @@ class VkRegistry(object): # The funcs dictionary is used as a convenient way to lookup function # calls when needed e.g. to adjust member variables. - self.funcs = OrderedDict(sorted(funcs.items())) + Context.funcs = OrderedDict(sorted(funcs.items())) def _parse_enums(self, root): """ Parse enums section or better described as constants section. """ enums = {} - self.consts = [] for enum in filter(is_api_supported, root.findall("./enums")): name = enum.attrib.get("name") _type = enum.attrib.get("type") @@ -3126,11 +3118,11 @@ class VkRegistry(object): # E.g. VK_LUID_SIZE_KHR is an alias to VK_LUID_SIZE. alias = value.attrib.get("alias") if alias: - self.consts.append(VkConstant(value.attrib.get("name"), alias)) + Context.consts.append(VkConstant(value.attrib.get("name"), alias)) else: - self.consts.append(VkConstant(value.attrib.get("name"), value.attrib.get("value"))) + Context.consts.append(VkConstant(value.attrib.get("name"), value.attrib.get("value"))) - self.enums = OrderedDict(sorted(enums.items())) + Context.enums = OrderedDict(sorted(enums.items())) def _process_require_enum(self, enum_elem, ext=None, only_aliased=False): if "extends" in enum_elem.keys(): @@ -3177,13 +3169,13 @@ class VkRegistry(object): if only_aliased: return - self.consts.append(VkConstant(enum_elem.attrib["name"], enum_elem.attrib["value"])) + Context.consts.append(VkConstant(enum_elem.attrib["name"], enum_elem.attrib["value"])) elif "alias" in enum_elem.keys(): # Aliased constant if not only_aliased: return - self.consts.append(VkConstant(enum_elem.attrib["name"], enum_elem.attrib["alias"])) + Context.consts.append(VkConstant(enum_elem.attrib["name"], enum_elem.attrib["alias"])) @staticmethod def _require_type(type_info): @@ -3193,7 +3185,7 @@ class VkRegistry(object): if type(type_info) == VkStruct: for member in type_info.members: if "data" in member.type_info: - VkRegistry._require_type(member.type_info["data"]) + Generator._require_type(member.type_info["data"]) def _parse_extensions(self, root): """ Parse extensions section and pull in any types and commands for this extension. """ @@ -3248,7 +3240,7 @@ class VkRegistry(object): # Set extension name on any functions calls part of this extension as we # were not aware of the name during initial parsing. for command in ext.findall("require/command"): - self.funcs[command.attrib["name"]].extensions.add(extension) + Context.funcs[command.attrib["name"]].extensions.add(extension) if not extension.is_supported: return @@ -3365,7 +3357,7 @@ class VkRegistry(object): if type_info["category"] == "basetype": name = t.find("name").text - define = VkDefine.from_xml(self, t) + define = VkDefine.from_xml(t) defines.append(define) type_info["data"] = define @@ -3388,7 +3380,7 @@ class VkRegistry(object): type_info["data"] = bitmask elif type_info["category"] == "define": - define = VkDefine.from_xml(self, t) + define = VkDefine.from_xml(t) defines.append(define) type_info["data"] = define @@ -3397,7 +3389,7 @@ class VkRegistry(object): # The type section only contains enum names, not the actual definition. # Since we already parsed the enum before, just link it in. try: - type_info["data"] = self.enums[name] + type_info["data"] = Context.enums[name] except KeyError: # Not all enums seem to be defined yet, typically that's for # ones ending in 'FlagBits' where future extensions may add @@ -3405,12 +3397,12 @@ class VkRegistry(object): type_info["data"] = None elif type_info["category"] == "funcpointer": - funcpointer = VkFunctionPointer.from_xml(self, t) + funcpointer = VkFunctionPointer.from_xml(t) funcpointers.append(funcpointer) type_info["data"] = funcpointer elif type_info["category"] == "handle": - handle = VkHandle.from_xml(self, t) + handle = VkHandle.from_xml(t) handles.append(handle) type_info["data"] = handle @@ -3419,7 +3411,7 @@ class VkRegistry(object): # on unions. The types are very similar in parsing and # generation anyway. The official Vulkan scripts use # a similar kind of hack. - struct = VkStruct.from_xml(self, t) + struct = VkStruct.from_xml(t) structs.append(struct) type_info["data"] = struct @@ -3451,16 +3443,16 @@ class VkRegistry(object): type_info["data"] = bitmask if type_info["category"] == "enum": - type_info["data"] = self.enums[alias] - self.enums[alias].typedefs += [type_info["name"]] + type_info["data"] = Context.enums[alias] + Context.enums[alias].typedefs += [type_info["name"]] if type_info["category"] == "handle": - handle = VkHandle.from_alias(self, t, self.types[alias]["data"]) + handle = VkHandle.from_alias(t, self.types[alias]["data"]) handles.append(handle) type_info["data"] = handle if type_info["category"] == "struct": - struct = VkStruct.from_alias(self, t, self.types[alias]["data"]) + struct = VkStruct.from_alias(t, self.types[alias]["data"]) structs.append(struct) type_info["data"] = struct @@ -3480,13 +3472,13 @@ class VkRegistry(object): # Guarantee everything is sorted, so code generation doesn't have # to deal with this. - self.base_types = sorted(base_types, key=lambda base_type: base_type.name) - self.bitmasks = sorted(bitmasks, key=lambda bitmask: bitmask.name) - self.defines = defines - self.enums = OrderedDict(sorted(self.enums.items())) - self.funcpointers = sorted(funcpointers, key=lambda fp: fp.value) - self.handles = sorted(handles, key=lambda handle: handle.name) - self.structs = sorted(structs.values(), key=lambda struct: (-struct.order, struct.name)) + Context.base_types = sorted(base_types, key=lambda base_type: base_type.name) + Context.bitmasks = sorted(bitmasks, key=lambda bitmask: bitmask.name) + Context.defines = defines + Context.enums = OrderedDict(sorted(Context.enums.items())) + Context.func_ptrs = sorted(funcpointers, key=lambda fp: fp.value) + Context.handles = sorted(handles, key=lambda handle: handle.name) + Context.structs = sorted(structs.values(), key=lambda struct: (-struct.order, struct.name)) def generate_vulkan_json(f): f.write("{\n") @@ -3541,8 +3533,7 @@ def main(): video_xml = os.path.join(cache, "video-{0}.xml".format(VK_XML_VERSION)) download_vk_xml(video_xml, "video.xml") - registry = VkRegistry(vk_xml, video_xml) - generator = VkGenerator(registry) + generator = Generator(vk_xml, video_xml) with open(WINE_VULKAN_H, "w") as f: generator.generate_vulkan_h(f) -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/9931
From: Rémi Bernon <rbernon@codeweavers.com> --- dlls/winevulkan/make_vulkan | 141 +++++++++++++++++++----------------- 1 file changed, 74 insertions(+), 67 deletions(-) diff --git a/dlls/winevulkan/make_vulkan b/dlls/winevulkan/make_vulkan index 5e6f0ff8a80..67eebdd641f 100755 --- a/dlls/winevulkan/make_vulkan +++ b/dlls/winevulkan/make_vulkan @@ -1353,37 +1353,36 @@ class VkMember(VkVariable): return expr.format(prefix=prefix, length=length) def copy(self, input, output, direction, conv, unwrap, parent_const, conversions, parent): - """ Helper method for use by conversion logic to generate a C-code statement to copy this member. - - `conv` indicates whether the statement is in a struct alignment conversion path. """ - - win_type = "win32" if conv else "win64" - suffix = convert_suffix(direction, win_type, unwrap, self.is_wrapped()) is_const = self.is_const() if self.is_pointer() else parent_const if self.needs_conversion(conv, unwrap, direction, False): if self.is_dynamic_array(): + convert = ArrayConversionFunction(self, direction, conv, unwrap) + conversions.append(convert) + # Array length is either a variable name (string) or an int. count = self.get_dyn_array_len(parent, input, conv) - pointer_part = "pointer_" if self.pointer_array else "" - conversions.append(ArrayConversionFunction(self, direction, conv, unwrap)) if direction == Direction.OUTPUT: - return "convert_{2}_{6}array_{5}({3}{1}, {0}, {4});\n".format(self.value(output, conv), - self.name, self.type, input, count, suffix, pointer_part) + value = self.value(output, conv) + return f"{convert.name}({input}{self.name}, {value}, {count});\n" else: - return "{0}{1} = convert_{2}_{6}array_{5}(ctx, {3}, {4});\n".format(output, - self.name, self.type, self.value(input, conv), count, suffix, pointer_part) + value = self.value(input, conv) + return f"{output}{self.name} = {convert.name}(ctx, {value}, {count});\n" + elif self.is_static_array(): + convert = ArrayConversionFunction(self, direction, conv, unwrap) + conversions.append(convert) + count = self.array_lens[0] if len(self.array_lens) > 1: LOGGER.warn("TODO: implement conversion of multidimensional static array for {0}.{1}".format(self.type, self.name)) elif direction == Direction.OUTPUT: # Needed by VkMemoryHeap.memoryHeaps - conversions.append(ArrayConversionFunction(self, direction, conv, unwrap)) - return "convert_{0}_array_{5}({2}{1}, {3}{1}, {4});\n".format(self.type, - self.name, input, output, count, suffix) + return f"{convert.name}({input}{self.name}, {output}{self.name}, {count});\n" else: # Nothing needed this yet. LOGGER.warn("TODO: implement copying of static array for {0}.{1}".format(self.type, self.name)) + elif self.is_handle() and self.is_wrapped(): handle = self.type_info["data"] if direction == Direction.OUTPUT: @@ -1394,20 +1393,23 @@ class VkMember(VkVariable): else: return "{0}{1} = {2};\n".format(output, self.name, handle.unwrap_handle(self.value(input, conv), unwrap)) + elif self.is_generic_handle(): if direction == Direction.OUTPUT: LOGGER.error("OUTPUT parameter {0}.{1} cannot be unwrapped".format(self.type, self.name)) return "{0}{1} = wine_vk_unwrap_handle({2}{3}, {2}{1});\n".format(output, self.name, input, self.object_type) else: - selector_part = ", {0}{1}".format(input, self.selector) if self.selector else "" - conversions.append(StructConversionFunction(self.struct, direction, conv, unwrap, is_const)) + convert = StructConversionFunction(self.struct, direction, conv, unwrap, is_const) + conversions.append(convert) + + sel = f", {input}{self.selector}" if self.selector else "" + ctx = "ctx, " if self.needs_alloc(conv, unwrap) else "" + if direction == Direction.OUTPUT: - return "convert_{0}_{4}(&{2}{1}, &{3}{1}{5});\n".format(self.type, - self.name, input, output, suffix, selector_part) + return f"{convert.name}(&{input}{self.name}, &{output}{self.name}{sel});\n" else: - ctx_param = "ctx, " if self.needs_alloc(conv, unwrap) else "" - return "convert_{0}_{4}({5}&{2}{1}, &{3}{1}{6});\n".format(self.type, - self.name, input, output, suffix, ctx_param, selector_part) + return f"{convert.name}({ctx}&{input}{self.name}, &{output}{self.name}{sel});\n" + elif self.is_static_array(): bytes_count = "sizeof({0})".format(self.type) for l in self.array_lens: @@ -1629,44 +1631,55 @@ class VkParam(VkVariable): return var.value(prefix, conv, deref=True) def copy(self, direction, conv, unwrap, conversions, params, prefix=""): - win_type = "win32" if conv else "win64" - suffix = convert_suffix(direction, win_type, unwrap, self.is_wrapped()) + value = self.value(prefix, conv) is_const = self.is_const() if self.is_pointer() else False if direction == Direction.INPUT: ctx_param = "ctx, " if self.needs_alloc(conv, unwrap) else "" if self.is_dynamic_array(): - conversions.append(ArrayConversionFunction(self, direction, conv, unwrap)) - return " {0}_host = convert_{2}_array_{4}({5}{1}, {3});\n".format(self.name, self.value(prefix, conv), - self.type, self.get_dyn_array_len(params, prefix, conv), suffix, ctx_param) + convert = ArrayConversionFunction(self, direction, conv, unwrap) + conversions.append(convert) + + length = self.get_dyn_array_len(params, prefix, conv) + return f" {self.name}_host = {convert.name}({ctx_param}{value}, {length});\n" + elif self.optional: - conversions.append(StructConversionFunction(self.struct, direction, conv, unwrap, is_const)) - ret = " if ({0}{1})\n".format(prefix, self.name) - ret += " {\n" - ret += " {0}_host = conversion_context_alloc(ctx, sizeof(*{0}_host));\n".format(self.name) - ret += " convert_{0}_{3}({4}{1}, {2}_host);\n".format(self.type, self.value(prefix, conv), - self.name, suffix, ctx_param) - ret += " }\n" + convert = StructConversionFunction(self.struct, direction, conv, unwrap, is_const) + conversions.append(convert) + + ret = f" if ({prefix}{self.name})\n" + ret += u" {\n" + ret += f" {self.name}_host = conversion_context_alloc(ctx, sizeof(*{self.name}_host));\n" + ret += f" {convert.name}({ctx_param}{value}, {self.name}_host);\n" + ret += u" }\n" return ret + elif self.is_struct(): - conversions.append(StructConversionFunction(self.struct, direction, conv, unwrap, is_const)) - return " convert_{0}_{3}({4}{1}, &{2}_host);\n".format(self.type, self.value(prefix, conv), - self.name, suffix, ctx_param) + convert = StructConversionFunction(self.struct, direction, conv, unwrap, is_const) + conversions.append(convert) + + return f" {convert.name}({ctx_param}{value}, &{self.name}_host);\n" + elif self.is_pointer_size() and self.type != "size_t": return " {0}_host = UlongToPtr(*{1});\n".format(self.name, self.value(prefix, conv)) else: return " {0}_host = *{1};\n".format(self.name, self.value(prefix, conv)) else: if self.is_dynamic_array(): - conversions.append(ArrayConversionFunction(self, direction, conv, unwrap)) - return " convert_{0}_array_{1}({2}_host, {3}, {4});\n".format( - self.type, suffix, self.name, self.value(prefix, conv).replace('const ', ''), - self.get_dyn_array_len(params, prefix, conv)) + convert = ArrayConversionFunction(self, direction, conv, unwrap) + conversions.append(convert) + + value = value.replace('const ', '') + length = self.get_dyn_array_len(params, prefix, conv) + return f" {convert.name}({self.name}_host, {value}, {length});\n" + elif self.is_struct(): + convert = StructConversionFunction(self.struct, direction, conv, unwrap, is_const) + conversions.append(convert) + ref_part = "" if self.optional else "&" - conversions.append(StructConversionFunction(self.struct, direction, conv, unwrap, is_const)) - return " convert_{0}_host_to_{3}({4}{2}_host, {1});\n".format( - self.type, self.value(prefix, conv), self.name, win_type, ref_part) + return f" {convert.name}({ref_part}{self.name}_host, {value});\n" + elif self.is_pointer_size() and self.type != "size_t": return " *{0} = PtrToUlong({1}_host);\n".format(self.value(prefix, conv), self.name) else: @@ -2410,33 +2423,27 @@ class ArrayConversionFunction(object): if self.array.is_struct(): struct = self.array.struct is_const = self.array.is_const() if self.array.is_pointer() else False - win_part = "win32" if self.conv else "win64" - suffix = convert_suffix(self.direction, win_part, self.unwrap, struct.is_wrapped()) - ctx_part = "" - if self.direction == Direction.INPUT and struct.needs_alloc(self.conv, self.unwrap): - ctx_part = "ctx, " + + convert = StructConversionFunction(struct, self.direction, self.conv, self.unwrap, is_const) + ctx = "ctx, " if self.direction == Direction.INPUT and struct.needs_alloc(self.conv, self.unwrap) else "" + inp = f"({win_type} *)UlongToPtr(in[i])" if self.conv else "in[i]" if not pointer_array: - conversions.append(StructConversionFunction(struct, self.direction, self.conv, self.unwrap, is_const)) - body += " convert_{0}_{1}({2}&in[i], &out[i]);\n".format( - struct.name, suffix, ctx_part) + conversions.append(convert) + body += f" {convert.name}({ctx}&in[i], &out[i]);\n" + + elif struct.needs_conversion(self.conv, self.unwrap, self.direction, False): + conversions.append(convert) + body += u" if (in[i])\n" + body += u" {\n" + body += u" out[i] = conversion_context_alloc(ctx, sizeof(*out[i]));\n" + body += f" {convert.name}({ctx}{inp}, out[i]);\n" + body += u" }\n" + body += u" else\n" + body += u" out[i] = NULL;\n" else: - if struct.needs_conversion(self.conv, self.unwrap, self.direction, False): - body += " if (in[i])\n" - body += " {\n" - body += " out[i] = conversion_context_alloc(ctx, sizeof(*out[i]));\n" - if self.conv: - in_param = "({0} *)UlongToPtr(in[i])".format(win_type) - else: - in_param = "in[i]" - conversions.append(StructConversionFunction(struct, self.direction, self.conv, self.unwrap, is_const)) - body += " convert_{0}_{1}({2}{3}, out[i]);\n".format( - struct.name, suffix, ctx_part, in_param) - body += " }\n" - body += " else\n" - body += " out[i] = NULL;\n" - else: - body += " out[i] = UlongToPtr(in[i]);\n" + body += u" out[i] = UlongToPtr(in[i]);\n" + elif self.array.is_handle(): if pointer_array: LOGGER.error("Unhandled handle pointer arrays") -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/9931
From: Rémi Bernon <rbernon@codeweavers.com> --- dlls/winevulkan/loader.c | 7 +--- dlls/winevulkan/loader_thunks.c | 59 +++++++++++++++++++++++++++++++++ dlls/winevulkan/make_vulkan | 15 ++++++--- include/wine/vulkan.h | 12 +++---- 4 files changed, 76 insertions(+), 17 deletions(-) diff --git a/dlls/winevulkan/loader.c b/dlls/winevulkan/loader.c index 33a3c80e3f4..649aec5448c 100644 --- a/dlls/winevulkan/loader.c +++ b/dlls/winevulkan/loader.c @@ -121,9 +121,6 @@ PFN_vkVoidFunction WINAPI vkGetInstanceProcAddr(VkInstance instance, const char func = wine_vk_get_instance_proc_addr(name); if (func) return func; - func = wine_vk_get_phys_dev_proc_addr(name); - if (func) return func; - /* vkGetInstanceProcAddr also loads any children of instance, so device functions as well. */ func = wine_vk_get_device_proc_addr(name); if (func) return func; @@ -188,9 +185,7 @@ PFN_vkVoidFunction WINAPI vkGetDeviceProcAddr(VkDevice device, const char *name) * https://github.com/KhronosGroup/Vulkan-LoaderAndValidationLayers/issues/2323 * https://github.com/KhronosGroup/Vulkan-Docs/issues/655 */ - if (get_device_proc_addr_instance_procs - && ((func = wine_vk_get_instance_proc_addr(name)) - || (func = wine_vk_get_phys_dev_proc_addr(name)))) + if (get_device_proc_addr_instance_procs && (func = wine_vk_get_instance_proc_addr(name))) { WARN("Returning instance function %s.\n", debugstr_a(name)); return func; diff --git a/dlls/winevulkan/loader_thunks.c b/dlls/winevulkan/loader_thunks.c index 963455b56fc..a7daff6b0ff 100644 --- a/dlls/winevulkan/loader_thunks.c +++ b/dlls/winevulkan/loader_thunks.c @@ -7869,15 +7869,74 @@ static const struct vulkan_func vk_instance_dispatch_table[] = { {"vkCreateDebugReportCallbackEXT", vkCreateDebugReportCallbackEXT}, {"vkCreateDebugUtilsMessengerEXT", vkCreateDebugUtilsMessengerEXT}, + {"vkCreateDevice", vkCreateDevice}, {"vkCreateWin32SurfaceKHR", vkCreateWin32SurfaceKHR}, {"vkDebugReportMessageEXT", vkDebugReportMessageEXT}, {"vkDestroyDebugReportCallbackEXT", vkDestroyDebugReportCallbackEXT}, {"vkDestroyDebugUtilsMessengerEXT", vkDestroyDebugUtilsMessengerEXT}, {"vkDestroyInstance", vkDestroyInstance}, {"vkDestroySurfaceKHR", vkDestroySurfaceKHR}, + {"vkEnumerateDeviceExtensionProperties", vkEnumerateDeviceExtensionProperties}, + {"vkEnumerateDeviceLayerProperties", vkEnumerateDeviceLayerProperties}, {"vkEnumeratePhysicalDeviceGroups", vkEnumeratePhysicalDeviceGroups}, {"vkEnumeratePhysicalDeviceGroupsKHR", vkEnumeratePhysicalDeviceGroupsKHR}, + {"vkEnumeratePhysicalDeviceQueueFamilyPerformanceCountersByRegionARM", vkEnumeratePhysicalDeviceQueueFamilyPerformanceCountersByRegionARM}, + {"vkEnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR", vkEnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR}, {"vkEnumeratePhysicalDevices", vkEnumeratePhysicalDevices}, + {"vkGetPhysicalDeviceCalibrateableTimeDomainsEXT", vkGetPhysicalDeviceCalibrateableTimeDomainsEXT}, + {"vkGetPhysicalDeviceCalibrateableTimeDomainsKHR", vkGetPhysicalDeviceCalibrateableTimeDomainsKHR}, + {"vkGetPhysicalDeviceCooperativeMatrixFlexibleDimensionsPropertiesNV", vkGetPhysicalDeviceCooperativeMatrixFlexibleDimensionsPropertiesNV}, + {"vkGetPhysicalDeviceCooperativeMatrixPropertiesKHR", vkGetPhysicalDeviceCooperativeMatrixPropertiesKHR}, + {"vkGetPhysicalDeviceCooperativeMatrixPropertiesNV", vkGetPhysicalDeviceCooperativeMatrixPropertiesNV}, + {"vkGetPhysicalDeviceCooperativeVectorPropertiesNV", vkGetPhysicalDeviceCooperativeVectorPropertiesNV}, + {"vkGetPhysicalDeviceExternalBufferProperties", vkGetPhysicalDeviceExternalBufferProperties}, + {"vkGetPhysicalDeviceExternalBufferPropertiesKHR", vkGetPhysicalDeviceExternalBufferPropertiesKHR}, + {"vkGetPhysicalDeviceExternalFenceProperties", vkGetPhysicalDeviceExternalFenceProperties}, + {"vkGetPhysicalDeviceExternalFencePropertiesKHR", vkGetPhysicalDeviceExternalFencePropertiesKHR}, + {"vkGetPhysicalDeviceExternalSemaphoreProperties", vkGetPhysicalDeviceExternalSemaphoreProperties}, + {"vkGetPhysicalDeviceExternalSemaphorePropertiesKHR", vkGetPhysicalDeviceExternalSemaphorePropertiesKHR}, + {"vkGetPhysicalDeviceExternalTensorPropertiesARM", vkGetPhysicalDeviceExternalTensorPropertiesARM}, + {"vkGetPhysicalDeviceFeatures", vkGetPhysicalDeviceFeatures}, + {"vkGetPhysicalDeviceFeatures2", vkGetPhysicalDeviceFeatures2}, + {"vkGetPhysicalDeviceFeatures2KHR", vkGetPhysicalDeviceFeatures2KHR}, + {"vkGetPhysicalDeviceFormatProperties", vkGetPhysicalDeviceFormatProperties}, + {"vkGetPhysicalDeviceFormatProperties2", vkGetPhysicalDeviceFormatProperties2}, + {"vkGetPhysicalDeviceFormatProperties2KHR", vkGetPhysicalDeviceFormatProperties2KHR}, + {"vkGetPhysicalDeviceFragmentShadingRatesKHR", vkGetPhysicalDeviceFragmentShadingRatesKHR}, + {"vkGetPhysicalDeviceImageFormatProperties", vkGetPhysicalDeviceImageFormatProperties}, + {"vkGetPhysicalDeviceImageFormatProperties2", vkGetPhysicalDeviceImageFormatProperties2}, + {"vkGetPhysicalDeviceImageFormatProperties2KHR", vkGetPhysicalDeviceImageFormatProperties2KHR}, + {"vkGetPhysicalDeviceMemoryProperties", vkGetPhysicalDeviceMemoryProperties}, + {"vkGetPhysicalDeviceMemoryProperties2", vkGetPhysicalDeviceMemoryProperties2}, + {"vkGetPhysicalDeviceMemoryProperties2KHR", vkGetPhysicalDeviceMemoryProperties2KHR}, + {"vkGetPhysicalDeviceMultisamplePropertiesEXT", vkGetPhysicalDeviceMultisamplePropertiesEXT}, + {"vkGetPhysicalDeviceOpticalFlowImageFormatsNV", vkGetPhysicalDeviceOpticalFlowImageFormatsNV}, + {"vkGetPhysicalDevicePresentRectanglesKHR", vkGetPhysicalDevicePresentRectanglesKHR}, + {"vkGetPhysicalDeviceProperties", vkGetPhysicalDeviceProperties}, + {"vkGetPhysicalDeviceProperties2", vkGetPhysicalDeviceProperties2}, + {"vkGetPhysicalDeviceProperties2KHR", vkGetPhysicalDeviceProperties2KHR}, + {"vkGetPhysicalDeviceQueueFamilyDataGraphProcessingEnginePropertiesARM", vkGetPhysicalDeviceQueueFamilyDataGraphProcessingEnginePropertiesARM}, + {"vkGetPhysicalDeviceQueueFamilyDataGraphPropertiesARM", vkGetPhysicalDeviceQueueFamilyDataGraphPropertiesARM}, + {"vkGetPhysicalDeviceQueueFamilyPerformanceQueryPassesKHR", vkGetPhysicalDeviceQueueFamilyPerformanceQueryPassesKHR}, + {"vkGetPhysicalDeviceQueueFamilyProperties", vkGetPhysicalDeviceQueueFamilyProperties}, + {"vkGetPhysicalDeviceQueueFamilyProperties2", vkGetPhysicalDeviceQueueFamilyProperties2}, + {"vkGetPhysicalDeviceQueueFamilyProperties2KHR", vkGetPhysicalDeviceQueueFamilyProperties2KHR}, + {"vkGetPhysicalDeviceSparseImageFormatProperties", vkGetPhysicalDeviceSparseImageFormatProperties}, + {"vkGetPhysicalDeviceSparseImageFormatProperties2", vkGetPhysicalDeviceSparseImageFormatProperties2}, + {"vkGetPhysicalDeviceSparseImageFormatProperties2KHR", vkGetPhysicalDeviceSparseImageFormatProperties2KHR}, + {"vkGetPhysicalDeviceSupportedFramebufferMixedSamplesCombinationsNV", vkGetPhysicalDeviceSupportedFramebufferMixedSamplesCombinationsNV}, + {"vkGetPhysicalDeviceSurfaceCapabilities2KHR", vkGetPhysicalDeviceSurfaceCapabilities2KHR}, + {"vkGetPhysicalDeviceSurfaceCapabilitiesKHR", vkGetPhysicalDeviceSurfaceCapabilitiesKHR}, + {"vkGetPhysicalDeviceSurfaceFormats2KHR", vkGetPhysicalDeviceSurfaceFormats2KHR}, + {"vkGetPhysicalDeviceSurfaceFormatsKHR", vkGetPhysicalDeviceSurfaceFormatsKHR}, + {"vkGetPhysicalDeviceSurfacePresentModesKHR", vkGetPhysicalDeviceSurfacePresentModesKHR}, + {"vkGetPhysicalDeviceSurfaceSupportKHR", vkGetPhysicalDeviceSurfaceSupportKHR}, + {"vkGetPhysicalDeviceToolProperties", vkGetPhysicalDeviceToolProperties}, + {"vkGetPhysicalDeviceToolPropertiesEXT", vkGetPhysicalDeviceToolPropertiesEXT}, + {"vkGetPhysicalDeviceVideoCapabilitiesKHR", vkGetPhysicalDeviceVideoCapabilitiesKHR}, + {"vkGetPhysicalDeviceVideoEncodeQualityLevelPropertiesKHR", vkGetPhysicalDeviceVideoEncodeQualityLevelPropertiesKHR}, + {"vkGetPhysicalDeviceVideoFormatPropertiesKHR", vkGetPhysicalDeviceVideoFormatPropertiesKHR}, + {"vkGetPhysicalDeviceWin32PresentationSupportKHR", vkGetPhysicalDeviceWin32PresentationSupportKHR}, {"vkSubmitDebugUtilsMessageEXT", vkSubmitDebugUtilsMessageEXT}, }; diff --git a/dlls/winevulkan/make_vulkan b/dlls/winevulkan/make_vulkan index 67eebdd641f..44b411cfc57 100755 --- a/dlls/winevulkan/make_vulkan +++ b/dlls/winevulkan/make_vulkan @@ -636,7 +636,7 @@ class VkFunction(object): def is_device_func(self): # If none of the other, it must be a device function - return not self.is_global_func() and not self.is_instance_func() and not self.is_phys_dev_func() + return not self.is_global_func() and not self.is_instance_func() def is_driver_func(self): """ Returns if function is part of Wine driver interface. """ @@ -653,12 +653,16 @@ class VkFunction(object): return True def is_instance_func(self): + if self.is_global_func(): + return False # Instance functions are passed VkInstance. if self.params[0].type == "VkInstance": return True - return False + return self.is_physical_device() - def is_phys_dev_func(self): + def is_physical_device(self): + if self.is_global_func(): + return False # Physical device functions are passed VkPhysicalDevice. if self.params[0].type == "VkPhysicalDevice": return True @@ -2937,7 +2941,7 @@ class Generator(object): f.write("\n\n") f.write("#define ALL_VK_INSTANCE_FUNCS") - for vk_func in self.instance_funcs + self.phys_dev_funcs: + for vk_func in self.instance_funcs: if not vk_func.is_required(): continue if not vk_func.needs_dispatch(): @@ -3093,8 +3097,9 @@ class Generator(object): device_funcs.append(func) elif func.is_global_func(): global_funcs.append(func) - elif func.is_phys_dev_func(): + elif func.is_physical_device(): phys_dev_funcs.append(func) + instance_funcs.append(func) else: instance_funcs.append(func) diff --git a/include/wine/vulkan.h b/include/wine/vulkan.h index 9842d035c1f..45cbef3ce83 100644 --- a/include/wine/vulkan.h +++ b/include/wine/vulkan.h @@ -21638,6 +21638,7 @@ VkResult VKAPI_CALL vkWriteMicromapsPropertiesEXT(VkDevice device, uint32_t micr #define ALL_VK_INSTANCE_FUNCS \ USE_VK_FUNC(vkCreateDebugReportCallbackEXT) \ USE_VK_FUNC(vkCreateDebugUtilsMessengerEXT) \ + USE_VK_FUNC(vkCreateDevice) \ USE_VK_FUNC(vkCreateHeadlessSurfaceEXT) \ USE_VK_FUNC(vkCreateMacOSSurfaceMVK) \ USE_VK_FUNC(vkCreateMetalSurfaceEXT) \ @@ -21649,15 +21650,13 @@ VkResult VKAPI_CALL vkWriteMicromapsPropertiesEXT(VkDevice device, uint32_t micr USE_VK_FUNC(vkDestroyDebugUtilsMessengerEXT) \ USE_VK_FUNC(vkDestroyInstance) \ USE_VK_FUNC(vkDestroySurfaceKHR) \ - USE_VK_FUNC(vkEnumeratePhysicalDeviceGroups) \ - USE_VK_FUNC(vkEnumeratePhysicalDeviceGroupsKHR) \ - USE_VK_FUNC(vkEnumeratePhysicalDevices) \ - USE_VK_FUNC(vkSubmitDebugUtilsMessageEXT) \ - USE_VK_FUNC(vkCreateDevice) \ USE_VK_FUNC(vkEnumerateDeviceExtensionProperties) \ USE_VK_FUNC(vkEnumerateDeviceLayerProperties) \ + USE_VK_FUNC(vkEnumeratePhysicalDeviceGroups) \ + USE_VK_FUNC(vkEnumeratePhysicalDeviceGroupsKHR) \ USE_VK_FUNC(vkEnumeratePhysicalDeviceQueueFamilyPerformanceCountersByRegionARM) \ USE_VK_FUNC(vkEnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR) \ + USE_VK_FUNC(vkEnumeratePhysicalDevices) \ USE_VK_FUNC(vkGetPhysicalDeviceCalibrateableTimeDomainsEXT) \ USE_VK_FUNC(vkGetPhysicalDeviceCalibrateableTimeDomainsKHR) \ USE_VK_FUNC(vkGetPhysicalDeviceCooperativeMatrixFlexibleDimensionsPropertiesNV) \ @@ -21713,7 +21712,8 @@ VkResult VKAPI_CALL vkWriteMicromapsPropertiesEXT(VkDevice device, uint32_t micr USE_VK_FUNC(vkGetPhysicalDeviceVideoFormatPropertiesKHR) \ USE_VK_FUNC(vkGetPhysicalDeviceWaylandPresentationSupportKHR) \ USE_VK_FUNC(vkGetPhysicalDeviceWin32PresentationSupportKHR) \ - USE_VK_FUNC(vkGetPhysicalDeviceXlibPresentationSupportKHR) + USE_VK_FUNC(vkGetPhysicalDeviceXlibPresentationSupportKHR) \ + USE_VK_FUNC(vkSubmitDebugUtilsMessageEXT) #define ALL_VK_CLIENT_INSTANCE_EXTS \ USE_VK_EXT(VK_EXT_debug_report) \ -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/9931
From: Rémi Bernon <rbernon@codeweavers.com> --- dlls/winevulkan/make_vulkan | 79 ++++++++++--------------------------- 1 file changed, 21 insertions(+), 58 deletions(-) diff --git a/dlls/winevulkan/make_vulkan b/dlls/winevulkan/make_vulkan index 44b411cfc57..5c4358fdb70 100755 --- a/dlls/winevulkan/make_vulkan +++ b/dlls/winevulkan/make_vulkan @@ -590,7 +590,7 @@ class EnumValue(object): return f"{self.name} = {value}{suffix}" -class VkFunction(object): +class Function(object): def __init__(self, _type, name, params, alias=None): self.extensions = set() self.platforms = set() @@ -616,7 +616,7 @@ class VkFunction(object): @staticmethod def from_alias(command, alias): func_name = command.attrib.get("name") - return VkFunction(alias.type, func_name, alias.params, alias=alias) + return Function(alias.type, func_name, alias.params, alias=alias) @staticmethod def from_xml(command, types): @@ -626,7 +626,7 @@ class VkFunction(object): params = filter(is_api_supported, command.findall("param")) params = [VkParam.from_xml(param, types) for param in params] - return VkFunction(func_type, func_name, params) + return Function(func_type, func_name, params) def is_alias(self): return bool(self.alias) @@ -716,32 +716,12 @@ class VkFunction(object): pfn += ")" return pfn - def prototype(self, call_conv=None, prefix=None, is_thunk=False): - """ Generate prototype for given function. - - Args: - call_conv (str, optional): calling convention e.g. WINAPI - prefix (str, optional): prefix to append prior to function name e.g. vkFoo -> wine_vkFoo - """ - - proto = "{0}".format(self.type) - - if call_conv is not None: - proto += " {0}".format(call_conv) - - if prefix is not None: - proto += " {0}{1}(".format(prefix, self.name) - else: - proto += " {0}(".format(self.name) + def prototype(self, call_conv="", prefix="", is_thunk=False, suffix=""): + extra = [f"void *{self.extra_param}"] if is_thunk and self.extra_param else [] + params = [p.definition() for p in self.params] + params = ", ".join(params + extra) - # Add all the parameters. - proto += ", ".join([p.definition() for p in self.params]) - - if is_thunk and self.extra_param: - proto += ", void *" + self.extra_param - - proto += ")" - return proto + return f"{self.type} {call_conv}{prefix}{self.name}({params}){suffix}" def loader_body(self): body = " struct {0}_params params;\n".format(self.name) @@ -878,21 +858,6 @@ class VkFunction(object): spec += "\n" return spec - def stub(self, call_conv=None, prefix=None): - stub = self.prototype(call_conv=call_conv, prefix=prefix) - stub += "\n{\n" - stub += " {0}".format(self.trace(message="stub: ", trace_func="FIXME")) - - if self.type == "VkResult": - stub += " return VK_ERROR_OUT_OF_HOST_MEMORY;\n" - elif self.type == "VkBool32": - stub += " return VK_FALSE;\n" - elif self.type == "PFN_vkVoidFunction": - stub += " return NULL;\n" - - stub += "}\n\n" - return stub - def thunk(self, conversions, prefix=None, conv=False): thunk = "" if not conv: @@ -921,8 +886,8 @@ class VkFunction(object): thunk += "\n" return thunk - def loader_thunk(self, prefix=None): - thunk = self.prototype(call_conv="WINAPI", prefix=prefix) + def loader_thunk(self): + thunk = self.prototype(call_conv="WINAPI ") thunk += "\n{\n" thunk += self.loader_body() thunk += "}\n\n" @@ -958,20 +923,18 @@ class VkFunction(object): return trace -class VkFunctionPointer(object): +class FunctionPointer(object): def __init__(self, value): self.extensions = set() self.value = value self.required = False @staticmethod - def from_xml(funcpointer): - value = innertext(funcpointer).replace('\n', '') + def from_xml(xml): + value = innertext(xml).replace('\n', '') value = re.sub(r'\s*//.*$', '', value, flags=re.M) value = re.sub(r'\s+', ' ', value, flags=re.M) - value = value.strip() - - return VkFunctionPointer(value) + return FunctionPointer(value.strip()) def definition(self): return self.value + '\n' @@ -2671,7 +2634,7 @@ class Generator(object): f.write("};\n") f.write("C_ASSERT(ARRAYSIZE(__wine_unix_call_funcs) == unix_count);\n") - def generate_thunks_h(self, f, prefix): + def generate_thunks_h(self, f): self._generate_copyright(f) f.write("#ifndef __WINE_VULKAN_THUNKS_H\n") @@ -2686,7 +2649,7 @@ class Generator(object): if not vk_func.needs_private_thunk(): continue - f.write("{0};\n".format(vk_func.prototype(prefix=prefix, is_thunk=True))) + f.write("{0};\n".format(vk_func.prototype(prefix="wine_", is_thunk=True))) f.write("\n") f.write("#endif /* __WINE_VULKAN_THUNKS_H */\n") @@ -2916,7 +2879,7 @@ class Generator(object): continue LOGGER.debug("Generating API definition for: {0}".format(func.name)) - f.write("{0};\n".format(func.prototype(call_conv="VKAPI_CALL"))) + f.write("{0};\n".format(func.prototype(call_conv="VKAPI_CALL "))) f.write("#endif /* VK_NO_PROTOTYPES */\n\n") f.write("#define ALL_VK_DEVICE_FUNCS") @@ -3076,13 +3039,13 @@ class Generator(object): alias_commands.append(command) continue - func = VkFunction.from_xml(command, self.types) + func = Function.from_xml(command, self.types) funcs[func.name] = func for command in alias_commands: alias_name = command.attrib.get("alias") alias = funcs[alias_name] - func = VkFunction.from_alias(command, alias) + func = Function.from_alias(command, alias) funcs[func.name] = func # To make life easy for the code generation, separate all function @@ -3409,7 +3372,7 @@ class Generator(object): type_info["data"] = None elif type_info["category"] == "funcpointer": - funcpointer = VkFunctionPointer.from_xml(t) + funcpointer = FunctionPointer.from_xml(t) funcpointers.append(funcpointer) type_info["data"] = funcpointer @@ -3551,7 +3514,7 @@ def main(): generator.generate_vulkan_h(f) with open(WINE_VULKAN_THUNKS_H, "w") as f: - generator.generate_thunks_h(f, "wine_") + generator.generate_thunks_h(f) with open(WINE_VULKAN_THUNKS_C, "w") as f: generator.generate_thunks_c(f) -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/9931
participants (2)
-
Rémi Bernon -
Rémi Bernon (@rbernon)