From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winevulkan/make_vulkan | 145 ++++++++++++++++++++---------------- 1 file changed, 82 insertions(+), 63 deletions(-)
diff --git a/dlls/winevulkan/make_vulkan b/dlls/winevulkan/make_vulkan index 5c7733c4e1d..7b3d107aa36 100755 --- a/dlls/winevulkan/make_vulkan +++ b/dlls/winevulkan/make_vulkan @@ -188,7 +188,7 @@ FUNCTION_OVERRIDES = { "vkGetInstanceProcAddr": {"dispatch" : False, "driver" : True, "thunk" : ThunkType.NONE, "loader_thunk" : ThunkType.NONE},
# Instance functions - "vkCreateDevice" : {"dispatch" : True, "driver" : False, "thunk" : ThunkType.NONE, "loader_thunk" : ThunkType.PRIVATE, "extra_param" : "client_ptr"}, + "vkCreateDevice" : {"dispatch" : True, "driver" : False, "thunk" : ThunkType.PRIVATE, "loader_thunk" : ThunkType.PRIVATE, "extra_param" : "client_ptr"}, "vkDestroyInstance" : {"dispatch" : False, "driver" : True, "thunk" : ThunkType.NONE, "loader_thunk" : ThunkType.PRIVATE}, "vkEnumerateDeviceExtensionProperties" : {"dispatch" : True, "driver" : False, "thunk" : ThunkType.NONE}, "vkEnumerateDeviceLayerProperties": {"dispatch": True, "driver": False, "thunk": ThunkType.NONE}, @@ -197,7 +197,7 @@ FUNCTION_OVERRIDES = { "vkGetPhysicalDeviceExternalBufferProperties" : {"dispatch" : False, "driver" : False, "thunk" : ThunkType.NONE}, "vkGetPhysicalDeviceExternalFenceProperties" : {"dispatch" : False, "driver" : False, "thunk" : ThunkType.NONE}, "vkGetPhysicalDeviceExternalSemaphoreProperties" : {"dispatch" : False, "driver" : False, "thunk" : ThunkType.NONE}, - "vkGetPhysicalDeviceImageFormatProperties2" : {"dispatch" : True, "driver" : False, "thunk" : ThunkType.PRIVATE}, + "vkGetPhysicalDeviceImageFormatProperties2" : {"dispatch" : True, "driver" : False, "thunk" : ThunkType.NONE}, "vkGetPhysicalDeviceProperties2" : {"dispatch" : True, "driver" : False, "thunk" : ThunkType.PUBLIC, "loader_thunk" : ThunkType.PRIVATE}, "vkGetPhysicalDeviceProperties2KHR" : {"dispatch" : True, "driver" : False, "thunk" : ThunkType.PUBLIC, "loader_thunk" : ThunkType.PRIVATE},
@@ -210,24 +210,24 @@ FUNCTION_OVERRIDES = { "vkGetDeviceProcAddr" : {"dispatch" : False, "driver" : True, "thunk" : ThunkType.NONE, "loader_thunk" : ThunkType.NONE}, "vkGetDeviceQueue" : {"dispatch": True, "driver" : False, "thunk" : ThunkType.NONE}, "vkGetDeviceQueue2" : {"dispatch": True, "driver" : False, "thunk" : ThunkType.NONE}, - "vkAllocateMemory" : {"dispatch" : True, "driver" : False, "thunk" : ThunkType.PRIVATE}, - "vkFreeMemory" : {"dispatch" : True, "driver" : False, "thunk" : ThunkType.PRIVATE}, - "vkMapMemory" : {"dispatch" : True, "driver" : False, "thunk" : ThunkType.PRIVATE}, - "vkMapMemory2KHR" : {"dispatch" : True, "driver" : False, "thunk" : ThunkType.PRIVATE}, - "vkUnmapMemory" : {"dispatch" : True, "driver" : False, "thunk" : ThunkType.PRIVATE}, - "vkUnmapMemory2KHR" : {"dispatch" : True, "driver" : False, "thunk" : ThunkType.PRIVATE}, - "vkCreateBuffer" : {"dispatch" : True, "driver" : False, "thunk" : ThunkType.PRIVATE}, - "vkCreateImage" : {"dispatch" : True, "driver" : False, "thunk" : ThunkType.PRIVATE}, + "vkAllocateMemory" : {"dispatch" : True, "driver" : False, "thunk" : ThunkType.NONE}, + "vkFreeMemory" : {"dispatch" : True, "driver" : False, "thunk" : ThunkType.NONE}, + "vkMapMemory" : {"dispatch" : True, "driver" : False, "thunk" : ThunkType.NONE}, + "vkMapMemory2KHR" : {"dispatch" : True, "driver" : False, "thunk" : ThunkType.NONE}, + "vkUnmapMemory" : {"dispatch" : True, "driver" : False, "thunk" : ThunkType.NONE}, + "vkUnmapMemory2KHR" : {"dispatch" : True, "driver" : False, "thunk" : ThunkType.NONE}, + "vkCreateBuffer" : {"dispatch" : True, "driver" : False, "thunk" : ThunkType.NONE}, + "vkCreateImage" : {"dispatch" : True, "driver" : False, "thunk" : ThunkType.NONE},
# VK_KHR_surface "vkDestroySurfaceKHR" : {"dispatch" : True, "driver" : True, "thunk" : ThunkType.NONE}, "vkGetPhysicalDeviceSurfaceSupportKHR" : {"dispatch" : True, "driver" : True, "thunk" : ThunkType.PUBLIC}, - "vkGetPhysicalDeviceSurfaceCapabilitiesKHR" : {"dispatch" : True, "driver" : True, "thunk" : ThunkType.PRIVATE}, + "vkGetPhysicalDeviceSurfaceCapabilitiesKHR" : {"dispatch" : True, "driver" : True, "thunk" : ThunkType.NONE}, "vkGetPhysicalDeviceSurfaceFormatsKHR" : {"dispatch" : True, "driver" : True, "thunk" : ThunkType.PUBLIC}, "vkGetPhysicalDeviceSurfacePresentModesKHR" : {"dispatch" : True, "driver" : True, "thunk" : ThunkType.PUBLIC},
# VK_KHR_get_surface_capabilities2 - "vkGetPhysicalDeviceSurfaceCapabilities2KHR" : {"dispatch" : True, "driver" : True, "thunk" : ThunkType.PRIVATE}, + "vkGetPhysicalDeviceSurfaceCapabilities2KHR" : {"dispatch" : True, "driver" : True, "thunk" : ThunkType.NONE}, "vkGetPhysicalDeviceSurfaceFormats2KHR" : {"dispatch" : True, "driver" : True, "thunk" : ThunkType.PUBLIC},
# VK_KHR_win32_surface @@ -245,7 +245,7 @@ FUNCTION_OVERRIDES = {
# VK_KHR_external_memory_capabilities "vkGetPhysicalDeviceExternalBufferPropertiesKHR" : {"dispatch" : False, "driver" : False, "thunk" : ThunkType.NONE}, - "vkGetPhysicalDeviceImageFormatProperties2KHR" : {"dispatch" : True, "driver" : False, "thunk" : ThunkType.PRIVATE}, + "vkGetPhysicalDeviceImageFormatProperties2KHR" : {"dispatch" : True, "driver" : False, "thunk" : ThunkType.NONE},
# VK_KHR_external_semaphore_capabilities "vkGetPhysicalDeviceExternalSemaphorePropertiesKHR" : {"dispatch" : False, "driver" : False, "thunk" : ThunkType.NONE}, @@ -305,17 +305,27 @@ class Direction(Enum): INPUT = 1 OUTPUT = 2
+ +class Unwrap(Enum): + NONE = 0 + HOST = 1 + + def api_is_vulkan(obj): return "vulkan" in obj.get("api", "vulkan").split(",")
-def convert_suffix(direction, win_type, unwrap): +def convert_suffix(direction, win_type, unwrap, is_wrapped): if direction == Direction.OUTPUT: - if not unwrap: + if not is_wrapped: + return "host_to_{0}".format(win_type) + if unwrap == Unwrap.NONE: return "unwrapped_host_to_{0}".format(win_type) return "host_to_{0}".format(win_type) else: - if not unwrap: + if not is_wrapped: + return "{0}_to_host".format(win_type) + if unwrap == Unwrap.NONE: return "{0}_to_unwrapped_host".format(win_type) return "{0}_to_host".format(win_type)
@@ -603,6 +613,11 @@ class VkFunction(object): # and is used by the code generation. self.required = True if func_info else False
+ if self.thunk_type == ThunkType.NONE: + self.unwrap = Unwrap.NONE + else: + self.unwrap = Unwrap.HOST + @staticmethod def from_alias(command, alias): """ Create VkFunction from an alias command. @@ -649,7 +664,7 @@ class VkFunction(object):
conversions = [] for param in self.params: - conversions.extend(param.get_conversions(self.thunk_type == ThunkType.PUBLIC)) + conversions.extend(param.get_conversions(self.unwrap)) return conversions
def is_alias(self): @@ -789,14 +804,14 @@ class VkFunction(object): body += " return params.result;\n" return body
- def body(self, conv, unwrap, params_prefix=""): + def body(self, conv, params_prefix=""): body = "" needs_alloc = False deferred_op = None
# Declare any tmp parameters for conversion. for p in self.params: - if p.needs_variable(conv, unwrap): + if p.needs_variable(conv, self.unwrap): if p.is_dynamic_array(): body += " {2}{0} *{1}_host;\n".format( p.type, p.name, "const " if p.is_const() else "") @@ -805,7 +820,7 @@ class VkFunction(object): needs_alloc = True else: body += " {0} {1}_host;\n".format(p.type, p.name) - if p.needs_alloc(conv, unwrap): + if p.needs_alloc(conv, self.unwrap): needs_alloc = True if p.type == "VkDeferredOperationKHR" and not p.is_pointer(): deferred_op = p.name @@ -834,24 +849,24 @@ class VkFunction(object): body += " ctx = &wine_deferred_operation_from_handle(params->{})->ctx;\n".format(deferred_op)
# Call any win_to_host conversion calls. - unwrap = self.thunk_type == ThunkType.PUBLIC for p in self.params: - if p.needs_conversion(conv, unwrap, Direction.INPUT): - body += p.copy(Direction.INPUT, conv, unwrap, prefix=params_prefix) - elif p.is_dynamic_array() and p.needs_conversion(conv, unwrap, Direction.OUTPUT): + if p.needs_conversion(conv, self.unwrap, Direction.INPUT): + body += p.copy(Direction.INPUT, conv, self.unwrap, prefix=params_prefix) + elif p.is_dynamic_array() and p.needs_conversion(conv, self.unwrap, Direction.OUTPUT): body += " {0}_host = ({2}{0} && {1}) ? conversion_context_alloc(ctx, sizeof(*{0}_host) * {1}) : NULL;\n".format( p.name, p.get_dyn_array_len(params_prefix, conv), params_prefix)
# Build list of parameters containing converted and non-converted parameters. # The param itself knows if conversion is needed and applies it when we set conv=True. - params = ", ".join([p.variable(conv=conv, unwrap=unwrap, params_prefix=params_prefix) for p in self.params]) + unwrap = Unwrap.NONE if self.thunk_type == ThunkType.PRIVATE else self.unwrap + params = ", ".join([p.variable(conv, unwrap, params_prefix) for p in self.params]) if self.extra_param: if conv: params += ", UlongToPtr({0}{1})".format(params_prefix, self.extra_param) else: params += ", {0}{1}".format(params_prefix, self.extra_param)
- if unwrap or self.thunk_type == ThunkType.PUBLIC: + if self.thunk_type == ThunkType.PUBLIC: func_prefix = "{0}.p_".format(self.params[0].dispatch_table(params_prefix, conv)) else: func_prefix = "wine_" @@ -864,8 +879,8 @@ class VkFunction(object):
# Call any host_to_win conversion calls. for p in self.params: - if p.needs_conversion(conv, unwrap, Direction.OUTPUT): - body += p.copy(Direction.OUTPUT, conv, unwrap, prefix=params_prefix) + if p.needs_conversion(conv, self.unwrap, Direction.OUTPUT): + body += p.copy(Direction.OUTPUT, conv, self.unwrap, prefix=params_prefix)
if needs_alloc: if deferred_op is not None: @@ -936,7 +951,7 @@ class VkFunction(object): thunk += " } *params = args;\n" else: thunk += " struct {0}_params *params = args;\n".format(self.name) - thunk += self.body(conv=conv, unwrap=self.thunk_type == ThunkType.PUBLIC, params_prefix="params->") + thunk += self.body(conv, params_prefix="params->") thunk += "}\n" if not conv: thunk += "#endif /* _WIN64 */\n" @@ -1161,8 +1176,11 @@ class VkHandle(object):
return self.host_handle(name)
- def is_wrapped(self): - return self.host_handle("test") is not None + def is_wrapped(self, unwrap): + if unwrap == Unwrap.HOST: + return self.host_handle("test") is not None + assert unwrap == Unwrap.NONE + return False
class VkVariable(object): @@ -1309,14 +1327,14 @@ class VkVariable(object): return not self.handle.is_dispatchable() return False
- def is_wrapped(self): + def is_wrapped(self, unwrap): """ Returns if variable needs unwrapping of handle. """
if self.is_struct(): - return self.struct.is_wrapped() + return self.struct.is_wrapped(unwrap)
if self.is_handle(): - return self.handle.is_wrapped() + return self.handle.is_wrapped(unwrap)
if self.is_generic_handle(): return True @@ -1492,7 +1510,7 @@ class VkMember(VkVariable): - `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 or not self.is_wrapped()) + suffix = convert_suffix(direction, win_type, unwrap, self.is_wrapped(Unwrap.HOST))
if self.needs_conversion(conv, unwrap, direction, False): if self.is_dynamic_array(): @@ -1514,7 +1532,7 @@ class VkMember(VkVariable): 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(): + elif self.is_handle() and self.is_wrapped(Unwrap.HOST): handle = self.type_info["data"] if direction == Direction.OUTPUT: LOGGER.err("OUTPUT parameter {0}.{1} cannot be unwrapped".format(self.type, self.name)) @@ -1522,7 +1540,8 @@ class VkMember(VkVariable): return "{0}{1} = {2} ? {3} : 0;\n".format(output, self.name, self.value(input, conv), handle.driver_handle(self.value(input, conv))) else: - return "{0}{1} = {2};\n".format(output, self.name, handle.driver_handle(self.value(input, conv))) + return "{0}{1} = {2};\n".format(output, self.name, + handle.driver_handle(self.value(input, conv))) elif self.is_generic_handle(): if direction == Direction.OUTPUT: LOGGER.err("OUTPUT parameter {0}.{1} cannot be unwrapped".format(self.type, self.name)) @@ -1531,7 +1550,8 @@ class VkMember(VkVariable): else: selector_part = ", {0}{1}".format(input, self.selector) if self.selector else "" if direction == Direction.OUTPUT: - return "convert_{0}_host_to_{4}(&{2}{1}, &{3}{1}{5});\n".format(self.type, self.name, input, output, win_type, selector_part) + return "convert_{0}_{4}(&{2}{1}, &{3}{1}{5});\n".format(self.type, + self.name, input, output, suffix, selector_part) 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, @@ -1618,12 +1638,12 @@ class VkMember(VkVariable): return True
if self.is_handle(): - if unwrap and self.handle.is_wrapped(): + if self.handle.is_wrapped(unwrap): return True if conv and self.handle.is_dispatchable(): return True elif self.is_generic_handle(): - if unwrap: + if unwrap != Unwrap.NONE: return True elif self.is_struct() or self.is_union(): if self.struct.needs_conversion(conv, unwrap, direction, is_const): @@ -1744,7 +1764,7 @@ class VkParam(VkVariable):
def copy(self, direction, conv, unwrap, prefix=""): win_type = "win32" if conv else "win64" - suffix = convert_suffix(direction, win_type, unwrap or not self.is_wrapped()) + suffix = convert_suffix(direction, win_type, unwrap, self.is_wrapped(Unwrap.HOST))
if direction == Direction.INPUT: ctx_param = "ctx, " if self.needs_alloc(conv, unwrap) else "" @@ -1852,7 +1872,7 @@ class VkParam(VkVariable): if direction != param_direction: return False
- if unwrap and self.handle.is_wrapped(): + if self.handle.is_wrapped(unwrap): return True if conv and self.handle.is_dispatchable(): return True @@ -1905,7 +1925,7 @@ class VkParam(VkVariable):
# Hack until we enable allocation callbacks from ICD to application. These are a joy # to enable one day, because of calling convention conversion. - if unwrap and "VkAllocationCallbacks" in self.type: + if unwrap != Unwrap.NONE and "VkAllocationCallbacks" in self.type: LOGGER.debug("TODO: setting NULL VkAllocationCallbacks for {0}".format(self.name)) return "NULL"
@@ -1917,7 +1937,7 @@ class VkParam(VkVariable):
p = self.value(params_prefix, conv)
- if unwrap: + if unwrap != Unwrap.NONE: unwrap_handle = None if self.object_type != None and self.type == "uint64_t": unwrap_handle = "wine_vk_unwrap_handle({0}{1}, {0}{2})".format( @@ -2108,17 +2128,17 @@ class VkStruct(Sequence): return True return False
- def is_wrapped(self): + def is_wrapped(self, unwrap): """ Returns if struct members need unwrapping of handle. """
for m in self.members: if self.name == m.type: continue - if m.is_wrapped(): + if m.is_wrapped(unwrap): return True return False
- def needs_extensions_conversion(self, conv, direction): + def needs_extensions_conversion(self, conv, unwrap, direction): """ Check if struct contains extensions chain that needs to be converted """
if direction == Direction.INPUT and self.name in STRUCT_CHAIN_CONVERSIONS: @@ -2135,12 +2155,12 @@ class VkStruct(Sequence): for e in self.struct_extensions: if not e.required: continue - if e.needs_conversion(conv, True, direction, is_const, check_extensions=False): + if e.needs_conversion(conv, unwrap, direction, is_const, check_extensions=False): return True if direction == Direction.INPUT: # we need input conversion of structs containing struct chain even if it's returnedonly, # so that we have a chance to allocate buffers - if e.needs_conversion(conv, True, Direction.OUTPUT, is_const, check_extensions=False): + if e.needs_conversion(conv, unwrap, Direction.OUTPUT, is_const, check_extensions=False): return True
return False @@ -2201,12 +2221,12 @@ class VkStruct(Sequence): if needs_output_copy and self.needs_conversion(conv, unwrap, Direction.INPUT, check_extensions): return True
- return check_extensions and self.needs_extensions_conversion(conv, direction) + return check_extensions and self.needs_extensions_conversion(conv, unwrap, direction)
def needs_alloc(self, conv, unwrap): """ Check if any struct member needs some memory allocation."""
- if self.needs_extensions_conversion(conv, Direction.INPUT): + if self.needs_extensions_conversion(conv, unwrap, Direction.INPUT): return True
for m in self.members: @@ -2248,7 +2268,7 @@ class VkStruct(Sequence): for e in self.struct_extensions: if not e.required: continue - conversions.extend(e.get_conversions(True, parent_const)) + conversions.extend(e.get_conversions(unwrap, parent_const))
# Collect any conversion for any member structs. for m in self: @@ -2265,12 +2285,12 @@ class StructConversionFunction(object): self.operand = struct self.type = struct.name self.conv = conv - self.unwrap = unwrap or not self.operand.is_wrapped() + self.unwrap = unwrap self.const = const
name = "convert_{0}_".format(self.type) win_type = "win32" if self.conv else "win64" - name += convert_suffix(self.direction, win_type, self.unwrap) + name += convert_suffix(direction, win_type, unwrap, struct.is_wrapped(Unwrap.HOST)) self.name = name
def __eq__(self, other): @@ -2340,7 +2360,7 @@ class StructConversionFunction(object): body += ", ".join(p for p in params) body += ")\n"
- needs_extensions = self.operand.needs_extensions_conversion(self.conv, self.direction) + needs_extensions = self.operand.needs_extensions_conversion(self.conv, self.unwrap, self.direction)
body += "{\n" if needs_extensions: @@ -2426,7 +2446,7 @@ class StructConversionFunction(object): copy_body += ident + "out_ext->pNext = NULL;\n" continue
- copy_body += ident + m.copy("in_ext->", "out_ext->", self.direction, self.conv, True) + copy_body += ident + m.copy("in_ext->", "out_ext->", self.direction, self.conv, self.unwrap)
# Generate the definition of "in_ext" if we need it if "in_ext->" in copy_body: @@ -2463,7 +2483,7 @@ class ArrayConversionFunction(object): self.direction = direction self.type = array.type self.conv = conv - self.unwrap = unwrap or not array.is_wrapped() + self.unwrap = unwrap
if array.is_static_array() and direction == Direction.INPUT: LOGGER.error("Static array input conversion is not supported") @@ -2473,7 +2493,7 @@ class ArrayConversionFunction(object): name += "pointer_" name += "array_" win_type = "win32" if self.conv else "win64" - name += convert_suffix(self.direction, win_type, self.unwrap) + name += convert_suffix(direction, win_type, unwrap, array.is_wrapped(Unwrap.HOST)) self.name = name
def __eq__(self, other): @@ -2544,8 +2564,7 @@ class ArrayConversionFunction(object): if self.array.is_struct(): struct = self.array.struct win_part = "win32" if self.conv else "win64" - suffix = convert_suffix(self.direction, win_part, self.unwrap) - + suffix = convert_suffix(self.direction, win_part, self.unwrap, struct.is_wrapped(Unwrap.HOST)) ctx_part = "" if self.direction == Direction.INPUT and struct.needs_alloc(self.conv, self.unwrap): ctx_part = "ctx, " @@ -2580,7 +2599,7 @@ class ArrayConversionFunction(object): else: input = "PtrToUlong(in[i])"
- if not self.unwrap or not handle.is_wrapped(): + if self.unwrap == Unwrap.NONE or not handle.is_wrapped(Unwrap.HOST): body += " out[i] = {0};\n".format(input) elif self.direction == Direction.INPUT: body += " out[i] = " + handle.driver_handle(input) + ";\n" @@ -2673,7 +2692,7 @@ class VkGenerator(object): 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(): + if not handle.is_required() or not handle.is_wrapped(Unwrap.HOST) or handle.is_alias(): continue f.write(" case {}:\n".format(handle.object_type)) if handle.is_dispatchable(): @@ -2751,7 +2770,7 @@ class VkGenerator(object): 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(): + if not handle.is_required() or not handle.is_wrapped(Unwrap.HOST) or handle.is_alias(): continue f.write(" ||\n type == {}".format(handle.object_type)) f.write(";\n")