From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/vulkan.c | 21 ++++- dlls/winemac.drv/vulkan.c | 26 +++++- dlls/winevulkan/loader.c | 48 +++++++++-- dlls/winevulkan/loader_thunks.c | 1 + dlls/winevulkan/make_vulkan | 60 +++++--------- dlls/winevulkan/vulkan.c | 131 ++++++++++++++++--------------- dlls/winevulkan/vulkan_loader.h | 3 +- dlls/winevulkan/vulkan_private.h | 2 +- dlls/winevulkan/vulkan_thunks.c | 31 +------- dlls/winewayland.drv/vulkan.c | 7 ++ dlls/winex11.drv/vulkan.c | 7 ++ include/wine/vulkan.h | 26 ++++++ include/wine/vulkan_driver.h | 12 ++- 13 files changed, 229 insertions(+), 146 deletions(-)
diff --git a/dlls/win32u/vulkan.c b/dlls/win32u/vulkan.c index f7b98404d52..12b31fbc26f 100644 --- a/dlls/win32u/vulkan.c +++ b/dlls/win32u/vulkan.c @@ -2266,6 +2266,11 @@ static const char *win32u_get_host_extension( const char *name ) return driver_funcs->p_get_host_extension( name ); }
+static void win32u_map_instance_extensions( struct vulkan_instance_extensions *extensions ) +{ + return driver_funcs->p_map_instance_extensions( extensions ); +} + static struct vulkan_funcs vulkan_funcs = { .p_vkAcquireNextImage2KHR = win32u_vkAcquireNextImage2KHR, @@ -2316,6 +2321,7 @@ static struct vulkan_funcs vulkan_funcs = .p_vkUnmapMemory = win32u_vkUnmapMemory, .p_vkUnmapMemory2KHR = win32u_vkUnmapMemory2KHR, .p_get_host_extension = win32u_get_host_extension, + .p_map_instance_extensions = win32u_map_instance_extensions, };
static VkResult nulldrv_vulkan_surface_create( HWND hwnd, const struct vulkan_instance *instance, VkSurfaceKHR *surface, @@ -2348,11 +2354,18 @@ static const char *nulldrv_get_host_extension( const char *name ) return name; }
+static void nulldrv_map_instance_extensions( struct vulkan_instance_extensions *extensions ) +{ + if (extensions->has_VK_KHR_win32_surface) extensions->has_VK_EXT_headless_surface = 1; + if (extensions->has_VK_EXT_headless_surface) extensions->has_VK_KHR_win32_surface = 1; +} + static const struct vulkan_driver_funcs nulldrv_funcs = { .p_vulkan_surface_create = nulldrv_vulkan_surface_create, .p_get_physical_device_presentation_support = nulldrv_get_physical_device_presentation_support, .p_get_host_extension = nulldrv_get_host_extension, + .p_map_instance_extensions = nulldrv_map_instance_extensions, };
static void vulkan_driver_init(void) @@ -2367,7 +2380,6 @@ static void vulkan_driver_init(void) }
if (status == STATUS_NOT_IMPLEMENTED) driver_funcs = &nulldrv_funcs; - else vulkan_funcs.p_get_host_extension = driver_funcs->p_get_host_extension; }
static void vulkan_driver_load(void) @@ -2395,11 +2407,18 @@ static const char *lazydrv_get_host_extension( const char *name ) return driver_funcs->p_get_host_extension( name ); }
+static void lazydrv_map_instance_extensions( struct vulkan_instance_extensions *extensions ) +{ + vulkan_driver_load(); + return driver_funcs->p_map_instance_extensions( extensions ); +} + static const struct vulkan_driver_funcs lazydrv_funcs = { .p_vulkan_surface_create = lazydrv_vulkan_surface_create, .p_get_physical_device_presentation_support = lazydrv_get_physical_device_presentation_support, .p_get_host_extension = lazydrv_get_host_extension, + .p_map_instance_extensions = lazydrv_map_instance_extensions, };
static void vulkan_init_once(void) diff --git a/dlls/winemac.drv/vulkan.c b/dlls/winemac.drv/vulkan.c index 51d951139b9..9ba3befafde 100644 --- a/dlls/winemac.drv/vulkan.c +++ b/dlls/winemac.drv/vulkan.c @@ -98,18 +98,38 @@ static VkBool32 macdrv_get_physical_device_presentation_support(struct vulkan_ph return VK_TRUE; }
-static const char *host_surface_extension = "VK_MVK_macos_surface"; +static BOOL use_VK_EXT_metal_surface; + static const char *macdrv_get_host_extension(const char *name) { - if (!strcmp( name, "VK_KHR_win32_surface" )) return host_surface_extension; + if (!strcmp( name, "VK_KHR_win32_surface" )) + { + if (use_VK_EXT_metal_surface) return "VK_EXT_metal_surface"; + return "VK_MVK_macos_surface"; + } return name; }
+static void macdrv_map_instance_extensions(struct vulkan_instance_extensions *extensions) +{ + if (use_VK_EXT_metal_surface) + { + if (extensions->has_VK_KHR_win32_surface) extensions->has_VK_EXT_metal_surface = 1; + if (extensions->has_VK_EXT_metal_surface) extensions->has_VK_KHR_win32_surface = 1; + } + else + { + if (extensions->has_VK_KHR_win32_surface) extensions->has_VK_MVK_macos_surface = 1; + if (extensions->has_VK_MVK_macos_surface) extensions->has_VK_KHR_win32_surface = 1; + } +} + static const struct vulkan_driver_funcs macdrv_vulkan_driver_funcs = { .p_vulkan_surface_create = macdrv_vulkan_surface_create, .p_get_physical_device_presentation_support = macdrv_get_physical_device_presentation_support, .p_get_host_extension = macdrv_get_host_extension, + .p_map_instance_extensions = macdrv_map_instance_extensions, };
UINT macdrv_VulkanInit(UINT version, void *vulkan_handle, const struct vulkan_driver_funcs **driver_funcs) @@ -120,7 +140,7 @@ UINT macdrv_VulkanInit(UINT version, void *vulkan_handle, const struct vulkan_dr return STATUS_INVALID_PARAMETER; }
- if (dlsym(vulkan_handle, "vkCreateMetalSurfaceEXT")) host_surface_extension = "VK_EXT_metal_surface"; + use_VK_EXT_metal_surface = !!dlsym(vulkan_handle, "vkCreateMetalSurfaceEXT");
*driver_funcs = &macdrv_vulkan_driver_funcs; return STATUS_SUCCESS; diff --git a/dlls/winevulkan/loader.c b/dlls/winevulkan/loader.c index b5d1b5a1310..e6fc7e21d22 100644 --- a/dlls/winevulkan/loader.c +++ b/dlls/winevulkan/loader.c @@ -30,6 +30,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(vulkan);
static HINSTANCE hinstance; static BOOL get_device_proc_addr_instance_procs = FALSE; +static struct vulkan_instance_extensions instance_extensions; /* supported client instance extensions */
VkResult WINAPI vkEnumerateInstanceLayerProperties(uint32_t *count, VkLayerProperties *properties) { @@ -305,13 +306,14 @@ static NTSTATUS WINAPI call_vulkan_debug_utils_callback(void *args, ULONG size)
static BOOL WINAPI wine_vk_init(INIT_ONCE *once, void *param, void **context) { - struct vk_callback_funcs callback_funcs = + struct init_params params = { - .call_vulkan_debug_report_callback = (ULONG_PTR)call_vulkan_debug_report_callback, - .call_vulkan_debug_utils_callback = (ULONG_PTR)call_vulkan_debug_utils_callback, + .call_vulkan_debug_report_callback = (UINT_PTR)call_vulkan_debug_report_callback, + .call_vulkan_debug_utils_callback = (UINT_PTR)call_vulkan_debug_utils_callback, + .extensions = &instance_extensions, };
- return !__wine_init_unix_call() && !UNIX_CALL(init, &callback_funcs); + return !__wine_init_unix_call() && !UNIX_CALL(init, ¶ms); }
static BOOL wine_vk_init_once(void) @@ -321,6 +323,15 @@ static BOOL wine_vk_init_once(void) return InitOnceExecuteOnce(&init_once, wine_vk_init, NULL, NULL); }
+static BOOL is_instance_extension_supported(const char *extension, struct vulkan_instance_extensions *extensions) +{ +#define USE_VK_EXT(x) if (!strcmp(extension, #x)) return (extensions->has_ ## x = instance_extensions.has_ ## x); + ALL_VK_CLIENT_INSTANCE_EXTS +#undef USE_VK_EXT + WARN("Extension %s is not supported.\n", debugstr_a(extension)); + return FALSE; +} + VkResult WINAPI vkCreateInstance(const VkInstanceCreateInfo *create_info, const VkAllocationCallbacks *allocator, VkInstance *ret) { @@ -386,6 +397,8 @@ VkResult WINAPI vkEnumerateInstanceExtensionProperties(const char *layer_name, uint32_t *count, VkExtensionProperties *properties) { struct vkEnumerateInstanceExtensionProperties_params params; + struct vulkan_instance_extensions extensions = {0}; + uint32_t i, j, capacity = *count; NTSTATUS status;
TRACE("%p, %p, %p\n", layer_name, count, properties); @@ -406,7 +419,32 @@ VkResult WINAPI vkEnumerateInstanceExtensionProperties(const char *layer_name, params.pPropertyCount = count; params.pProperties = properties; status = UNIX_CALL(vkEnumerateInstanceExtensionProperties, ¶ms); - assert(!status); + assert(!status && "vkEnumerateInstanceExtensionProperties"); + if (params.result) return params.result; + + if (!properties) + { + if (instance_extensions.has_VK_KHR_win32_surface) *count += 1; + return params.result; + } + + TRACE("Client instance extensions:\n"); + for (i = 0, j = 0; i < *count; i++) + { + const char *extension = properties[i].extensionName; + if (!is_instance_extension_supported(extension, &extensions)) continue; + TRACE(" - %s\n", extension); + properties[j++] = properties[i]; + } + if (instance_extensions.has_VK_KHR_win32_surface) + { + static const VkExtensionProperties VK_KHR_win32_surface = {VK_KHR_WIN32_SURFACE_EXTENSION_NAME, VK_KHR_WIN32_SURFACE_SPEC_VERSION}; + if (j == capacity) return VK_INCOMPLETE; + TRACE(" - VK_KHR_win32_surface\n"); + properties[j++] = VK_KHR_win32_surface; + } + *count = j; + return params.result; }
diff --git a/dlls/winevulkan/loader_thunks.c b/dlls/winevulkan/loader_thunks.c index 2b396998be8..1a210a19b37 100644 --- a/dlls/winevulkan/loader_thunks.c +++ b/dlls/winevulkan/loader_thunks.c @@ -7880,3 +7880,4 @@ void *wine_vk_get_instance_proc_addr(const char *name) } return NULL; } + diff --git a/dlls/winevulkan/make_vulkan b/dlls/winevulkan/make_vulkan index 619dd35cd72..7673570f61a 100755 --- a/dlls/winevulkan/make_vulkan +++ b/dlls/winevulkan/make_vulkan @@ -156,12 +156,6 @@ CORE_EXTENSIONS = [ "VK_KHR_win32_surface", ]
-# List of surface extensions that can be exposed directly to the PE side -WIN_SURFACE_EXTENSIONS = [ - "VK_KHR_win32_surface", - "VK_EXT_headless_surface", -] - # Some experimental extensions are used by shipping applications so their API is extremely unlikely # to change in a backwards-incompatible way. Allow translation of those extensions with WineVulkan. ALLOWED_X_EXTENSIONS = [ @@ -2670,13 +2664,6 @@ class VkGenerator(object): f.write(" "{0}",\n".format(ext["name"])) f.write("};\n\n")
- # Create array of surface extensions. - f.write("static const char * const vk_host_surface_extensions[] =\n{\n") - for ext in self.registry.surface_extensions: - if ext["name"] not in WIN_SURFACE_EXTENSIONS: - f.write(" "{0}",\n".format(ext["name"])) - f.write("};\n\n") - f.write("BOOL wine_vk_device_extension_supported(const char *name)\n") f.write("{\n") f.write(" unsigned int i;\n") @@ -2699,17 +2686,6 @@ class VkGenerator(object): f.write(" return FALSE;\n") f.write("}\n\n")
- f.write("BOOL wine_vk_is_host_surface_extension(const char *name)\n") - f.write("{\n") - f.write(" unsigned int i;\n") - f.write(" for (i = 0; i < ARRAY_SIZE(vk_host_surface_extensions); i++)\n") - f.write(" {\n") - f.write(" if (strcmp(vk_host_surface_extensions[i], name) == 0)\n") - 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") @@ -2749,7 +2725,7 @@ class VkGenerator(object): f.write("const unixlib_entry_t __wine_unix_call_funcs[] =\n") f.write("#endif\n") f.write("{\n") - f.write(" init_vulkan,\n") + f.write(" wow64_init_vulkan,\n") f.write(" vk_is_available_instance_function32,\n") f.write(" vk_is_available_device_function32,\n") for vk_func in self.registry.funcs.values(): @@ -2863,7 +2839,7 @@ class VkGenerator(object): f.write(" }\n") f.write(" }\n") f.write(" return NULL;\n") - f.write("}\n") + f.write("}\n\n")
def generate_loader_thunks_h(self, f): self._generate_copyright(f) @@ -3029,21 +3005,31 @@ class VkGenerator(object): f.write(" \\n USE_VK_FUNC({0})".format(vk_func.name)) f.write("\n\n")
- f.write("#define ALL_VK_INSTANCE_FUNCS \\n") - first = True + f.write("#define ALL_VK_INSTANCE_FUNCS") for vk_func in self.registry.instance_funcs + self.registry.phys_dev_funcs: if not vk_func.is_required(): continue - if not vk_func.needs_dispatch(): - LOGGER.debug("skipping {0} in ALL_VK_INSTANCE_FUNCS".format(vk_func.name)) continue + f.write(" \\n USE_VK_FUNC({0})".format(vk_func.name)) + f.write("\n\n")
- if first: - f.write(" USE_VK_FUNC({0})".format(vk_func.name)) - first = False - else: - f.write(" \\n USE_VK_FUNC({0})".format(vk_func.name)) + f.write("#define ALL_VK_CLIENT_INSTANCE_EXTS") + for ext in self.registry.extensions: + if ext["type"] != "instance": + continue + if ext["name"] in UNEXPOSED_EXTENSIONS: + continue + f.write(f" \\n USE_VK_EXT({ext["name"]})") + f.write("\n\n") + + f.write("#define ALL_VK_INSTANCE_EXTS ALL_VK_CLIENT_INSTANCE_EXTS") + for ext in self.registry.extensions: + if ext["type"] != "instance": + continue + if ext["name"] not in UNEXPOSED_EXTENSIONS: + continue + f.write(f" \\n USE_VK_EXT({ext["name"]})") f.write("\n\n")
f.write("#endif /* __WINE_VULKAN_H */\n") @@ -3100,7 +3086,6 @@ class VkRegistry(object): # We aggregate all types in here for cross-referencing. self.funcs = {} self.types = {} - self.surface_extensions = []
self.version_regex = re.compile( r'^' @@ -3377,9 +3362,6 @@ class VkRegistry(object): def process_ext(ext, deferred=False): ext_name = ext.attrib["name"]
- if ext_name.endswith('_surface') and ext.attrib.get('depends', None) == 'VK_KHR_surface': - self.surface_extensions.append({"name" : ext_name}) - # Set extension name on any functions calls part of this extension as we # were not aware of the name during initial parsing. commands = ext.findall("require/command") diff --git a/dlls/winevulkan/vulkan.c b/dlls/winevulkan/vulkan.c index d566eec841e..f7217e6ac14 100644 --- a/dlls/winevulkan/vulkan.c +++ b/dlls/winevulkan/vulkan.c @@ -35,6 +35,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(vulkan); static PFN_vkCreateInstance p_vkCreateInstance; static PFN_vkEnumerateInstanceVersion p_vkEnumerateInstanceVersion; static PFN_vkEnumerateInstanceExtensionProperties p_vkEnumerateInstanceExtensionProperties; +static struct vulkan_instance_extensions instance_extensions; /* supported host instance extensions */
static struct wine_instance *wine_instance_from_handle(VkInstance handle) { @@ -131,7 +132,8 @@ static uint64_t client_handle_from_host(struct vulkan_instance *obj, uint64_t ho return result; }
-struct vk_callback_funcs callback_funcs; +static UINT64 call_vulkan_debug_report_callback; +static UINT64 call_vulkan_debug_utils_callback;
static UINT append_string(const char *name, char *strings, UINT *strings_len) { @@ -208,7 +210,7 @@ static VkBool32 debug_utils_callback_conversion(VkDebugUtilsMessageSeverityFlagB ptr = (char *)(params + 1); strings = (char *)params + size;
- params->dispatch.callback = callback_funcs.call_vulkan_debug_utils_callback; + params->dispatch.callback = call_vulkan_debug_utils_callback; params->user_callback = object->user_callback; params->user_data = object->user_data; params->severity = severity; @@ -296,7 +298,7 @@ static VkBool32 debug_report_callback_conversion(VkDebugReportFlagsEXT flags, Vk if (!(params = malloc(sizeof(*params) + strings_len))) return VK_FALSE; strings = (char *)(params + 1);
- params->dispatch.callback = callback_funcs.call_vulkan_debug_report_callback; + params->dispatch.callback = call_vulkan_debug_report_callback; params->user_callback = object->user_callback; params->user_data = object->user_data; params->flags = flags; @@ -668,7 +670,11 @@ static VkResult wine_vk_device_convert_create_info(struct vulkan_physical_device
NTSTATUS init_vulkan(void *arg) { - const struct vk_callback_funcs *funcs = arg; + struct vulkan_instance_extensions extensions = {0}; + VkExtensionProperties *properties = NULL; + const struct init_params *params = arg; + uint32_t count = 0; + VkResult res;
vk_funcs = __wine_get_vulkan_driver(WINE_VULKAN_DRIVER_VERSION); if (!vk_funcs) @@ -677,7 +683,9 @@ NTSTATUS init_vulkan(void *arg) return STATUS_UNSUCCESSFUL; }
- callback_funcs = *funcs; + call_vulkan_debug_report_callback = params->call_vulkan_debug_report_callback; + call_vulkan_debug_utils_callback = params->call_vulkan_debug_utils_callback; + p_vkCreateInstance = (PFN_vkCreateInstance)vk_funcs->p_vkGetInstanceProcAddr(NULL, "vkCreateInstance"); p_vkEnumerateInstanceVersion = (PFN_vkEnumerateInstanceVersion)vk_funcs->p_vkGetInstanceProcAddr(NULL, "vkEnumerateInstanceVersion"); p_vkEnumerateInstanceExtensionProperties = (PFN_vkEnumerateInstanceExtensionProperties)vk_funcs->p_vkGetInstanceProcAddr(NULL, "vkEnumerateInstanceExtensionProperties"); @@ -690,7 +698,43 @@ NTSTATUS init_vulkan(void *arg) zero_bits = (ULONG_PTR)info.HighestUserAddress | 0x7fffffff; }
- return STATUS_SUCCESS; + do + { + free(properties); + properties = NULL; + if ((res = p_vkEnumerateInstanceExtensionProperties(NULL, &count, NULL))) goto failed; + if (!count || !(properties = malloc(count * sizeof(*properties)))) return STATUS_UNSUCCESSFUL; + } while ((res = p_vkEnumerateInstanceExtensionProperties(NULL, &count, properties) == VK_INCOMPLETE)); + if (res) goto failed; + + TRACE("Host instance extensions:\n"); + for (uint32_t i = 0; i < count; i++) + { + const char *extension = properties[i].extensionName; +#define USE_VK_EXT(x) \ + if (!strcmp(extension, #x)) \ + { \ + extensions.has_ ## x = 1; \ + TRACE(" - %s\n", extension); \ + } else + ALL_VK_INSTANCE_EXTS +#undef USE_VK_EXT + WARN("Extension %s is not supported.\n", debugstr_a(extension)); + } + instance_extensions = extensions; + + /* map host instance extensions for VK_KHR_win32_surface */ + vk_funcs->p_map_instance_extensions(&extensions); + + /* filter out unsupported client instance extensions */ +#define USE_VK_EXT(x) params->extensions->has_ ## x = extensions.has_ ## x; + ALL_VK_CLIENT_INSTANCE_EXTS +#undef USE_VK_EXT + +failed: + free(properties); + if (res) ERR("Failed to initialize Vulkan, res %d\n", res); + return res ? STATUS_UNSUCCESSFUL : STATUS_SUCCESS; }
/* Helper function for converting between win32 and host compatible VkInstanceCreateInfo. @@ -1138,65 +1182,7 @@ VkResult wine_vkEnumerateDeviceExtensionProperties(VkPhysicalDevice client_physi VkResult wine_vkEnumerateInstanceExtensionProperties(const char *name, uint32_t *count, VkExtensionProperties *properties) { - uint32_t num_properties = 0, num_host_properties; - VkExtensionProperties *host_properties; - unsigned int i, j, surface; - VkResult res; - - res = p_vkEnumerateInstanceExtensionProperties(NULL, &num_host_properties, NULL); - if (res != VK_SUCCESS) - return res; - - if (!(host_properties = calloc(num_host_properties, sizeof(*host_properties)))) - return VK_ERROR_OUT_OF_HOST_MEMORY; - - res = p_vkEnumerateInstanceExtensionProperties(NULL, &num_host_properties, host_properties); - if (res != VK_SUCCESS) - { - ERR("Failed to retrieve host properties, res=%d.\n", res); - free(host_properties); - return res; - } - - /* The Wine graphics driver provides us with all extensions supported by the host side - * including extension fixup (e.g. VK_KHR_xlib_surface -> VK_KHR_win32_surface). It is - * up to us here to filter the list down to extensions for which we have thunks. - */ - for (i = 0, surface = 0; i < num_host_properties; i++) - { - if (wine_vk_instance_extension_supported(host_properties[i].extensionName) - || (wine_vk_is_host_surface_extension(host_properties[i].extensionName) && !surface++)) - num_properties++; - else - TRACE("Instance extension '%s' is not supported.\n", host_properties[i].extensionName); - } - - if (!properties) - { - TRACE("Returning %u extensions.\n", num_properties); - *count = num_properties; - free(host_properties); - return VK_SUCCESS; - } - - for (i = 0, j = 0, surface = 0; i < num_host_properties && j < *count; i++) - { - if (wine_vk_instance_extension_supported(host_properties[i].extensionName)) - { - TRACE("Enabling extension '%s'.\n", host_properties[i].extensionName); - properties[j++] = host_properties[i]; - } - else if (wine_vk_is_host_surface_extension(host_properties[i].extensionName) && !surface++) - { - VkExtensionProperties win32_surface = {VK_KHR_WIN32_SURFACE_EXTENSION_NAME, VK_KHR_WIN32_SURFACE_SPEC_VERSION}; - TRACE("Enabling VK_KHR_win32_surface.\n"); - properties[j++] = win32_surface; - } - } - *count = min(*count, num_properties); - - free(host_properties); - return *count < num_properties ? VK_INCOMPLETE : VK_SUCCESS; + return p_vkEnumerateInstanceExtensionProperties(name, count, properties); }
VkResult wine_vkEnumerateDeviceLayerProperties(VkPhysicalDevice client_physical_device, uint32_t *count, @@ -1842,6 +1828,21 @@ NTSTATUS vk_is_available_device_function(void *arg)
#endif /* _WIN64 */
+NTSTATUS wow64_init_vulkan(void *arg) +{ + struct + { + UINT64 call_vulkan_debug_report_callback; + UINT64 call_vulkan_debug_utils_callback; + ULONG extensions; + } *params32 = arg; + struct init_params params; + params.call_vulkan_debug_report_callback = params32->call_vulkan_debug_report_callback; + params.call_vulkan_debug_utils_callback = params32->call_vulkan_debug_utils_callback; + params.extensions = UlongToPtr(params32->extensions); + return init_vulkan(¶ms); +} + NTSTATUS vk_is_available_instance_function32(void *arg) { struct diff --git a/dlls/winevulkan/vulkan_loader.h b/dlls/winevulkan/vulkan_loader.h index 1d91bdf0216..e9a4195eee2 100644 --- a/dlls/winevulkan/vulkan_loader.h +++ b/dlls/winevulkan/vulkan_loader.h @@ -90,10 +90,11 @@ void *wine_vk_get_device_proc_addr(const char *name); void *wine_vk_get_phys_dev_proc_addr(const char *name); void *wine_vk_get_instance_proc_addr(const char *name);
-struct vk_callback_funcs +struct init_params { UINT64 call_vulkan_debug_report_callback; UINT64 call_vulkan_debug_utils_callback; + struct vulkan_instance_extensions *extensions; };
/* debug callbacks params */ diff --git a/dlls/winevulkan/vulkan_private.h b/dlls/winevulkan/vulkan_private.h index 0231cd3291b..5572c11ed6c 100644 --- a/dlls/winevulkan/vulkan_private.h +++ b/dlls/winevulkan/vulkan_private.h @@ -112,11 +112,11 @@ static inline struct wine_debug_report_callback *wine_debug_report_callback_from
BOOL wine_vk_device_extension_supported(const char *name); BOOL wine_vk_instance_extension_supported(const char *name); -BOOL wine_vk_is_host_surface_extension(const char *name);
BOOL wine_vk_is_type_wrapped(VkObjectType type);
NTSTATUS init_vulkan(void *args); +NTSTATUS wow64_init_vulkan(void *args);
NTSTATUS vk_is_available_instance_function(void *arg); NTSTATUS vk_is_available_device_function(void *arg); diff --git a/dlls/winevulkan/vulkan_thunks.c b/dlls/winevulkan/vulkan_thunks.c index 7f902f8ad47..dd0ce0acc52 100644 --- a/dlls/winevulkan/vulkan_thunks.c +++ b/dlls/winevulkan/vulkan_thunks.c @@ -61391,24 +61391,6 @@ static const char * const vk_instance_extensions[] = "VK_KHR_win32_surface", };
-static const char * const vk_host_surface_extensions[] = -{ - "VK_KHR_xlib_surface", - "VK_KHR_xcb_surface", - "VK_KHR_wayland_surface", - "VK_KHR_mir_surface", - "VK_KHR_android_surface", - "VK_GGP_stream_descriptor_surface", - "VK_NN_vi_surface", - "VK_MVK_ios_surface", - "VK_MVK_macos_surface", - "VK_FUCHSIA_imagepipe_surface", - "VK_EXT_metal_surface", - "VK_EXT_directfb_surface", - "VK_QNX_screen_surface", - "VK_OHOS_surface", -}; - BOOL wine_vk_device_extension_supported(const char *name) { unsigned int i; @@ -61431,17 +61413,6 @@ BOOL wine_vk_instance_extension_supported(const char *name) return FALSE; }
-BOOL wine_vk_is_host_surface_extension(const char *name) -{ - unsigned int i; - for (i = 0; i < ARRAY_SIZE(vk_host_surface_extensions); i++) - { - if (strcmp(vk_host_surface_extensions[i], name) == 0) - return TRUE; - } - return FALSE; -} - BOOL wine_vk_is_type_wrapped(VkObjectType type) { return FALSE || @@ -62145,7 +62116,7 @@ const unixlib_entry_t __wine_unix_call_wow64_funcs[] = const unixlib_entry_t __wine_unix_call_funcs[] = #endif { - init_vulkan, + wow64_init_vulkan, vk_is_available_instance_function32, vk_is_available_device_function32, thunk32_vkAcquireNextImage2KHR, diff --git a/dlls/winewayland.drv/vulkan.c b/dlls/winewayland.drv/vulkan.c index 9a70c90447d..74a4337de6e 100644 --- a/dlls/winewayland.drv/vulkan.c +++ b/dlls/winewayland.drv/vulkan.c @@ -90,11 +90,18 @@ static const char *wayland_get_host_extension(const char *name) return name; }
+static void wayland_map_instance_extensions(struct vulkan_instance_extensions *extensions) +{ + if (extensions->has_VK_KHR_win32_surface) extensions->has_VK_KHR_wayland_surface = 1; + if (extensions->has_VK_KHR_wayland_surface) extensions->has_VK_KHR_win32_surface = 1; +} + static const struct vulkan_driver_funcs wayland_vulkan_driver_funcs = { .p_vulkan_surface_create = wayland_vulkan_surface_create, .p_get_physical_device_presentation_support = wayland_get_physical_device_presentation_support, .p_get_host_extension = wayland_get_host_extension, + .p_map_instance_extensions = wayland_map_instance_extensions, };
/********************************************************************** diff --git a/dlls/winex11.drv/vulkan.c b/dlls/winex11.drv/vulkan.c index 72f367898de..82335e5c5a7 100644 --- a/dlls/winex11.drv/vulkan.c +++ b/dlls/winex11.drv/vulkan.c @@ -87,11 +87,18 @@ static const char *X11DRV_get_host_extension( const char *name ) return name; }
+static void X11DRV_map_instance_extensions( struct vulkan_instance_extensions *extensions ) +{ + if (extensions->has_VK_KHR_win32_surface) extensions->has_VK_KHR_xlib_surface = 1; + if (extensions->has_VK_KHR_xlib_surface) extensions->has_VK_KHR_win32_surface = 1; +} + static const struct vulkan_driver_funcs x11drv_vulkan_driver_funcs = { .p_vulkan_surface_create = X11DRV_vulkan_surface_create, .p_get_physical_device_presentation_support = X11DRV_get_physical_device_presentation_support, .p_get_host_extension = X11DRV_get_host_extension, + .p_map_instance_extensions = X11DRV_map_instance_extensions, };
UINT X11DRV_VulkanInit( UINT version, void *vulkan_handle, const struct vulkan_driver_funcs **driver_funcs ) diff --git a/include/wine/vulkan.h b/include/wine/vulkan.h index a6138d23213..cd395ac015b 100644 --- a/include/wine/vulkan.h +++ b/include/wine/vulkan.h @@ -21005,4 +21005,30 @@ VkResult VKAPI_CALL vkWriteMicromapsPropertiesEXT(VkDevice device, uint32_t micr USE_VK_FUNC(vkGetPhysicalDeviceWin32PresentationSupportKHR) \ USE_VK_FUNC(vkGetPhysicalDeviceXlibPresentationSupportKHR)
+#define ALL_VK_CLIENT_INSTANCE_EXTS \ + USE_VK_EXT(VK_EXT_debug_report) \ + USE_VK_EXT(VK_EXT_debug_utils) \ + USE_VK_EXT(VK_EXT_layer_settings) \ + USE_VK_EXT(VK_EXT_surface_maintenance1) \ + USE_VK_EXT(VK_EXT_swapchain_colorspace) \ + USE_VK_EXT(VK_EXT_validation_features) \ + USE_VK_EXT(VK_EXT_validation_flags) \ + USE_VK_EXT(VK_KHR_device_group_creation) \ + USE_VK_EXT(VK_KHR_external_fence_capabilities) \ + USE_VK_EXT(VK_KHR_external_memory_capabilities) \ + USE_VK_EXT(VK_KHR_external_semaphore_capabilities) \ + USE_VK_EXT(VK_KHR_get_physical_device_properties2) \ + USE_VK_EXT(VK_KHR_get_surface_capabilities2) \ + USE_VK_EXT(VK_KHR_portability_enumeration) \ + USE_VK_EXT(VK_KHR_surface) \ + USE_VK_EXT(VK_KHR_surface_maintenance1) \ + USE_VK_EXT(VK_KHR_win32_surface) + +#define ALL_VK_INSTANCE_EXTS ALL_VK_CLIENT_INSTANCE_EXTS \ + USE_VK_EXT(VK_EXT_headless_surface) \ + USE_VK_EXT(VK_EXT_metal_surface) \ + USE_VK_EXT(VK_KHR_wayland_surface) \ + USE_VK_EXT(VK_KHR_xlib_surface) \ + USE_VK_EXT(VK_MVK_macos_surface) + #endif /* __WINE_VULKAN_H */ diff --git a/include/wine/vulkan_driver.h b/include/wine/vulkan_driver.h index fbc639f69fa..ba8599751c1 100644 --- a/include/wine/vulkan_driver.h +++ b/include/wine/vulkan_driver.h @@ -27,6 +27,8 @@ #include <windef.h> #include <winbase.h>
+#include "wine/vulkan.h" + /* Base 'class' for our Vulkan dispatchable objects such as VkDevice and VkInstance. * This structure MUST be the first element of a dispatchable object as the ICD * loader depends on it. For now only contains loader_magic, but over time more common @@ -41,9 +43,15 @@ struct vulkan_client_object UINT64 unix_handle; };
+struct vulkan_instance_extensions +{ +#define USE_VK_EXT(x) unsigned has_ ## x : 1; + ALL_VK_INSTANCE_EXTS +#undef USE_VK_EXT +}; + #ifdef WINE_UNIX_LIB
-#include "wine/vulkan.h" #include "wine/rbtree.h"
/* Wine internal vulkan driver version, needs to be bumped upon vulkan_funcs changes. */ @@ -261,6 +269,7 @@ struct vulkan_funcs
/* winevulkan specific functions */ const char *(*p_get_host_extension)( const char *name ); + void (*p_map_instance_extensions)( struct vulkan_instance_extensions *extensions ); };
/* interface between win32u and the user drivers */ @@ -270,6 +279,7 @@ struct vulkan_driver_funcs VkResult (*p_vulkan_surface_create)(HWND, const struct vulkan_instance *, VkSurfaceKHR *, struct client_surface **); VkBool32 (*p_get_physical_device_presentation_support)(struct vulkan_physical_device *, uint32_t); const char *(*p_get_host_extension)( const char *name ); + void (*p_map_instance_extensions)( struct vulkan_instance_extensions *extensions ); };
#endif /* WINE_UNIX_LIB */