Split from https://gitlab.winehq.org/wine/wine/-/merge_requests/4572
When there's driver wrappers the handles are always unwrapped to driver handles, including for functions which don't have a driver entry point. This fixes that and unwrap to host / driver depending on the functions. Extension chains are still always unwrapped to host handles for now.
I have pushed some sample change to wrap swapchain handles in https://gitlab.winehq.org/rbernon/wine/-/commit/3181c3adbb3abd5967e947dfd42e... and https://gitlab.winehq.org/rbernon/wine/-/commit/00220d8b80d0d39ce003232f47ab..., without the last change in this MR they would look like https://gitlab.winehq.org/rbernon/wine/-/commit/470b67c514028983b23d3118377b... and https://gitlab.winehq.org/rbernon/wine/-/commit/122980f2b04a60661533599b513e... respectively.
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winevulkan/make_vulkan | 67 ++++++++++++++++++++++++------------- 1 file changed, 43 insertions(+), 24 deletions(-)
diff --git a/dlls/winevulkan/make_vulkan b/dlls/winevulkan/make_vulkan index e345c0d3287..aadde48872b 100755 --- a/dlls/winevulkan/make_vulkan +++ b/dlls/winevulkan/make_vulkan @@ -177,18 +177,17 @@ class ThunkType(Enum): # - PUBLIC means the implementation is fully auto generated. # - PRIVATE thunks can be used in custom implementations for # struct conversion. -# - loader_thunk (default: ThunkType.PUBLIC): sets whether to create a thunk for unix funcs. FUNCTION_OVERRIDES = { # Global functions - "vkCreateInstance" : {"driver" : True, "thunk" : ThunkType.NONE, "loader_thunk" : ThunkType.PRIVATE, "extra_param" : "client_ptr"}, - "vkEnumerateInstanceExtensionProperties" : {"driver" : True, "thunk" : ThunkType.NONE, "loader_thunk" : ThunkType.PRIVATE}, - "vkEnumerateInstanceLayerProperties" : {"thunk" : ThunkType.NONE, "loader_thunk" : ThunkType.NONE}, - "vkEnumerateInstanceVersion" : {"thunk" : ThunkType.NONE, "loader_thunk" : ThunkType.PRIVATE}, - "vkGetInstanceProcAddr" : {"driver" : True, "thunk" : ThunkType.NONE, "loader_thunk" : ThunkType.NONE}, + "vkCreateInstance" : {"driver" : True, "thunk" : ThunkType.NONE, "extra_param" : "client_ptr"}, + "vkEnumerateInstanceExtensionProperties" : {"driver" : True, "thunk" : ThunkType.NONE}, + "vkEnumerateInstanceLayerProperties" : {"thunk" : ThunkType.NONE}, + "vkEnumerateInstanceVersion" : {"thunk" : ThunkType.NONE}, + "vkGetInstanceProcAddr" : {"driver" : True, "thunk" : ThunkType.NONE},
# Instance functions - "vkCreateDevice" : {"thunk" : ThunkType.NONE, "loader_thunk" : ThunkType.PRIVATE, "extra_param" : "client_ptr"}, - "vkDestroyInstance" : {"dispatch" : False, "driver" : True, "thunk" : ThunkType.NONE, "loader_thunk" : ThunkType.PRIVATE}, + "vkCreateDevice" : {"thunk" : ThunkType.NONE, "extra_param" : "client_ptr"}, + "vkDestroyInstance" : {"dispatch" : False, "driver" : True, "thunk" : ThunkType.NONE}, "vkEnumerateDeviceExtensionProperties" : {"thunk" : ThunkType.NONE}, "vkEnumerateDeviceLayerProperties" : {"thunk" : ThunkType.NONE}, "vkEnumeratePhysicalDeviceGroups" : {"thunk" : ThunkType.NONE}, @@ -197,16 +196,14 @@ FUNCTION_OVERRIDES = { "vkGetPhysicalDeviceExternalFenceProperties" : {"dispatch" : False, "thunk" : ThunkType.NONE}, "vkGetPhysicalDeviceExternalSemaphoreProperties" : {"dispatch" : False, "thunk" : ThunkType.NONE}, "vkGetPhysicalDeviceImageFormatProperties2" : {"thunk" : ThunkType.PRIVATE}, - "vkGetPhysicalDeviceProperties2" : {"loader_thunk" : ThunkType.PRIVATE}, - "vkGetPhysicalDeviceProperties2KHR" : {"loader_thunk" : ThunkType.PRIVATE},
# Device functions - "vkAllocateCommandBuffers" : {"thunk" : ThunkType.NONE, "loader_thunk" : ThunkType.PRIVATE}, - "vkCreateCommandPool" : {"thunk" : ThunkType.NONE, "loader_thunk" : ThunkType.PRIVATE, "extra_param" : "client_ptr"}, - "vkDestroyCommandPool" : {"thunk" : ThunkType.NONE, "loader_thunk" : ThunkType.PRIVATE}, - "vkDestroyDevice" : {"thunk" : ThunkType.NONE, "loader_thunk" : ThunkType.PRIVATE}, - "vkFreeCommandBuffers" : {"thunk" : ThunkType.NONE, "loader_thunk" : ThunkType.PRIVATE}, - "vkGetDeviceProcAddr" : {"dispatch" : False, "driver" : True, "thunk" : ThunkType.NONE, "loader_thunk" : ThunkType.NONE}, + "vkAllocateCommandBuffers" : {"thunk" : ThunkType.NONE}, + "vkCreateCommandPool" : {"thunk" : ThunkType.NONE, "extra_param" : "client_ptr"}, + "vkDestroyCommandPool" : {"thunk" : ThunkType.NONE}, + "vkDestroyDevice" : {"thunk" : ThunkType.NONE}, + "vkFreeCommandBuffers" : {"thunk" : ThunkType.NONE}, + "vkGetDeviceProcAddr" : {"dispatch" : False, "driver" : True, "thunk" : ThunkType.NONE}, "vkGetDeviceQueue" : {"thunk" : ThunkType.NONE}, "vkGetDeviceQueue2" : {"thunk" : ThunkType.NONE}, "vkAllocateMemory" : {"thunk" : ThunkType.PRIVATE}, @@ -273,6 +270,29 @@ FUNCTION_OVERRIDES = { "vkDestroyDebugReportCallbackEXT" : {"thunk" : ThunkType.NONE}, }
+# loader functions which are entirely manually implemented +MANUAL_LOADER_FUNCTIONS = { + "vkEnumerateInstanceLayerProperties", + "vkGetDeviceProcAddr", + "vkGetInstanceProcAddr", +} + +# functions which loader thunks are manually implemented +MANUAL_LOADER_THUNKS = { + "vkAllocateCommandBuffers", + "vkCreateCommandPool", + "vkCreateDevice", + "vkCreateInstance", + "vkDestroyCommandPool", + "vkDestroyDevice", + "vkDestroyInstance", + "vkEnumerateInstanceExtensionProperties", + "vkEnumerateInstanceVersion", + "vkFreeCommandBuffers", + "vkGetPhysicalDeviceProperties2", + "vkGetPhysicalDeviceProperties2KHR", +} + STRUCT_CHAIN_CONVERSIONS = { # Ignore to not confuse host loader. "VkDeviceCreateInfo": ["VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO"], @@ -583,7 +603,6 @@ class VkFunction(object): self.dispatch = func_info.get("dispatch", True) self.driver = func_info.get("driver", False) self.thunk_type = func_info.get("thunk", ThunkType.PUBLIC) - self.loader_thunk_type = func_info.get("loader_thunk", ThunkType.PUBLIC) self.extra_param = func_info.get("extra_param", None)
# Required is set while parsing which APIs and types are required @@ -693,7 +712,7 @@ class VkFunction(object): return self.dispatch
def needs_private_thunk(self): - return self.needs_exposing() and self.loader_thunk_type != ThunkType.NONE and \ + return self.needs_exposing() and self.name not in MANUAL_LOADER_FUNCTIONS and \ self.thunk_type != ThunkType.PUBLIC
def needs_exposing(self): @@ -2700,7 +2719,7 @@ class VkGenerator(object): for vk_func in self.registry.funcs.values(): if not vk_func.needs_exposing(): continue - if vk_func.loader_thunk_type == ThunkType.NONE: + if vk_func.name in MANUAL_LOADER_FUNCTIONS: continue
f.write(vk_func.thunk(prefix="thunk64_")) @@ -2771,7 +2790,7 @@ class VkGenerator(object): for vk_func in self.registry.funcs.values(): if not vk_func.needs_exposing(): continue - if vk_func.loader_thunk_type == ThunkType.NONE: + if vk_func.name in MANUAL_LOADER_FUNCTIONS: continue
if vk_func.is_perf_critical(): @@ -2795,7 +2814,7 @@ class VkGenerator(object): for vk_func in self.registry.funcs.values(): if not vk_func.needs_exposing(): continue - if vk_func.loader_thunk_type == ThunkType.NONE: + if vk_func.name in MANUAL_LOADER_FUNCTIONS: continue
if vk_func.is_perf_critical(): @@ -2894,7 +2913,7 @@ class VkGenerator(object): for vk_func in self.registry.funcs.values(): if not vk_func.needs_exposing(): continue - if vk_func.loader_thunk_type != ThunkType.PUBLIC: + if vk_func.name in MANUAL_LOADER_THUNKS | MANUAL_LOADER_FUNCTIONS: continue
f.write(vk_func.loader_thunk()) @@ -2979,7 +2998,7 @@ class VkGenerator(object): for vk_func in self.registry.funcs.values(): if not vk_func.needs_exposing(): continue - if vk_func.loader_thunk_type == ThunkType.NONE: + if vk_func.name in MANUAL_LOADER_FUNCTIONS: continue
f.write(" unix_{0},\n".format(vk_func.name)) @@ -2989,7 +3008,7 @@ class VkGenerator(object): for vk_func in self.registry.funcs.values(): if not vk_func.needs_exposing(): continue - if vk_func.loader_thunk_type == ThunkType.NONE: + if vk_func.name in MANUAL_LOADER_FUNCTIONS: continue
f.write("struct {0}_params\n".format(vk_func.name))
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winevulkan/make_vulkan | 154 ++++++++++++++++++------------------ 1 file changed, 77 insertions(+), 77 deletions(-)
diff --git a/dlls/winevulkan/make_vulkan b/dlls/winevulkan/make_vulkan index aadde48872b..4c5e92ea456 100755 --- a/dlls/winevulkan/make_vulkan +++ b/dlls/winevulkan/make_vulkan @@ -161,73 +161,42 @@ PERF_CRITICAL_FUNCTIONS = [ # in FUNCTION_OVERRIDES DRIVER_VERSION = 11
-class ThunkType(Enum): - NONE = 1 - PUBLIC = 2 - PRIVATE = 3 - # Table of functions for which we have a special implementation. # These are regular device / instance functions for which we need # to do more work compared to a regular thunk or because they are # part of the driver interface. # - dispatch (default: True): set whether we need a function pointer in the device / instance dispatch table. # - driver (default: False): sets whether the API is part of the driver interface. -# - thunk (default: ThunkType.PUBLIC): sets whether to create a thunk in vulkan_thunks.c. -# - NONE means there's a fully custom implementation. -# - PUBLIC means the implementation is fully auto generated. -# - PRIVATE thunks can be used in custom implementations for -# struct conversion. FUNCTION_OVERRIDES = { # Global functions - "vkCreateInstance" : {"driver" : True, "thunk" : ThunkType.NONE, "extra_param" : "client_ptr"}, - "vkEnumerateInstanceExtensionProperties" : {"driver" : True, "thunk" : ThunkType.NONE}, - "vkEnumerateInstanceLayerProperties" : {"thunk" : ThunkType.NONE}, - "vkEnumerateInstanceVersion" : {"thunk" : ThunkType.NONE}, - "vkGetInstanceProcAddr" : {"driver" : True, "thunk" : ThunkType.NONE}, + "vkCreateInstance" : {"driver" : True, "extra_param" : "client_ptr"}, + "vkEnumerateInstanceExtensionProperties" : {"driver" : True}, + "vkGetInstanceProcAddr" : {"driver" : True},
# Instance functions - "vkCreateDevice" : {"thunk" : ThunkType.NONE, "extra_param" : "client_ptr"}, - "vkDestroyInstance" : {"dispatch" : False, "driver" : True, "thunk" : ThunkType.NONE}, - "vkEnumerateDeviceExtensionProperties" : {"thunk" : ThunkType.NONE}, - "vkEnumerateDeviceLayerProperties" : {"thunk" : ThunkType.NONE}, - "vkEnumeratePhysicalDeviceGroups" : {"thunk" : ThunkType.NONE}, - "vkEnumeratePhysicalDevices" : {"thunk" : ThunkType.NONE}, - "vkGetPhysicalDeviceExternalBufferProperties" : {"dispatch" : False, "thunk" : ThunkType.NONE}, - "vkGetPhysicalDeviceExternalFenceProperties" : {"dispatch" : False, "thunk" : ThunkType.NONE}, - "vkGetPhysicalDeviceExternalSemaphoreProperties" : {"dispatch" : False, "thunk" : ThunkType.NONE}, - "vkGetPhysicalDeviceImageFormatProperties2" : {"thunk" : ThunkType.PRIVATE}, + "vkCreateDevice" : {"extra_param" : "client_ptr"}, + "vkDestroyInstance" : {"dispatch" : False, "driver" : True}, + "vkGetPhysicalDeviceExternalBufferProperties" : {"dispatch" : False}, + "vkGetPhysicalDeviceExternalFenceProperties" : {"dispatch" : False}, + "vkGetPhysicalDeviceExternalSemaphoreProperties" : {"dispatch" : False},
# Device functions - "vkAllocateCommandBuffers" : {"thunk" : ThunkType.NONE}, - "vkCreateCommandPool" : {"thunk" : ThunkType.NONE, "extra_param" : "client_ptr"}, - "vkDestroyCommandPool" : {"thunk" : ThunkType.NONE}, - "vkDestroyDevice" : {"thunk" : ThunkType.NONE}, - "vkFreeCommandBuffers" : {"thunk" : ThunkType.NONE}, - "vkGetDeviceProcAddr" : {"dispatch" : False, "driver" : True, "thunk" : ThunkType.NONE}, - "vkGetDeviceQueue" : {"thunk" : ThunkType.NONE}, - "vkGetDeviceQueue2" : {"thunk" : ThunkType.NONE}, - "vkAllocateMemory" : {"thunk" : ThunkType.PRIVATE}, - "vkFreeMemory" : {"thunk" : ThunkType.PRIVATE}, - "vkMapMemory" : {"thunk" : ThunkType.PRIVATE}, - "vkMapMemory2KHR" : {"thunk" : ThunkType.PRIVATE}, - "vkUnmapMemory" : {"thunk" : ThunkType.PRIVATE}, - "vkUnmapMemory2KHR" : {"thunk" : ThunkType.PRIVATE}, - "vkCreateBuffer" : {"thunk" : ThunkType.PRIVATE}, - "vkCreateImage" : {"thunk" : ThunkType.PRIVATE}, + "vkCreateCommandPool" : {"extra_param" : "client_ptr"}, + "vkGetDeviceProcAddr" : {"dispatch" : False, "driver" : True},
# VK_KHR_surface - "vkDestroySurfaceKHR" : {"driver" : True, "thunk" : ThunkType.NONE}, + "vkDestroySurfaceKHR" : {"driver" : True}, "vkGetPhysicalDeviceSurfaceSupportKHR" : {"driver" : True}, - "vkGetPhysicalDeviceSurfaceCapabilitiesKHR" : {"driver" : True, "thunk" : ThunkType.PRIVATE}, + "vkGetPhysicalDeviceSurfaceCapabilitiesKHR" : {"driver" : True}, "vkGetPhysicalDeviceSurfaceFormatsKHR" : {"driver" : True}, "vkGetPhysicalDeviceSurfacePresentModesKHR" : {"driver" : True},
# VK_KHR_get_surface_capabilities2 - "vkGetPhysicalDeviceSurfaceCapabilities2KHR" : {"driver" : True, "thunk" : ThunkType.PRIVATE}, + "vkGetPhysicalDeviceSurfaceCapabilities2KHR" : {"driver" : True}, "vkGetPhysicalDeviceSurfaceFormats2KHR" : {"driver" : True},
# VK_KHR_win32_surface - "vkCreateWin32SurfaceKHR" : {"driver" : True, "thunk" : ThunkType.NONE}, + "vkCreateWin32SurfaceKHR" : {"driver" : True}, "vkGetPhysicalDeviceWin32PresentationSupportKHR" : {"driver" : True},
# VK_KHR_swapchain @@ -237,37 +206,69 @@ FUNCTION_OVERRIDES = { "vkQueuePresentKHR" : {"driver" : True},
# VK_KHR_external_fence_capabilities - "vkGetPhysicalDeviceExternalFencePropertiesKHR" : {"dispatch" : False, "thunk" : ThunkType.NONE}, + "vkGetPhysicalDeviceExternalFencePropertiesKHR" : {"dispatch" : False},
# VK_KHR_external_memory_capabilities - "vkGetPhysicalDeviceExternalBufferPropertiesKHR" : {"dispatch" : False, "thunk" : ThunkType.NONE}, - "vkGetPhysicalDeviceImageFormatProperties2KHR" : {"thunk" : ThunkType.PRIVATE}, + "vkGetPhysicalDeviceExternalBufferPropertiesKHR" : {"dispatch" : False},
# VK_KHR_external_semaphore_capabilities - "vkGetPhysicalDeviceExternalSemaphorePropertiesKHR" : {"dispatch" : False, "thunk" : ThunkType.NONE}, - - # VK_KHR_device_group_creation - "vkEnumeratePhysicalDeviceGroupsKHR" : {"thunk" : ThunkType.NONE}, + "vkGetPhysicalDeviceExternalSemaphorePropertiesKHR" : {"dispatch" : False},
# VK_KHR_device_group "vkGetDeviceGroupSurfacePresentModesKHR" : {"driver" : True}, "vkGetPhysicalDevicePresentRectanglesKHR" : {"driver" : True}, +}
- # VK_KHR_deferred_host_operations - "vkCreateDeferredOperationKHR" : {"thunk" : ThunkType.NONE}, - "vkDestroyDeferredOperationKHR" : {"thunk" : ThunkType.NONE}, - - # VK_EXT_calibrated_timestamps - "vkGetPhysicalDeviceCalibrateableTimeDomainsEXT" : {"thunk" : ThunkType.NONE}, - "vkGetCalibratedTimestampsEXT" : {"thunk" : ThunkType.NONE}, - - # VK_EXT_debug_utils - "vkCreateDebugUtilsMessengerEXT" : {"thunk" : ThunkType.NONE}, - "vkDestroyDebugUtilsMessengerEXT" : {"thunk" : ThunkType.NONE}, - - # VK_EXT_debug_report - "vkCreateDebugReportCallbackEXT" : {"thunk" : ThunkType.NONE}, - "vkDestroyDebugReportCallbackEXT" : {"thunk" : ThunkType.NONE}, +# functions for which the unix thunk is manually implemented +MANUAL_UNIX_THUNKS = { + "vkAllocateCommandBuffers", + "vkAllocateMemory", + "vkCreateBuffer", + "vkCreateCommandPool", + "vkCreateDebugReportCallbackEXT", + "vkCreateDebugUtilsMessengerEXT", + "vkCreateDeferredOperationKHR", + "vkCreateDevice", + "vkCreateImage", + "vkCreateInstance", + "vkCreateWin32SurfaceKHR", + "vkDestroyCommandPool", + "vkDestroyDebugReportCallbackEXT", + "vkDestroyDebugUtilsMessengerEXT", + "vkDestroyDeferredOperationKHR", + "vkDestroyDevice", + "vkDestroyInstance", + "vkDestroySurfaceKHR", + "vkEnumerateDeviceExtensionProperties", + "vkEnumerateDeviceLayerProperties", + "vkEnumerateInstanceExtensionProperties", + "vkEnumerateInstanceLayerProperties", + "vkEnumerateInstanceVersion", + "vkEnumeratePhysicalDeviceGroups", + "vkEnumeratePhysicalDeviceGroupsKHR", + "vkEnumeratePhysicalDevices", + "vkFreeCommandBuffers", + "vkFreeMemory", + "vkGetCalibratedTimestampsEXT", + "vkGetDeviceProcAddr", + "vkGetDeviceQueue", + "vkGetDeviceQueue2", + "vkGetInstanceProcAddr", + "vkGetPhysicalDeviceCalibrateableTimeDomainsEXT", + "vkGetPhysicalDeviceExternalBufferProperties", + "vkGetPhysicalDeviceExternalBufferPropertiesKHR", + "vkGetPhysicalDeviceExternalFenceProperties", + "vkGetPhysicalDeviceExternalFencePropertiesKHR", + "vkGetPhysicalDeviceExternalSemaphoreProperties", + "vkGetPhysicalDeviceExternalSemaphorePropertiesKHR", + "vkGetPhysicalDeviceImageFormatProperties2", + "vkGetPhysicalDeviceImageFormatProperties2KHR", + "vkGetPhysicalDeviceSurfaceCapabilities2KHR", + "vkGetPhysicalDeviceSurfaceCapabilitiesKHR", + "vkMapMemory", + "vkMapMemory2KHR", + "vkUnmapMemory", + "vkUnmapMemory2KHR", }
# loader functions which are entirely manually implemented @@ -602,7 +603,6 @@ class VkFunction(object): func_info = FUNCTION_OVERRIDES.get(self.name, {}) self.dispatch = func_info.get("dispatch", True) self.driver = func_info.get("driver", False) - self.thunk_type = func_info.get("thunk", ThunkType.PUBLIC) self.extra_param = func_info.get("extra_param", None)
# Required is set while parsing which APIs and types are required @@ -655,7 +655,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(unwrap=self.name not in MANUAL_UNIX_THUNKS)) return conversions
def is_alias(self): @@ -713,7 +713,7 @@ class VkFunction(object):
def needs_private_thunk(self): return self.needs_exposing() and self.name not in MANUAL_LOADER_FUNCTIONS and \ - self.thunk_type != ThunkType.PUBLIC + self.name in MANUAL_UNIX_THUNKS
def needs_exposing(self): # The function needs exposed if at-least one extension isn't both UNSUPPORTED and UNEXPOSED @@ -840,24 +840,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 + unwrap = self.name not in MANUAL_UNIX_THUNKS for p in self.params: - if p.needs_conversion(conv, unwrap, Direction.INPUT): + if p.needs_conversion(conv, unwrap, direction=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): + elif p.is_dynamic_array() and p.needs_conversion(conv, unwrap, direction=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]) + params = ", ".join([p.variable(conv, unwrap, params_prefix=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.name not in MANUAL_UNIX_THUNKS: func_prefix = "{0}.p_".format(self.params[0].dispatch_table(params_prefix, conv)) else: func_prefix = "wine_" @@ -870,7 +870,7 @@ class VkFunction(object):
# Call any host_to_win conversion calls. for p in self.params: - if p.needs_conversion(conv, unwrap, Direction.OUTPUT): + if p.needs_conversion(conv, unwrap, direction=Direction.OUTPUT): body += p.copy(Direction.OUTPUT, conv, unwrap, prefix=params_prefix)
if needs_alloc: @@ -942,7 +942,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=conv, unwrap=self.name not in MANUAL_UNIX_THUNKS, params_prefix="params->") thunk += "}\n" if not conv: thunk += "#endif /* _WIN64 */\n"
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winevulkan/make_vulkan | 59 +++++++++++++++++-------------------- 1 file changed, 27 insertions(+), 32 deletions(-)
diff --git a/dlls/winevulkan/make_vulkan b/dlls/winevulkan/make_vulkan index 4c5e92ea456..06281aaf9ed 100755 --- a/dlls/winevulkan/make_vulkan +++ b/dlls/winevulkan/make_vulkan @@ -166,44 +166,20 @@ DRIVER_VERSION = 11 # to do more work compared to a regular thunk or because they are # part of the driver interface. # - dispatch (default: True): set whether we need a function pointer in the device / instance dispatch table. -# - driver (default: False): sets whether the API is part of the driver interface. FUNCTION_OVERRIDES = { # Global functions - "vkCreateInstance" : {"driver" : True, "extra_param" : "client_ptr"}, - "vkEnumerateInstanceExtensionProperties" : {"driver" : True}, - "vkGetInstanceProcAddr" : {"driver" : True}, + "vkCreateInstance" : {"extra_param" : "client_ptr"},
# Instance functions "vkCreateDevice" : {"extra_param" : "client_ptr"}, - "vkDestroyInstance" : {"dispatch" : False, "driver" : True}, + "vkDestroyInstance" : {"dispatch" : False}, "vkGetPhysicalDeviceExternalBufferProperties" : {"dispatch" : False}, "vkGetPhysicalDeviceExternalFenceProperties" : {"dispatch" : False}, "vkGetPhysicalDeviceExternalSemaphoreProperties" : {"dispatch" : False},
# Device functions "vkCreateCommandPool" : {"extra_param" : "client_ptr"}, - "vkGetDeviceProcAddr" : {"dispatch" : False, "driver" : True}, - - # VK_KHR_surface - "vkDestroySurfaceKHR" : {"driver" : True}, - "vkGetPhysicalDeviceSurfaceSupportKHR" : {"driver" : True}, - "vkGetPhysicalDeviceSurfaceCapabilitiesKHR" : {"driver" : True}, - "vkGetPhysicalDeviceSurfaceFormatsKHR" : {"driver" : True}, - "vkGetPhysicalDeviceSurfacePresentModesKHR" : {"driver" : True}, - - # VK_KHR_get_surface_capabilities2 - "vkGetPhysicalDeviceSurfaceCapabilities2KHR" : {"driver" : True}, - "vkGetPhysicalDeviceSurfaceFormats2KHR" : {"driver" : True}, - - # VK_KHR_win32_surface - "vkCreateWin32SurfaceKHR" : {"driver" : True}, - "vkGetPhysicalDeviceWin32PresentationSupportKHR" : {"driver" : True}, - - # VK_KHR_swapchain - "vkCreateSwapchainKHR" : {"driver" : True}, - "vkDestroySwapchainKHR" : {"driver" : True}, - "vkGetSwapchainImagesKHR" : {"driver" : True}, - "vkQueuePresentKHR" : {"driver" : True}, + "vkGetDeviceProcAddr" : {"dispatch" : False},
# VK_KHR_external_fence_capabilities "vkGetPhysicalDeviceExternalFencePropertiesKHR" : {"dispatch" : False}, @@ -213,10 +189,30 @@ FUNCTION_OVERRIDES = {
# VK_KHR_external_semaphore_capabilities "vkGetPhysicalDeviceExternalSemaphorePropertiesKHR" : {"dispatch" : False}, +}
- # VK_KHR_device_group - "vkGetDeviceGroupSurfacePresentModesKHR" : {"driver" : True}, - "vkGetPhysicalDevicePresentRectanglesKHR" : {"driver" : True}, +# functions for which a user driver entry must be generated +USER_DRIVER_FUNCS = { + "vkCreateInstance", + "vkCreateSwapchainKHR", + "vkCreateWin32SurfaceKHR", + "vkDestroyInstance", + "vkDestroySurfaceKHR", + "vkDestroySwapchainKHR", + "vkEnumerateInstanceExtensionProperties", + "vkGetDeviceGroupSurfacePresentModesKHR", + "vkGetDeviceProcAddr", + "vkGetInstanceProcAddr", + "vkGetPhysicalDevicePresentRectanglesKHR", + "vkGetPhysicalDeviceSurfaceCapabilities2KHR", + "vkGetPhysicalDeviceSurfaceCapabilitiesKHR", + "vkGetPhysicalDeviceSurfaceFormats2KHR", + "vkGetPhysicalDeviceSurfaceFormatsKHR", + "vkGetPhysicalDeviceSurfacePresentModesKHR", + "vkGetPhysicalDeviceSurfaceSupportKHR", + "vkGetPhysicalDeviceWin32PresentationSupportKHR", + "vkGetSwapchainImagesKHR", + "vkQueuePresentKHR", }
# functions for which the unix thunk is manually implemented @@ -602,7 +598,6 @@ class VkFunction(object): # For some functions we need some extra metadata from FUNCTION_OVERRIDES. func_info = FUNCTION_OVERRIDES.get(self.name, {}) self.dispatch = func_info.get("dispatch", True) - self.driver = func_info.get("driver", False) self.extra_param = func_info.get("extra_param", None)
# Required is set while parsing which APIs and types are required @@ -678,7 +673,7 @@ class VkFunction(object):
def is_driver_func(self): """ Returns if function is part of Wine driver interface. """ - return self.driver + return self.name in USER_DRIVER_FUNCS
def is_global_func(self): # Treat vkGetInstanceProcAddr as a global function as it
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winevulkan/make_vulkan | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-)
diff --git a/dlls/winevulkan/make_vulkan b/dlls/winevulkan/make_vulkan index 06281aaf9ed..68cdc2baef1 100755 --- a/dlls/winevulkan/make_vulkan +++ b/dlls/winevulkan/make_vulkan @@ -1165,8 +1165,6 @@ class VkHandle(object): def is_wrapped(self): return self.host_handle("test") is not None
- def needs_unwrapping(self): - return self.is_wrapped()
class VkVariable(object): def __init__(self, const=False, type_info=None, type=None, name=None, pointer=None, array_len=None, @@ -1312,14 +1310,14 @@ class VkVariable(object): return not self.handle.is_dispatchable() return False
- def needs_unwrapping(self): + def is_wrapped(self): """ Returns if variable needs unwrapping of handle. """
if self.is_struct(): - return self.struct.needs_unwrapping() + return self.struct.is_wrapped()
if self.is_handle(): - return self.handle.needs_unwrapping() + return self.handle.is_wrapped()
if self.is_generic_handle(): return True @@ -1519,7 +1517,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.needs_unwrapping(): + elif self.is_handle() and self.is_wrapped(): handle = self.type_info["data"] if direction == Direction.OUTPUT: LOGGER.err("OUTPUT parameter {0}.{1} cannot be unwrapped".format(self.type, self.name)) @@ -1749,7 +1747,7 @@ class VkParam(VkVariable):
def copy(self, direction, conv, unwrap, prefix=""): win_type = "win32" if conv else "win64" - wrap_part = "" if unwrap or not self.needs_unwrapping() else "unwrapped_" + wrap_part = "" if unwrap or not self.is_wrapped() else "unwrapped_" if direction == Direction.INPUT: ctx_param = "ctx, " if self.needs_alloc(conv, unwrap) else "" if self.is_dynamic_array(): @@ -2113,13 +2111,13 @@ class VkStruct(Sequence): return True return False
- def needs_unwrapping(self): + def is_wrapped(self): """ Returns if struct members need unwrapping of handle. """
for m in self.members: if self.name == m.type: continue - if m.needs_unwrapping(): + if m.is_wrapped(): return True return False
@@ -2270,7 +2268,7 @@ class StructConversionFunction(object): self.operand = struct self.type = struct.name self.conv = conv - self.unwrap = unwrap or not self.operand.needs_unwrapping() + self.unwrap = unwrap or not self.operand.is_wrapped() self.const = const
name = "convert_{0}_".format(self.type) @@ -2472,7 +2470,7 @@ class ArrayConversionFunction(object): self.direction = direction self.type = array.type self.conv = conv - self.unwrap = unwrap or not array.needs_unwrapping() + self.unwrap = unwrap or not array.is_wrapped()
if array.is_static_array() and direction == Direction.INPUT: LOGGER.error("Static array input conversion is not supported")
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winevulkan/make_vulkan | 80 ++++++++++++++++++------------------- 1 file changed, 39 insertions(+), 41 deletions(-)
diff --git a/dlls/winevulkan/make_vulkan b/dlls/winevulkan/make_vulkan index 68cdc2baef1..7e1cc3f1dd9 100755 --- a/dlls/winevulkan/make_vulkan +++ b/dlls/winevulkan/make_vulkan @@ -324,6 +324,18 @@ class Direction(Enum): def api_is_vulkan(obj): return "vulkan" in obj.get("api", "vulkan").split(",")
+ +def convert_suffix(direction, win_type, unwrap): + if direction == Direction.OUTPUT: + if not unwrap: + return "unwrapped_host_to_{0}".format(win_type) + return "host_to_{0}".format(win_type) + else: + if not unwrap: + return "{0}_to_unwrapped_host".format(win_type) + return "{0}_to_host".format(win_type) + + class VkBaseType(object): def __init__(self, name, _type, alias=None, requires=None): """ Vulkan base type class. @@ -1493,27 +1505,25 @@ 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()) + if self.needs_conversion(conv, unwrap, direction, False): if self.is_dynamic_array(): # Array length is either a variable name (string) or an int. count = self.get_dyn_array_len(input, conv) - host_part = "host" if unwrap else "unwrapped_host" pointer_part = "pointer_" if self.pointer_array else "" if direction == Direction.OUTPUT: - return "convert_{2}_{7}array_{6}_to_{5}({3}{1}, {0}, {4});\n".format( - self.value(output, conv), self.name, self.type, input, count, win_type, - host_part, pointer_part) + 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) else: - return "{0}{1} = convert_{2}_{7}array_{5}_to_{6}(ctx, {3}, {4});\n".format( - output, self.name, self.type, self.value(input, conv), count, win_type, - host_part, pointer_part) + 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) elif self.is_static_array(): count = self.array_len if direction == Direction.OUTPUT: # Needed by VkMemoryHeap.memoryHeaps - host_part = "host" if unwrap else "unwrapped_host" - return "convert_{0}_array_{6}_to_{5}({2}{1}, {3}{1}, {4});\n".format( - self.type, self.name, input, output, count, win_type, host_part) + return "convert_{0}_array_{5}({2}{1}, {3}{1}, {4});\n".format(self.type, + self.name, input, output, count, suffix) else: # Nothing needed this yet. LOGGER.warn("TODO: implement copying of static array for {0}.{1}".format(self.type, self.name)) @@ -1522,8 +1532,8 @@ class VkMember(VkVariable): if direction == Direction.OUTPUT: LOGGER.err("OUTPUT parameter {0}.{1} cannot be unwrapped".format(self.type, self.name)) elif self.optional: - return "{0}{1} = {2} ? {3} : 0;\n".format(output, self.name, - self.value(input, conv), handle.driver_handle(self.value(input, conv))) + 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))) elif self.is_generic_handle(): @@ -1537,8 +1547,8 @@ class VkMember(VkVariable): return "convert_{0}_host_to_{4}(&{2}{1}, &{3}{1}{5});\n".format(self.type, self.name, input, output, win_type, selector_part) else: ctx_param = "ctx, " if self.needs_alloc(conv, unwrap) else "" - host_part = "host" if unwrap else "unwrapped_host" - return "convert_{0}_{4}_to_{6}({5}&{2}{1}, &{3}{1}{7});\n".format(self.type, self.name, input, output, win_type, ctx_param, host_part, selector_part) + return "convert_{0}_{4}({5}&{2}{1}, &{3}{1}{6});\n".format(self.type, + self.name, input, output, suffix, ctx_param, selector_part) elif self.is_static_array(): bytes_count = "{0} * sizeof({1})".format(self.array_len, self.type) return "memcpy({0}{1}, {2}{1}, {3});\n".format(output, self.name, input, bytes_count) @@ -1747,32 +1757,32 @@ class VkParam(VkVariable):
def copy(self, direction, conv, unwrap, prefix=""): win_type = "win32" if conv else "win64" - wrap_part = "" if unwrap or not self.is_wrapped() else "unwrapped_" + suffix = convert_suffix(direction, win_type, unwrap or not self.is_wrapped()) + if direction == Direction.INPUT: ctx_param = "ctx, " if self.needs_alloc(conv, unwrap) else "" if self.is_dynamic_array(): - return " {0}_host = convert_{2}_array_{4}_to_{6}host({5}{1}, {3});\n".format( - self.name, self.value(prefix, conv), self.type, self.get_dyn_array_len(prefix, conv), - win_type, ctx_param, wrap_part) + 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(prefix, conv), suffix, ctx_param) elif self.optional: 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}_to_{5}host({4}{1}, {2}_host);\n".format( - self.type, self.value(prefix, conv), self.name, win_type, ctx_param, wrap_part) + ret += " convert_{0}_{3}({4}{1}, {2}_host);\n".format(self.type, self.value(prefix, conv), + self.name, suffix, ctx_param) ret += " }\n" return ret elif self.is_struct(): - return " convert_{0}_{3}_to_{5}host({4}{1}, &{2}_host);\n".format( - self.type, self.value(prefix, conv), self.name, win_type, ctx_param, wrap_part) + return " convert_{0}_{3}({4}{1}, &{2}_host);\n".format(self.type, self.value(prefix, conv), + self.name, suffix, ctx_param) 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(): - return " convert_{0}_array_{1}host_to_{2}({3}_host, {4}, {5});\n".format( - self.type, wrap_part, win_type, self.name, self.value(prefix, conv), + return " convert_{0}_array_{1}({2}_host, {3}, {4});\n".format( + self.type, suffix, self.name, self.value(prefix, conv), self.get_dyn_array_len(prefix, conv)) elif self.is_struct(): ref_part = "" if self.optional else "&" @@ -2273,11 +2283,7 @@ class StructConversionFunction(object):
name = "convert_{0}_".format(self.type) win_type = "win32" if self.conv else "win64" - host_part = "host" if self.unwrap else "unwrapped_host" - if self.direction == Direction.INPUT: - name += "{0}_to_{1}".format(win_type, host_part) - else: # Direction.OUTPUT - name += "{0}_to_{1}".format(host_part, win_type) + name += convert_suffix(self.direction, win_type, self.unwrap) self.name = name
def __eq__(self, other): @@ -2480,11 +2486,7 @@ class ArrayConversionFunction(object): name += "pointer_" name += "array_" win_type = "win32" if self.conv else "win64" - host_part = "host" if self.unwrap else "unwrapped_host" - if self.direction == Direction.INPUT: - name += "{0}_to_{1}".format(win_type, host_part) - else: # Direction.OUTPUT - name += "{0}_to_{1}".format(host_part, win_type) + name += convert_suffix(self.direction, win_type, self.unwrap) self.name = name
def __eq__(self, other): @@ -2555,11 +2557,7 @@ class ArrayConversionFunction(object): if self.array.is_struct(): struct = self.array.struct win_part = "win32" if self.conv else "win64" - host_part = "host" if self.unwrap else "unwrapped_host" - if self.direction == Direction.INPUT: - conv_suffix = "{0}_to_{1}".format(win_part, host_part) - else: - conv_suffix = "{0}_to_{1}".format(host_part, win_part) + suffix = convert_suffix(self.direction, win_part, self.unwrap)
ctx_part = "" if self.direction == Direction.INPUT and struct.needs_alloc(self.conv, self.unwrap): @@ -2567,7 +2565,7 @@ class ArrayConversionFunction(object):
if not self.array.pointer_array: body += " convert_{0}_{1}({2}&in[i], &out[i]);\n".format( - struct.name, conv_suffix, ctx_part) + struct.name, suffix, ctx_part) else: if struct.needs_conversion(self.conv, self.unwrap, self.direction, False): body += " if (in[i])\n" @@ -2578,7 +2576,7 @@ class ArrayConversionFunction(object): else: in_param = "in[i]" body += " convert_{0}_{1}({2}{3}, out[i]);\n".format( - struct.name, conv_suffix, ctx_part, in_param) + struct.name, suffix, ctx_part, in_param) body += " }\n" body += " else\n" body += " out[i] = NULL;\n"
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winevulkan/make_vulkan | 120 +++++++++++++++++++++--------------- 1 file changed, 72 insertions(+), 48 deletions(-)
diff --git a/dlls/winevulkan/make_vulkan b/dlls/winevulkan/make_vulkan index 7e1cc3f1dd9..f951481bf63 100755 --- a/dlls/winevulkan/make_vulkan +++ b/dlls/winevulkan/make_vulkan @@ -321,17 +321,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)
@@ -616,6 +626,11 @@ class VkFunction(object): # and is used by the code generation. self.required = True if func_info else False
+ if self.name not in MANUAL_UNIX_THUNKS: + self.unwrap = Unwrap.HOST + else: + self.unwrap = Unwrap.NONE + @staticmethod def from_alias(command, alias): """ Create VkFunction from an alias command. @@ -662,7 +677,7 @@ class VkFunction(object):
conversions = [] for param in self.params: - conversions.extend(param.get_conversions(unwrap=self.name not in MANUAL_UNIX_THUNKS)) + conversions.extend(param.get_conversions(self.unwrap)) return conversions
def is_alias(self): @@ -802,14 +817,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 "") @@ -818,7 +833,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 @@ -849,15 +864,16 @@ class VkFunction(object): # Call any win_to_host conversion calls. unwrap = self.name not in MANUAL_UNIX_THUNKS for p in self.params: - if p.needs_conversion(conv, unwrap, direction=Direction.INPUT): - body += p.copy(Direction.INPUT, conv, unwrap, prefix=params_prefix) - elif p.is_dynamic_array() and p.needs_conversion(conv, unwrap, direction=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, unwrap, params_prefix=params_prefix) for p in self.params]) + unwrap = Unwrap.NONE if self.name in MANUAL_UNIX_THUNKS 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) @@ -877,8 +893,8 @@ class VkFunction(object):
# Call any host_to_win conversion calls. for p in self.params: - if p.needs_conversion(conv, unwrap, direction=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: @@ -949,7 +965,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.name not in MANUAL_UNIX_THUNKS, params_prefix="params->") + thunk += self.body(conv, params_prefix="params->") thunk += "}\n" if not conv: thunk += "#endif /* _WIN64 */\n" @@ -1174,8 +1190,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): @@ -1322,14 +1341,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 @@ -1505,7 +1524,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(): @@ -1527,7 +1546,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)) @@ -1535,7 +1554,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)) @@ -1544,7 +1564,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, @@ -1631,12 +1652,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): @@ -1757,7 +1778,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 "" @@ -1865,7 +1886,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 @@ -1918,7 +1939,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"
@@ -1930,7 +1951,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( @@ -2121,17 +2142,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: @@ -2148,12 +2169,14 @@ 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): + # FIXME: This should follow the caller unwrapping instead of always unwrapping to host handles + if e.needs_conversion(conv, Unwrap.HOST, 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): + # FIXME: This should follow the caller unwrapping instead of always unwrapping to host handles + if e.needs_conversion(conv, Unwrap.HOST, Direction.OUTPUT, is_const, check_extensions=False): return True
return False @@ -2214,12 +2237,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: @@ -2261,7 +2284,8 @@ class VkStruct(Sequence): for e in self.struct_extensions: if not e.required: continue - conversions.extend(e.get_conversions(True, parent_const)) + # FIXME: This should follow the caller unwrapping instead of always unwrapping to host handles + conversions.extend(e.get_conversions(Unwrap.HOST, parent_const))
# Collect any conversion for any member structs. for m in self: @@ -2278,12 +2302,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): @@ -2353,7 +2377,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: @@ -2439,7 +2463,8 @@ 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) + # FIXME: This should follow the caller unwrapping instead of always unwrapping to host handles + copy_body += ident + m.copy("in_ext->", "out_ext->", self.direction, self.conv, Unwrap.HOST)
# Generate the definition of "in_ext" if we need it if "in_ext->" in copy_body: @@ -2476,7 +2501,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") @@ -2486,7 +2511,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): @@ -2557,8 +2582,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, " @@ -2593,7 +2617,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" @@ -2686,7 +2710,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(): @@ -2764,7 +2788,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")
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winevulkan/make_vulkan | 41 ++++++++++++++++++++++++--------- dlls/winevulkan/vulkan_thunks.c | 16 ++++++------- 2 files changed, 38 insertions(+), 19 deletions(-)
diff --git a/dlls/winevulkan/make_vulkan b/dlls/winevulkan/make_vulkan index f951481bf63..7d0f109785e 100755 --- a/dlls/winevulkan/make_vulkan +++ b/dlls/winevulkan/make_vulkan @@ -325,6 +325,7 @@ class Direction(Enum): class Unwrap(Enum): NONE = 0 HOST = 1 + DRIVER = 2
def api_is_vulkan(obj): @@ -337,12 +338,16 @@ def convert_suffix(direction, win_type, unwrap, is_wrapped): return "host_to_{0}".format(win_type) if unwrap == Unwrap.NONE: return "unwrapped_host_to_{0}".format(win_type) + if unwrap == Unwrap.DRIVER: + return "driver_to_{0}".format(win_type) return "host_to_{0}".format(win_type) else: if not is_wrapped: return "{0}_to_host".format(win_type) if unwrap == Unwrap.NONE: return "{0}_to_unwrapped_host".format(win_type) + if unwrap == Unwrap.DRIVER: + return "{0}_to_driver".format(win_type) return "{0}_to_host".format(win_type)
@@ -626,10 +631,12 @@ class VkFunction(object): # and is used by the code generation. self.required = True if func_info else False
- if self.name not in MANUAL_UNIX_THUNKS: - self.unwrap = Unwrap.HOST - else: + if self.name in MANUAL_UNIX_THUNKS: self.unwrap = Unwrap.NONE + elif self.name in USER_DRIVER_FUNCS: + self.unwrap = Unwrap.DRIVER + else: + self.unwrap = Unwrap.HOST
@staticmethod def from_alias(command, alias): @@ -1190,10 +1197,19 @@ class VkHandle(object):
return self.host_handle(name)
- def is_wrapped(self, unwrap): + def unwrap_handle(self, name, unwrap): + if unwrap == Unwrap.DRIVER: + return self.driver_handle(name) + if unwrap == Unwrap.HOST: + return self.host_handle(name) + assert unwrap != Unwrap.NONE + return None + + def is_wrapped(self, unwrap=Unwrap.HOST): + if unwrap == Unwrap.DRIVER: + return self.driver_handle("test") is not None if unwrap == Unwrap.HOST: return self.host_handle("test") is not None - assert unwrap == Unwrap.NONE return False
@@ -1552,15 +1568,16 @@ class VkMember(VkVariable): LOGGER.err("OUTPUT parameter {0}.{1} cannot be unwrapped".format(self.type, self.name)) elif self.optional: return "{0}{1} = {2} ? {3} : 0;\n".format(output, self.name, self.value(input, conv), - handle.driver_handle(self.value(input, conv))) + handle.unwrap_handle(self.value(input, conv), unwrap)) else: return "{0}{1} = {2};\n".format(output, self.name, - handle.driver_handle(self.value(input, conv))) + handle.unwrap_handle(self.value(input, conv), unwrap)) elif self.is_generic_handle(): if direction == Direction.OUTPUT: LOGGER.err("OUTPUT parameter {0}.{1} cannot be unwrapped".format(self.type, self.name)) - else: - return "{0}{1} = wine_vk_unwrap_handle({2}{3}, {2}{1});\n".format(output, self.name, input, self.object_type) + if unwrap == Unwrap.DRIVER and self.is_wrapped(Unwrap.DRIVER): + LOGGER.err("DRIVER unwrapping of {0}.{1} not implemented".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 "" if direction == Direction.OUTPUT: @@ -1954,13 +1971,15 @@ class VkParam(VkVariable): if unwrap != Unwrap.NONE: unwrap_handle = None if self.object_type != None and self.type == "uint64_t": + if unwrap == Unwrap.DRIVER and self.is_wrapped(Unwrap.DRIVER): + LOGGER.err("DRIVER unwrapping of {0}.{1} not implemented".format(self.type, self.name)) unwrap_handle = "wine_vk_unwrap_handle({0}{1}, {0}{2})".format( params_prefix, self.object_type, self.name)
elif self.is_handle(): # We need to pass the host handle to the host Vulkan calls and # the wine driver's handle to calls which are wrapped by the driver. - unwrap_handle = self.handle.driver_handle(p) + unwrap_handle = self.handle.unwrap_handle(p, unwrap) if unwrap_handle: if self.optional: unwrap_handle = "{0}{1} ? {2} : 0".format(params_prefix, self.name, unwrap_handle) @@ -2620,7 +2639,7 @@ class ArrayConversionFunction(object): 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" + body += " out[i] = {0};\n".format(handle.unwrap_handle(input, self.unwrap)) else: LOGGER.warning("Unhandled handle output conversion") elif self.array.pointer_array: diff --git a/dlls/winevulkan/vulkan_thunks.c b/dlls/winevulkan/vulkan_thunks.c index a766883115d..113b529c560 100644 --- a/dlls/winevulkan/vulkan_thunks.c +++ b/dlls/winevulkan/vulkan_thunks.c @@ -17914,7 +17914,7 @@ static inline const VkShaderCreateInfoEXT *convert_VkShaderCreateInfoEXT_array_w }
#ifdef _WIN64 -static inline void convert_VkSwapchainCreateInfoKHR_win64_to_host(const VkSwapchainCreateInfoKHR *in, VkSwapchainCreateInfoKHR *out) +static inline void convert_VkSwapchainCreateInfoKHR_win64_to_driver(const VkSwapchainCreateInfoKHR *in, VkSwapchainCreateInfoKHR *out) { if (!in) return;
@@ -17939,7 +17939,7 @@ static inline void convert_VkSwapchainCreateInfoKHR_win64_to_host(const VkSwapch } #endif /* _WIN64 */
-static inline void convert_VkSwapchainCreateInfoKHR_win32_to_host(struct conversion_context *ctx, const VkSwapchainCreateInfoKHR32 *in, VkSwapchainCreateInfoKHR *out) +static inline void convert_VkSwapchainCreateInfoKHR_win32_to_driver(struct conversion_context *ctx, const VkSwapchainCreateInfoKHR32 *in, VkSwapchainCreateInfoKHR *out) { const VkBaseInStructure32 *in_header; VkBaseOutStructure *out_header = (void *)out; @@ -26448,7 +26448,7 @@ static inline void convert_VkSurfaceCapabilities2KHR_host_to_win32(const VkSurfa }
#ifdef _WIN64 -static inline void convert_VkPhysicalDeviceSurfaceInfo2KHR_win64_to_host(const VkPhysicalDeviceSurfaceInfo2KHR *in, VkPhysicalDeviceSurfaceInfo2KHR *out) +static inline void convert_VkPhysicalDeviceSurfaceInfo2KHR_win64_to_driver(const VkPhysicalDeviceSurfaceInfo2KHR *in, VkPhysicalDeviceSurfaceInfo2KHR *out) { if (!in) return;
@@ -26458,7 +26458,7 @@ static inline void convert_VkPhysicalDeviceSurfaceInfo2KHR_win64_to_host(const V } #endif /* _WIN64 */
-static inline void convert_VkPhysicalDeviceSurfaceInfo2KHR_win32_to_host(struct conversion_context *ctx, const VkPhysicalDeviceSurfaceInfo2KHR32 *in, VkPhysicalDeviceSurfaceInfo2KHR *out) +static inline void convert_VkPhysicalDeviceSurfaceInfo2KHR_win32_to_driver(struct conversion_context *ctx, const VkPhysicalDeviceSurfaceInfo2KHR32 *in, VkPhysicalDeviceSurfaceInfo2KHR *out) { const VkBaseInStructure32 *in_header; VkBaseOutStructure *out_header = (void *)out; @@ -36113,7 +36113,7 @@ static NTSTATUS thunk64_vkCreateSwapchainKHR(void *args)
TRACE("%p, %p, %p, %p\n", params->device, params->pCreateInfo, params->pAllocator, params->pSwapchain);
- convert_VkSwapchainCreateInfoKHR_win64_to_host(params->pCreateInfo, &pCreateInfo_host); + convert_VkSwapchainCreateInfoKHR_win64_to_driver(params->pCreateInfo, &pCreateInfo_host); params->result = wine_device_from_handle(params->device)->funcs.p_vkCreateSwapchainKHR(wine_device_from_handle(params->device)->host_device, &pCreateInfo_host, NULL, params->pSwapchain); return STATUS_SUCCESS; } @@ -36136,7 +36136,7 @@ static NTSTATUS thunk32_vkCreateSwapchainKHR(void *args) TRACE("%#x, %#x, %#x, %#x\n", params->device, params->pCreateInfo, params->pAllocator, params->pSwapchain);
init_conversion_context(ctx); - convert_VkSwapchainCreateInfoKHR_win32_to_host(ctx, (const VkSwapchainCreateInfoKHR32 *)UlongToPtr(params->pCreateInfo), &pCreateInfo_host); + convert_VkSwapchainCreateInfoKHR_win32_to_driver(ctx, (const VkSwapchainCreateInfoKHR32 *)UlongToPtr(params->pCreateInfo), &pCreateInfo_host); params->result = wine_device_from_handle((VkDevice)UlongToPtr(params->device))->funcs.p_vkCreateSwapchainKHR(wine_device_from_handle((VkDevice)UlongToPtr(params->device))->host_device, &pCreateInfo_host, NULL, (VkSwapchainKHR *)UlongToPtr(params->pSwapchain)); free_conversion_context(ctx); return STATUS_SUCCESS; @@ -41232,7 +41232,7 @@ static NTSTATUS thunk64_vkGetPhysicalDeviceSurfaceFormats2KHR(void *args)
TRACE("%p, %p, %p, %p\n", params->physicalDevice, params->pSurfaceInfo, params->pSurfaceFormatCount, params->pSurfaceFormats);
- convert_VkPhysicalDeviceSurfaceInfo2KHR_win64_to_host(params->pSurfaceInfo, &pSurfaceInfo_host); + convert_VkPhysicalDeviceSurfaceInfo2KHR_win64_to_driver(params->pSurfaceInfo, &pSurfaceInfo_host); params->result = wine_phys_dev_from_handle(params->physicalDevice)->instance->funcs.p_vkGetPhysicalDeviceSurfaceFormats2KHR(wine_phys_dev_from_handle(params->physicalDevice)->host_physical_device, &pSurfaceInfo_host, params->pSurfaceFormatCount, params->pSurfaceFormats); return STATUS_SUCCESS; } @@ -41256,7 +41256,7 @@ static NTSTATUS thunk32_vkGetPhysicalDeviceSurfaceFormats2KHR(void *args) TRACE("%#x, %#x, %#x, %#x\n", params->physicalDevice, params->pSurfaceInfo, params->pSurfaceFormatCount, params->pSurfaceFormats);
init_conversion_context(ctx); - convert_VkPhysicalDeviceSurfaceInfo2KHR_win32_to_host(ctx, (const VkPhysicalDeviceSurfaceInfo2KHR32 *)UlongToPtr(params->pSurfaceInfo), &pSurfaceInfo_host); + convert_VkPhysicalDeviceSurfaceInfo2KHR_win32_to_driver(ctx, (const VkPhysicalDeviceSurfaceInfo2KHR32 *)UlongToPtr(params->pSurfaceInfo), &pSurfaceInfo_host); pSurfaceFormats_host = convert_VkSurfaceFormat2KHR_array_win32_to_host(ctx, (VkSurfaceFormat2KHR32 *)UlongToPtr(params->pSurfaceFormats), *(uint32_t *)UlongToPtr(params->pSurfaceFormatCount)); params->result = wine_phys_dev_from_handle((VkPhysicalDevice)UlongToPtr(params->physicalDevice))->instance->funcs.p_vkGetPhysicalDeviceSurfaceFormats2KHR(wine_phys_dev_from_handle((VkPhysicalDevice)UlongToPtr(params->physicalDevice))->host_physical_device, &pSurfaceInfo_host, (uint32_t *)UlongToPtr(params->pSurfaceFormatCount), pSurfaceFormats_host); convert_VkSurfaceFormat2KHR_array_host_to_win32(pSurfaceFormats_host, (VkSurfaceFormat2KHR32 *)UlongToPtr(params->pSurfaceFormats), *(uint32_t *)UlongToPtr(params->pSurfaceFormatCount));