[PATCH v6 1/3] winevulkan: Generate helpers for wrapped handles.

Liam Middlebrook lmiddlebrook at nvidia.com
Tue Oct 13 20:31:39 CDT 2020


Signed-off-by: Liam Middlebrook <lmiddlebrook at nvidia.com>

On 10/13/20 10:28 AM, Georg Lehmann wrote:
> Signed-off-by: Georg Lehmann <dadschoorse at gmail.com>
> ---
>   dlls/winevulkan/make_vulkan      | 81 +++++++++++++++++++++++++++-----
>   dlls/winevulkan/vulkan.c         | 21 +--------
>   dlls/winevulkan/vulkan_private.h |  3 ++
>   3 files changed, 74 insertions(+), 31 deletions(-)
> 
> diff --git a/dlls/winevulkan/make_vulkan b/dlls/winevulkan/make_vulkan
> index 7f89cfdabaa..13a4962dd1a 100755
> --- a/dlls/winevulkan/make_vulkan
> +++ b/dlls/winevulkan/make_vulkan
> @@ -371,20 +371,21 @@ class VkEnum(object):
>               # Value is either a value or a bitpos, only one can exist.
>               value = v.attrib.get("value")
>               alias_name = v.attrib.get("alias")
> +            comment = v.attrib.get("comment")
>               if alias_name:
>                   alias = next(x for x in values if x.name == alias_name)
> -                values.append(VkEnumValue(v.attrib.get("name"), value=alias.value, hex=alias.hex))
> +                values.append(VkEnumValue(v.attrib.get("name"), value=alias.value, hex=alias.hex, comment=comment))
>               elif value:
>                   # Some values are in hex form. We want to preserve the hex representation
>                   # at least when we convert back to a string. Internally we want to use int.
>                   if "0x" in value:
> -                    values.append(VkEnumValue(v.attrib.get("name"), value=int(value, 0), hex=True))
> +                    values.append(VkEnumValue(v.attrib.get("name"), value=int(value, 0), hex=True, comment=comment))
>                   else:
> -                    values.append(VkEnumValue(v.attrib.get("name"), value=int(value, 0)))
> +                    values.append(VkEnumValue(v.attrib.get("name"), value=int(value, 0), comment=comment))
>               else:
>                   # bitmask
>                   value = 1 << int(v.attrib.get("bitpos"))
> -                values.append(VkEnumValue(v.attrib.get("name"), value=value, hex=True))
> +                values.append(VkEnumValue(v.attrib.get("name"), value=value, hex=True, comment=comment))
>   
>           # vulkan.h contains a *_MAX_ENUM value set to 32-bit at the time of writing,
>           # which is to prepare for extensions as they can add values and hence affect
> @@ -435,11 +436,12 @@ class VkEnum(object):
>   
>   
>   class VkEnumValue(object):
> -    def __init__(self, name, value=None, hex=False, alias=None):
> +    def __init__(self, name, value=None, hex=False, alias=None, comment=None):
>           self.name = name
>           self.value = value
>           self.hex = hex
>           self.alias = alias
> +        self.comment = comment
>   
>       def __repr__(self):
>           if self.is_alias():
> @@ -885,6 +887,7 @@ class VkHandle(object):
>           self.parent = parent
>           self.alias = alias
>           self.required = False
> +        self.object_type = None
>   
>       @staticmethod
>       def from_alias(handle, alias):
> @@ -939,9 +942,6 @@ class VkHandle(object):
>       def native_handle(self, name):
>           """ Provide access to the native handle of a wrapped object. """
>   
> -        # Remember to add any new native handle whose parent is VkDevice
> -        # to unwrap_object_handle() in vulkan.c
> -
>           if self.name == "VkCommandPool":
>               return "wine_cmd_pool_from_handle({0})->command_pool".format(name)
>   
> @@ -965,6 +965,9 @@ class VkHandle(object):
>               LOGGER.error("Unhandled native handle for: {0}".format(self.name))
>           return None
>   
> +    def is_wrapped(self):
> +        return self.native_handle("test") is not None
> +
>   
>   class VkMember(object):
>       def __init__(self, const=False, struct_fwd_decl=False,_type=None, pointer=None, name=None, array_len=None,
> @@ -2276,6 +2279,36 @@ class VkGenerator(object):
>           f.write("            return TRUE;\n")
>           f.write("    }\n")
>           f.write("    return FALSE;\n")
> +        f.write("}\n\n")
> +
> +        f.write("BOOL wine_vk_is_type_wrapped(VkObjectType type)\n")
> +        f.write("{\n")
> +        f.write("    return FALSE")
> +        for handle in self.registry.handles:
> +            if not handle.is_required() or not handle.is_wrapped() or handle.is_alias():
> +                continue
> +            f.write(" ||\n        type == {}".format(handle.object_type))
> +        f.write(";\n")
> +        f.write("}\n\n")
> +
> +        f.write("uint64_t wine_vk_unwrap_handle(VkObjectType type, uint64_t handle)\n")
> +        f.write("{\n")
> +        f.write("    switch(type)\n")
> +        f.write("    {\n")
> +        for handle in self.registry.handles:
> +            if not handle.is_required() or not handle.is_wrapped() or handle.is_alias():
> +                continue
> +            f.write("    case {}:\n".format(handle.object_type))
> +            if handle.is_dispatchable():
> +                f.write("        return (uint64_t) (uintptr_t) ")
> +                f.write(handle.native_handle("(({}) (uintptr_t) handle)".format(handle.name)))
> +            else:
> +                f.write("        return (uint64_t) ")
> +                f.write(handle.native_handle("handle"))
> +            f.write(";\n");
> +        f.write("    default:\n")
> +        f.write("       return handle;\n")
> +        f.write("    }\n")
>           f.write("}\n")
>   
>       def generate_thunks_h(self, f, prefix):
> @@ -2619,6 +2652,8 @@ class VkRegistry(object):
>           self._parse_features(root)
>           self._parse_extensions(root)
>   
> +        self._match_object_types()
> +
>           self.copyright = root.find('./comment').text
>   
>       def _is_feature_supported(self, feature):
> @@ -2689,6 +2724,26 @@ class VkRegistry(object):
>               elif type_info["category"] == "bitmask":
>                   mark_bitmask_dependencies(type_info["data"], self.types)
>   
> +    def _match_object_types(self):
> +        """ Matches each handle with the correct object type. """
> +        for handle in self.handles:
> +            if not handle.is_required() or handle.is_alias():
> +                continue
> +            for value in self.enums["VkObjectType"].values:
> +                if value.comment == handle.name:
> +                    handle.object_type = value.name
> +                    break
> +            else:
> +                LOGGER.warning("No object type found for {}".format(handle.name))
> +
> +        for handle in self.handles:
> +            if not handle.is_required() or not handle.is_alias():
> +                continue
> +            # Use the object type of the alias
> +            handle.object_type = handle.alias.object_type
> +            if not handle.object_type:
> +                LOGGER.warning("No object type found for {}".format(handle.name))
> +
>       def _parse_commands(self, root):
>           """ Parse command section containing the Vulkan function calls. """
>           funcs = {}
> @@ -2782,10 +2837,12 @@ class VkRegistry(object):
>               if only_aliased and not aliased:
>                   return
>   
> +            comment = enum_elem.attrib.get("comment")
> +
>               if "bitpos" in enum_elem.keys():
>                   # We need to add an extra value to an existing enum type.
>                   # E.g. VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_IMG to VkFormatFeatureFlagBits.
> -                enum.add(VkEnumValue(enum_elem.attrib["name"], value=(1 << int(enum_elem.attrib["bitpos"])), hex=True))
> +                enum.add(VkEnumValue(enum_elem.attrib["name"], value=(1 << int(enum_elem.attrib["bitpos"])), hex=True, comment=comment))
>   
>               elif "offset" in enum_elem.keys():
>                   # Extensions promoted to Core, have the extension number as part
> @@ -2802,12 +2859,12 @@ class VkRegistry(object):
>                   if direction is not None:
>                       value = -value
>   
> -                enum.add(VkEnumValue(enum_elem.attrib["name"], value=value))
> +                enum.add(VkEnumValue(enum_elem.attrib["name"], value=value, comment=comment))
>   
>               elif "value" in enum_elem.keys():
> -                enum.add(VkEnumValue(enum_elem.attrib["name"], value=int(enum_elem.attrib["value"])))
> +                enum.add(VkEnumValue(enum_elem.attrib["name"], value=int(enum_elem.attrib["value"]), comment=comment))
>               elif "alias" in enum_elem.keys():
> -                enum.add(VkEnumValue(enum_elem.attrib["name"], alias=enum_elem.attrib["alias"]))
> +                enum.add(VkEnumValue(enum_elem.attrib["name"], alias=enum_elem.attrib["alias"], comment=comment))
>   
>           elif "value" in enum_elem.keys():
>               # Constants are not aliased, no need to add them here, they'll get added later on.
> diff --git a/dlls/winevulkan/vulkan.c b/dlls/winevulkan/vulkan.c
> index f730c04923a..3d1e8bd0abd 100644
> --- a/dlls/winevulkan/vulkan.c
> +++ b/dlls/winevulkan/vulkan.c
> @@ -1534,30 +1534,13 @@ void WINAPI wine_vkGetPhysicalDeviceExternalSemaphorePropertiesKHR(VkPhysicalDev
>       properties->externalSemaphoreFeatures = 0;
>   }
>   
> -static uint64_t unwrap_object_handle(VkObjectType type, uint64_t handle)
> -{
> -    switch (type)
> -    {
> -        case VK_OBJECT_TYPE_DEVICE:
> -            return (uint64_t) (uintptr_t) ((VkDevice) (uintptr_t) handle)->device;
> -        case VK_OBJECT_TYPE_QUEUE:
> -            return (uint64_t) (uintptr_t) ((VkQueue) (uintptr_t) handle)->queue;
> -        case VK_OBJECT_TYPE_COMMAND_BUFFER:
> -            return (uint64_t) (uintptr_t) ((VkCommandBuffer) (uintptr_t) handle)->command_buffer;
> -        case VK_OBJECT_TYPE_COMMAND_POOL:
> -            return (uint64_t) wine_cmd_pool_from_handle(handle)->command_pool;
> -        default:
> -            return handle;
> -    }
> -}
> -
>   VkResult WINAPI wine_vkSetPrivateDataEXT(VkDevice device, VkObjectType object_type, uint64_t object_handle,
>           VkPrivateDataSlotEXT private_data_slot, uint64_t data)
>   {
>       TRACE("%p, %#x, 0x%s, 0x%s, 0x%s\n", device, object_type, wine_dbgstr_longlong(object_handle),
>               wine_dbgstr_longlong(private_data_slot), wine_dbgstr_longlong(data));
>   
> -    object_handle = unwrap_object_handle(object_type, object_handle);
> +    object_handle = wine_vk_unwrap_handle(object_type, object_handle);
>       return device->funcs.p_vkSetPrivateDataEXT(device->device, object_type, object_handle, private_data_slot, data);
>   }
>   
> @@ -1567,7 +1550,7 @@ void WINAPI wine_vkGetPrivateDataEXT(VkDevice device, VkObjectType object_type,
>       TRACE("%p, %#x, 0x%s, 0x%s, %p\n", device, object_type, wine_dbgstr_longlong(object_handle),
>               wine_dbgstr_longlong(private_data_slot), data);
>   
> -    object_handle = unwrap_object_handle(object_type, object_handle);
> +    object_handle = wine_vk_unwrap_handle(object_type, object_handle);
>       device->funcs.p_vkGetPrivateDataEXT(device->device, object_type, object_handle, private_data_slot, data);
>   }
>   
> diff --git a/dlls/winevulkan/vulkan_private.h b/dlls/winevulkan/vulkan_private.h
> index 4bcc4de440d..bf09401c52a 100644
> --- a/dlls/winevulkan/vulkan_private.h
> +++ b/dlls/winevulkan/vulkan_private.h
> @@ -138,4 +138,7 @@ void *wine_vk_get_instance_proc_addr(const char *name) DECLSPEC_HIDDEN;
>   BOOL wine_vk_device_extension_supported(const char *name) DECLSPEC_HIDDEN;
>   BOOL wine_vk_instance_extension_supported(const char *name) DECLSPEC_HIDDEN;
>   
> +BOOL wine_vk_is_type_wrapped(VkObjectType type) DECLSPEC_HIDDEN;
> +uint64_t wine_vk_unwrap_handle(VkObjectType type, uint64_t handle) DECLSPEC_HIDDEN;
> +
>   #endif /* __WINE_VULKAN_PRIVATE_H */
> 



More information about the wine-devel mailing list