Hi all,
This patch series introduces the bulk of the functionality to support Vulkan Window System Integration (WSI). WSI consists of surface and swapchain code.
The WSI code is to be implemented in Wine graphics drivers as many of the calls require e.g. X11 or other platform specific code.
Thanks, Roderick
Roderick Colenbrander (7): winex11/winevulkan: add Vulkan WSI stubs (vk_khr_surface / vk_khr_swapchain). winevulkan: sanitize VkInstanceCreateInfo before passing to driver. winex11: Enable surface support for instances. winex11: Add initial vkCreateWin32SurfaceKHR implementation. winex11: Implement vkGetPhysicalDeviceWin32PresentationSupportKHR. winex11: Implement vkDestroySurfaceKHR. winex11: Implement support for vkGetPhysicalDeviceSurface*KHR APIs.
dlls/winevulkan/make_vulkan | 114 +++++++++++++- dlls/winevulkan/vulkan.c | 222 +++++++++++++++++++++++++++- dlls/winevulkan/vulkan_thunks.c | 12 ++ dlls/winevulkan/vulkan_thunks.h | 34 +++++ dlls/winex11.drv/vulkan.c | 320 ++++++++++++++++++++++++++++++++++++++-- include/wine/vulkan.h | 130 ++++++++++++++++ include/wine/vulkan_driver.h | 14 +- 7 files changed, 829 insertions(+), 17 deletions(-)
The WSI APIs are meant for window system integration, so essentially the WGL of Vulkan. Implementation belongs in the graphics drivers as we need to hook into surface and swapchains.
Signed-off-by: Roderick Colenbrander thunderbird2k@gmail.com --- dlls/winevulkan/make_vulkan | 114 +++++++++++++++++++++++++++++- dlls/winevulkan/vulkan.c | 153 ++++++++++++++++++++++++++++++++++++++++ dlls/winevulkan/vulkan_thunks.c | 12 ++++ dlls/winevulkan/vulkan_thunks.h | 34 +++++++++ dlls/winex11.drv/vulkan.c | 152 ++++++++++++++++++++++++++++++++++++--- include/wine/vulkan.h | 130 ++++++++++++++++++++++++++++++++++ include/wine/vulkan_driver.h | 14 +++- 7 files changed, 597 insertions(+), 12 deletions(-)
diff --git a/dlls/winevulkan/make_vulkan b/dlls/winevulkan/make_vulkan index 04896daafb..5fff3f1511 100755 --- a/dlls/winevulkan/make_vulkan +++ b/dlls/winevulkan/make_vulkan @@ -68,10 +68,27 @@ WINE_VULKAN_DRIVER_H = "../../include/wine/vulkan_driver.h" WINE_VULKAN_THUNKS_C = "vulkan_thunks.c" WINE_VULKAN_THUNKS_H = "vulkan_thunks.h"
+# Extension enum values start at a certain offset (EXT_BASE). +# Relative to the offset each extension has a block (EXT_BLOCK_SIZE) +# of values. +# Start for a given extension is: +# EXT_BASE + (extension_number-1) * EXT_BLOCK_SIZE +EXT_BASE = 1000000000 +EXT_BLOCK_SIZE = 1000 + +# In general instance extensions can't be automatically generated +# and need custom wrappers due to e.g. win32 / X11 specific code. +# List of supported instance extensions. +SUPPORTED_EXTENSIONS = [ + "VK_KHR_surface", + "VK_KHR_win32_surface", + "VK_KHR_swapchain", +] + # Functions part of our winevulkan graphics driver interface. # DRIVER_VERSION should be bumped on any change to driver interface # in FUNCTION_OVERRIDES -DRIVER_VERSION = 2 +DRIVER_VERSION = 3
# Table of functions for which we have a special implementation. # This are regular device / instance functions for which we need @@ -96,6 +113,24 @@ FUNCTION_OVERRIDES = { # Device functions "vkDestroyDevice" : {"dispatch" : True, "driver" : False, "thunk" : False}, "vkGetDeviceProcAddr" : {"dispatch" : True, "driver" : True, "thunk" : False}, + + # VK_KHR_surface + "vkDestroySurfaceKHR" : {"dispatch" : True, "driver" : True, "thunk" : False}, + "vkGetPhysicalDeviceSurfaceSupportKHR" : {"dispatch" : True, "driver" : True, "thunk" : False}, + "vkGetPhysicalDeviceSurfaceCapabilitiesKHR" : {"dispatch" : True, "driver" : True, "thunk" : False}, + "vkGetPhysicalDeviceSurfaceFormatsKHR" : {"dispatch" : True, "driver" : True, "thunk" : False}, + "vkGetPhysicalDeviceSurfacePresentModesKHR" : {"dispatch" : True, "driver" : True, "thunk" : False}, + + # VK_KHR_win32_surface + "vkCreateWin32SurfaceKHR" : {"dispatch" : True, "driver" : True, "thunk" : False}, + "vkGetPhysicalDeviceWin32PresentationSupportKHR" : {"dispatch" : True, "driver" : True, "thunk" : False}, + + # VK_KHR_swapchain + "vkAcquireNextImageKHR": {"dispatch" : True, "driver" : True, "thunk" : False}, + "vkCreateSwapchainKHR" : {"dispatch" : True, "driver" : True, "thunk" : False}, + "vkDestroySwapchainKHR" : {"dispatch" : True, "driver" : True, "thunk" : False}, + "vkGetSwapchainImagesKHR": {"dispatch" : True, "driver" : True, "thunk" : False}, + "vkQueuePresentKHR": {"dispatch" : True, "driver" : True, "thunk" : False}, }
@@ -356,6 +391,11 @@ class VkFunction(object):
def needs_stub(self): """ Temporary function to limit script hacks until more code is implemented. """ + + # Temporary hack to pull in VkSwapChainCreateInfoKHR. + if self.name == "vkCreateSwapchainKHR": + return False + if self.params[0].type != "VkPhysicalDevice": return True
@@ -1997,6 +2037,7 @@ class VkRegistry(object):
# Pull in any required types and functions. self._parse_features(root) + self._parse_extensions(root)
def _mark_command_required(self, command): """ Helper function to mark a certain command and the datatypes it needs as required.""" @@ -2099,6 +2140,77 @@ class VkRegistry(object):
self.enums = OrderedDict(sorted(enums.items()))
+ def _parse_extensions(self, root): + """ Parse extensions section and pull in any types and commands for this extensioin. """ + extensions = [] + exts = root.findall("./extensions/extension") + for ext in exts: + ext_name = ext.attrib["name"] + + # Some extensions are not ready or have numbers reserved as a place holder. + if ext.attrib["supported"] == "disabled": + LOGGER.debug("Skipping disabled extension: {0}".format(ext_name)) + continue + + # We only support a handful of extensions for now through a whitelist. + if ext_name not in SUPPORTED_EXTENSIONS: + LOGGER.debug("Skipping blacklisted extension: {0}".format(ext_name)) + continue + + LOGGER.debug("Loading extension: {0}".format(ext_name)) + + # Extensions can add enum values to Core / extension enums, so add these. + enums = ext.findall("require/enum") + for enum_elem in enums: + if "bitpos" in enum_elem.keys(): + # We need to add an extra value to an existing enum type. + # E.g. VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_IMG to VkFormatFeatureFlagBits. + type_name = enum_elem.attrib["extends"] + enum = self.types[type_name]["data"] + enum.add(VkEnumValue(enum_elem.attrib["name"], 1 << int(enum_elem.attrib["bitpos"]), hex=True)) + elif "offset" in enum_elem.keys(): + ext_number = int(ext.attrib["number"]) + offset = int(enum_elem.attrib["offset"]) + value = EXT_BASE + (ext_number - 1) * EXT_BLOCK_SIZE + offset + + # Deal with negative values. + direction = enum_elem.attrib.get("dir") + if direction is not None: + value = -value + + type_name = enum_elem.attrib["extends"] + enum = self.types[type_name]["data"] + enum.add(VkEnumValue(enum_elem.attrib["name"], value)) + + elif "value" in enum_elem.keys(): + # For now skip, it mostly contains extension name and version info. + continue + else: + # This seems to be used to pull in constants e.g. VK_MAX_DEVICE_GROUP_KHX + continue + + # Store a list with extensions. + ext_type = ext.attrib["type"] + ext_info = {"name" : ext_name, "type" : ext_type} + extensions.append(ext_info) + + commands = ext.findall("require/command") + if not commands: + continue + + # Pull in any commands we need. We infer types to pull in from the command + # as well. + for command in commands: + cmd_name = command.attrib["name"] + self._mark_command_required(cmd_name) + + # Set extension name on the function call as we were not aware of the + # name during initial parsing. + self.funcs[cmd_name].extension = ext_name + + # Sort in alphabetical order. + self.extensions = sorted(extensions, key=lambda ext: ext["name"]) + def _parse_features(self, root): """ Parse the feature section, which describes Core commands and types needed. """ requires = root.findall("./feature/require") diff --git a/dlls/winevulkan/vulkan.c b/dlls/winevulkan/vulkan.c index 678506fbb0..b17e290a66 100644 --- a/dlls/winevulkan/vulkan.c +++ b/dlls/winevulkan/vulkan.c @@ -162,6 +162,17 @@ static void wine_vk_instance_free(struct VkInstance_T *instance) heap_free(instance); }
+VkResult WINAPI wine_vkAcquireNextImageKHR(VkDevice device, VkSwapchainKHR swapchain, + uint64_t timeout, VkSemaphore semaphore, VkFence fence, uint32_t *image_index) +{ + TRACE("%p, 0x%s, 0x%s, 0x%s, 0x%s, %p\n", device, wine_dbgstr_longlong(swapchain), + wine_dbgstr_longlong(timeout), wine_dbgstr_longlong(semaphore), + wine_dbgstr_longlong(fence), image_index); + + return vk_funcs->p_vkAcquireNextImageKHR(device->device, swapchain, timeout, + semaphore, fence, image_index); +} + VkResult WINAPI wine_vkCreateDevice(VkPhysicalDevice phys_dev, const VkDeviceCreateInfo *create_info, const VkAllocationCallbacks *allocator, VkDevice *device) @@ -271,6 +282,72 @@ err: return res; }
+#if defined(USE_STRUCT_CONVERSION) +static inline void convert_VkSwapchainCreateInfoKHR_win_to_host(const VkSwapchainCreateInfoKHR *in, + VkSwapchainCreateInfoKHR_host *out) +{ + if (!in) return; + + out->sType = in->sType; + out->pNext = in->pNext; + out->flags = in->flags; + out->surface = in->surface; + out->minImageCount = in->minImageCount; + out->imageFormat = in->imageFormat; + out->imageColorSpace = in->imageColorSpace; + out->imageExtent = in->imageExtent; + out->imageArrayLayers = in->imageArrayLayers; + out->imageUsage = in->imageUsage; + out->imageSharingMode = in->imageSharingMode; + out->queueFamilyIndexCount = in->queueFamilyIndexCount; + out->pQueueFamilyIndices = in->pQueueFamilyIndices; + out->preTransform = in->preTransform; + out->compositeAlpha = in->compositeAlpha; + out->presentMode = in->presentMode; + out->clipped = in->clipped; + out->oldSwapchain = in->oldSwapchain; +} +#endif + +VkResult WINAPI wine_vkCreateSwapchainKHR(VkDevice device, + const VkSwapchainCreateInfoKHR *create_info, + const VkAllocationCallbacks *allocator, VkSwapchainKHR *swapchain) +{ +#if defined(USE_STRUCT_CONVERSION) + VkSwapchainCreateInfoKHR_host create_info_host; + TRACE("%p %p %p %p\n", device, create_info, allocator, swapchain); + + if (allocator) + FIXME("Support allocation allocators\n"); + + convert_VkSwapchainCreateInfoKHR_win_to_host(create_info, &create_info_host); + + /* Wine graphics driver only uses structs in host format. */ + return vk_funcs->p_vkCreateSwapchainKHR(device->device, + (VkSwapchainCreateInfoKHR*)&create_info_host, allocator, swapchain); +#else + TRACE("%p %p %p %p\n", device, create_info, allocator, swapchain); + + if (allocator) + FIXME("Support allocation allocators\n"); + + return vk_funcs->p_vkCreateSwapchainKHR(device->device, create_info, allocator, swapchain); +#endif +} + +VkResult WINAPI wine_vkCreateWin32SurfaceKHR(VkInstance instance, + const VkWin32SurfaceCreateInfoKHR *create_info, + const VkAllocationCallbacks* allocator, VkSurfaceKHR* surface) +{ + TRACE("%p %p %p %p\n", instance, create_info, allocator, surface); + + if (allocator) + FIXME("Support allocation allocators\n"); + + return vk_funcs->p_vkCreateWin32SurfaceKHR(instance->instance, create_info, + NULL /* allocator */, surface); +} + void WINAPI wine_vkDestroyDevice(VkDevice device, const VkAllocationCallbacks *allocator) { TRACE("%p %p\n", device, allocator); @@ -291,6 +368,28 @@ void WINAPI wine_vkDestroyInstance(VkInstance instance, const VkAllocationCallba wine_vk_instance_free(instance); }
+void WINAPI wine_vkDestroySurfaceKHR(VkInstance instance, VkSurfaceKHR surface, + const VkAllocationCallbacks *allocator) +{ + TRACE("%p, 0x%s, %p\n", instance, wine_dbgstr_longlong(surface), allocator); + + if (allocator) + FIXME("Support allocation allocators\n"); + + vk_funcs->p_vkDestroySurfaceKHR(instance->instance, surface, NULL /* allocator */); +} + +void WINAPI wine_vkDestroySwapchainKHR(VkDevice device, VkSwapchainKHR swapchain, + const VkAllocationCallbacks *allocator) +{ + TRACE("%p, 0x%s %p\n", device, wine_dbgstr_longlong(swapchain), allocator); + + if (allocator) + FIXME("Support allocation allocators\n"); + + vk_funcs->p_vkDestroySwapchainKHR(device->device, swapchain, NULL /* allocator */); +} + VkResult WINAPI wine_vkEnumerateDeviceExtensionProperties(VkPhysicalDevice phys_dev, const char *layer_name, uint32_t *count, VkExtensionProperties *properties) { @@ -418,6 +517,60 @@ static PFN_vkVoidFunction WINAPI wine_vkGetInstanceProcAddr(VkInstance instance, return NULL; }
+VkResult WINAPI wine_vkGetPhysicalDeviceSurfaceCapabilitiesKHR(VkPhysicalDevice phys_dev, + VkSurfaceKHR surface, VkSurfaceCapabilitiesKHR *capabilities) +{ + TRACE("%p, 0x%s, %p\n", phys_dev, wine_dbgstr_longlong(surface), capabilities); + return vk_funcs->p_vkGetPhysicalDeviceSurfaceCapabilitiesKHR(phys_dev->phys_dev, + surface, capabilities); +} + +VkResult WINAPI wine_vkGetPhysicalDeviceSurfaceFormatsKHR(VkPhysicalDevice phys_dev, + VkSurfaceKHR surface, uint32_t *format_count, VkSurfaceFormatKHR *formats) +{ + TRACE("%p, 0x%s, %p, %p\n", phys_dev, wine_dbgstr_longlong(surface), format_count, formats); + return vk_funcs->p_vkGetPhysicalDeviceSurfaceFormatsKHR(phys_dev->phys_dev, + surface, format_count, formats); +} + +VkResult WINAPI wine_vkGetPhysicalDeviceSurfacePresentModesKHR(VkPhysicalDevice phys_dev, + VkSurfaceKHR surface, uint32_t *mode_count, VkPresentModeKHR *modes) +{ + TRACE("%p, 0x%s, %p, %p\n", phys_dev, wine_dbgstr_longlong(surface), mode_count, modes); + return vk_funcs->p_vkGetPhysicalDeviceSurfacePresentModesKHR(phys_dev->phys_dev, + surface, mode_count, modes); +} + +VkResult WINAPI wine_vkGetPhysicalDeviceSurfaceSupportKHR(VkPhysicalDevice phys_dev, + uint32_t queue_family_index, VkSurfaceKHR surface, VkBool32 *supported) +{ + TRACE("%p, %u, 0x%s, %p\n", phys_dev, queue_family_index, wine_dbgstr_longlong(surface), supported); + return vk_funcs->p_vkGetPhysicalDeviceSurfaceSupportKHR(phys_dev->phys_dev, + queue_family_index, surface, supported); +} + +VkBool32 WINAPI wine_vkGetPhysicalDeviceWin32PresentationSupportKHR(VkPhysicalDevice phys_dev, + uint32_t queue_family_index) +{ + TRACE("%p %u\n", phys_dev, queue_family_index); + return vk_funcs->p_vkGetPhysicalDeviceWin32PresentationSupportKHR(phys_dev->phys_dev, + queue_family_index); +} + +VkResult WINAPI wine_vkGetSwapchainImagesKHR(VkDevice device, VkSwapchainKHR swapchain, + uint32_t *image_count, VkImage *images) +{ + TRACE("%p, 0x%s %p %p\n", device, wine_dbgstr_longlong(swapchain), image_count, images); + return vk_funcs->p_vkGetSwapchainImagesKHR(device->device, swapchain, + image_count, images); +} + +VkResult WINAPI wine_vkQueuePresentKHR(VkQueue queue, const VkPresentInfoKHR *present_info) +{ + FIXME("stub: %p, %p\n", queue, present_info); + return VK_ERROR_OUT_OF_HOST_MEMORY; +} + void * WINAPI wine_vk_icdGetInstanceProcAddr(VkInstance instance, const char *name) { TRACE("%p %s\n", instance, debugstr_a(name)); diff --git a/dlls/winevulkan/vulkan_thunks.c b/dlls/winevulkan/vulkan_thunks.c index 3670926c3e..5d9826cd67 100644 --- a/dlls/winevulkan/vulkan_thunks.c +++ b/dlls/winevulkan/vulkan_thunks.c @@ -895,6 +895,7 @@ static VkResult WINAPI wine_vkWaitForFences(VkDevice device, uint32_t fenceCount
static const struct vulkan_func vk_device_dispatch_table[] = { + {"vkAcquireNextImageKHR", &wine_vkAcquireNextImageKHR}, {"vkAllocateCommandBuffers", &wine_vkAllocateCommandBuffers}, {"vkAllocateDescriptorSets", &wine_vkAllocateDescriptorSets}, {"vkAllocateMemory", &wine_vkAllocateMemory}, @@ -964,6 +965,7 @@ static const struct vulkan_func vk_device_dispatch_table[] = {"vkCreateSampler", &wine_vkCreateSampler}, {"vkCreateSemaphore", &wine_vkCreateSemaphore}, {"vkCreateShaderModule", &wine_vkCreateShaderModule}, + {"vkCreateSwapchainKHR", &wine_vkCreateSwapchainKHR}, {"vkDestroyBuffer", &wine_vkDestroyBuffer}, {"vkDestroyBufferView", &wine_vkDestroyBufferView}, {"vkDestroyCommandPool", &wine_vkDestroyCommandPool}, @@ -983,6 +985,7 @@ static const struct vulkan_func vk_device_dispatch_table[] = {"vkDestroySampler", &wine_vkDestroySampler}, {"vkDestroySemaphore", &wine_vkDestroySemaphore}, {"vkDestroyShaderModule", &wine_vkDestroyShaderModule}, + {"vkDestroySwapchainKHR", &wine_vkDestroySwapchainKHR}, {"vkDeviceWaitIdle", &wine_vkDeviceWaitIdle}, {"vkEndCommandBuffer", &wine_vkEndCommandBuffer}, {"vkFlushMappedMemoryRanges", &wine_vkFlushMappedMemoryRanges}, @@ -1001,10 +1004,12 @@ static const struct vulkan_func vk_device_dispatch_table[] = {"vkGetPipelineCacheData", &wine_vkGetPipelineCacheData}, {"vkGetQueryPoolResults", &wine_vkGetQueryPoolResults}, {"vkGetRenderAreaGranularity", &wine_vkGetRenderAreaGranularity}, + {"vkGetSwapchainImagesKHR", &wine_vkGetSwapchainImagesKHR}, {"vkInvalidateMappedMemoryRanges", &wine_vkInvalidateMappedMemoryRanges}, {"vkMapMemory", &wine_vkMapMemory}, {"vkMergePipelineCaches", &wine_vkMergePipelineCaches}, {"vkQueueBindSparse", &wine_vkQueueBindSparse}, + {"vkQueuePresentKHR", &wine_vkQueuePresentKHR}, {"vkQueueSubmit", &wine_vkQueueSubmit}, {"vkQueueWaitIdle", &wine_vkQueueWaitIdle}, {"vkResetCommandBuffer", &wine_vkResetCommandBuffer}, @@ -1021,7 +1026,9 @@ static const struct vulkan_func vk_device_dispatch_table[] = static const struct vulkan_func vk_instance_dispatch_table[] = { {"vkCreateDevice", &wine_vkCreateDevice}, + {"vkCreateWin32SurfaceKHR", &wine_vkCreateWin32SurfaceKHR}, {"vkDestroyInstance", &wine_vkDestroyInstance}, + {"vkDestroySurfaceKHR", &wine_vkDestroySurfaceKHR}, {"vkEnumerateDeviceExtensionProperties", &wine_vkEnumerateDeviceExtensionProperties}, {"vkEnumerateDeviceLayerProperties", &wine_vkEnumerateDeviceLayerProperties}, {"vkEnumeratePhysicalDevices", &wine_vkEnumeratePhysicalDevices}, @@ -1032,6 +1039,11 @@ static const struct vulkan_func vk_instance_dispatch_table[] = {"vkGetPhysicalDeviceProperties", &wine_vkGetPhysicalDeviceProperties}, {"vkGetPhysicalDeviceQueueFamilyProperties", &wine_vkGetPhysicalDeviceQueueFamilyProperties}, {"vkGetPhysicalDeviceSparseImageFormatProperties", &wine_vkGetPhysicalDeviceSparseImageFormatProperties}, + {"vkGetPhysicalDeviceSurfaceCapabilitiesKHR", &wine_vkGetPhysicalDeviceSurfaceCapabilitiesKHR}, + {"vkGetPhysicalDeviceSurfaceFormatsKHR", &wine_vkGetPhysicalDeviceSurfaceFormatsKHR}, + {"vkGetPhysicalDeviceSurfacePresentModesKHR", &wine_vkGetPhysicalDeviceSurfacePresentModesKHR}, + {"vkGetPhysicalDeviceSurfaceSupportKHR", &wine_vkGetPhysicalDeviceSurfaceSupportKHR}, + {"vkGetPhysicalDeviceWin32PresentationSupportKHR", &wine_vkGetPhysicalDeviceWin32PresentationSupportKHR}, };
void *wine_vk_get_device_proc_addr(const char *name) diff --git a/dlls/winevulkan/vulkan_thunks.h b/dlls/winevulkan/vulkan_thunks.h index daf679b175..a91612e62b 100644 --- a/dlls/winevulkan/vulkan_thunks.h +++ b/dlls/winevulkan/vulkan_thunks.h @@ -13,12 +13,46 @@ void *wine_vk_get_device_proc_addr(const char *name) DECLSPEC_HIDDEN; void *wine_vk_get_instance_proc_addr(const char *name) DECLSPEC_HIDDEN;
/* Functions for which we have custom implementations outside of the thunks. */ +VkResult WINAPI wine_vkAcquireNextImageKHR(VkDevice device, VkSwapchainKHR swapchain, uint64_t timeout, VkSemaphore semaphore, VkFence fence, uint32_t *pImageIndex) DECLSPEC_HIDDEN; VkResult WINAPI wine_vkCreateDevice(VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkDevice *pDevice) DECLSPEC_HIDDEN; +VkResult WINAPI wine_vkCreateSwapchainKHR(VkDevice device, const VkSwapchainCreateInfoKHR *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkSwapchainKHR *pSwapchain) DECLSPEC_HIDDEN; +VkResult WINAPI wine_vkCreateWin32SurfaceKHR(VkInstance instance, const VkWin32SurfaceCreateInfoKHR *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) DECLSPEC_HIDDEN; void WINAPI wine_vkDestroyDevice(VkDevice device, const VkAllocationCallbacks *pAllocator) DECLSPEC_HIDDEN; void WINAPI wine_vkDestroyInstance(VkInstance instance, const VkAllocationCallbacks *pAllocator) DECLSPEC_HIDDEN; +void WINAPI wine_vkDestroySurfaceKHR(VkInstance instance, VkSurfaceKHR surface, const VkAllocationCallbacks *pAllocator) DECLSPEC_HIDDEN; +void WINAPI wine_vkDestroySwapchainKHR(VkDevice device, VkSwapchainKHR swapchain, const VkAllocationCallbacks *pAllocator) DECLSPEC_HIDDEN; VkResult WINAPI wine_vkEnumerateDeviceExtensionProperties(VkPhysicalDevice physicalDevice, const char *pLayerName, uint32_t *pPropertyCount, VkExtensionProperties *pProperties) DECLSPEC_HIDDEN; VkResult WINAPI wine_vkEnumeratePhysicalDevices(VkInstance instance, uint32_t *pPhysicalDeviceCount, VkPhysicalDevice *pPhysicalDevices) DECLSPEC_HIDDEN; PFN_vkVoidFunction WINAPI wine_vkGetDeviceProcAddr(VkDevice device, const char *pName) DECLSPEC_HIDDEN; +VkResult WINAPI wine_vkGetPhysicalDeviceSurfaceCapabilitiesKHR(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, VkSurfaceCapabilitiesKHR *pSurfaceCapabilities) DECLSPEC_HIDDEN; +VkResult WINAPI wine_vkGetPhysicalDeviceSurfaceFormatsKHR(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, uint32_t *pSurfaceFormatCount, VkSurfaceFormatKHR *pSurfaceFormats) DECLSPEC_HIDDEN; +VkResult WINAPI wine_vkGetPhysicalDeviceSurfacePresentModesKHR(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, uint32_t *pPresentModeCount, VkPresentModeKHR *pPresentModes) DECLSPEC_HIDDEN; +VkResult WINAPI wine_vkGetPhysicalDeviceSurfaceSupportKHR(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, VkSurfaceKHR surface, VkBool32 *pSupported) DECLSPEC_HIDDEN; +VkBool32 WINAPI wine_vkGetPhysicalDeviceWin32PresentationSupportKHR(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex) DECLSPEC_HIDDEN; +VkResult WINAPI wine_vkGetSwapchainImagesKHR(VkDevice device, VkSwapchainKHR swapchain, uint32_t *pSwapchainImageCount, VkImage *pSwapchainImages) DECLSPEC_HIDDEN; +VkResult WINAPI wine_vkQueuePresentKHR(VkQueue queue, const VkPresentInfoKHR *pPresentInfo) DECLSPEC_HIDDEN; + +typedef struct VkSwapchainCreateInfoKHR_host +{ + VkStructureType sType; + const void *pNext; + VkSwapchainCreateFlagsKHR flags; + VkSurfaceKHR surface; + uint32_t minImageCount; + VkFormat imageFormat; + VkColorSpaceKHR imageColorSpace; + VkExtent2D imageExtent; + uint32_t imageArrayLayers; + VkImageUsageFlags imageUsage; + VkSharingMode imageSharingMode; + uint32_t queueFamilyIndexCount; + const uint32_t *pQueueFamilyIndices; + VkSurfaceTransformFlagBitsKHR preTransform; + VkCompositeAlphaFlagBitsKHR compositeAlpha; + VkPresentModeKHR presentMode; + VkBool32 clipped; + VkSwapchainKHR oldSwapchain; +} VkSwapchainCreateInfoKHR_host;
typedef struct VkImageFormatProperties_host { diff --git a/dlls/winex11.drv/vulkan.c b/dlls/winex11.drv/vulkan.c index c99ca66168..eed09306d4 100644 --- a/dlls/winex11.drv/vulkan.c +++ b/dlls/winex11.drv/vulkan.c @@ -27,6 +27,10 @@
#include "wine/debug.h" #include "wine/library.h" + +/* We only want host compatible structures and don't need alignment. */ +#define WINE_VK_ALIGN(x) + #include "wine/vulkan.h" #include "wine/vulkan_driver.h"
@@ -34,11 +38,21 @@
WINE_DEFAULT_DEBUG_CHANNEL(vulkan);
+#ifndef ARRAY_SIZE +#define ARRAY_SIZE(array) (sizeof(array) / sizeof((array)[0])) +#endif + static VkResult (*pvkCreateInstance)(const VkInstanceCreateInfo *, const VkAllocationCallbacks *, VkInstance *); static void (*pvkDestroyInstance)(VkInstance, const VkAllocationCallbacks *); static void * (*pvkGetDeviceProcAddr)(VkDevice, const char *); static void * (*pvkGetInstanceProcAddr)(VkInstance, const char *);
+/* TODO: dynamically generate based on host driver capabilities. */ +struct VkExtensionProperties winex11_vk_instance_extensions[] = { + { "VK_KHR_surface", 1 }, + { "VK_KHR_win32_surface", 1}, +}; + static BOOL wine_vk_init(void) { static BOOL init_done = FALSE; @@ -59,6 +73,16 @@ LOAD_FUNCPTR(vkGetInstanceProcAddr) return TRUE; }
+static VkResult X11DRV_vkAcquireNextImageKHR(VkDevice device, VkSwapchainKHR swapchain, + uint64_t timeout, VkSemaphore semaphore, VkFence fence, uint32_t *index) +{ + FIXME("stub: %p, 0x%s, 0x%s, 0x%s, 0x%s, %p\n", device, + wine_dbgstr_longlong(swapchain), wine_dbgstr_longlong(timeout), + wine_dbgstr_longlong(semaphore), wine_dbgstr_longlong(fence), index); + + return VK_ERROR_OUT_OF_HOST_MEMORY; +} + static VkResult X11DRV_vkCreateInstance(const VkInstanceCreateInfo *create_info, const VkAllocationCallbacks *allocator, VkInstance *instance) { @@ -77,6 +101,22 @@ static VkResult X11DRV_vkCreateInstance(const VkInstanceCreateInfo *create_info, return pvkCreateInstance(create_info, NULL /* allocator */, instance); }
+static VkResult X11DRV_vkCreateSwapchainKHR(VkDevice device, + const VkSwapchainCreateInfoKHR *create_info, + const VkAllocationCallbacks *allocator, VkSwapchainKHR *swapchain) +{ + FIXME("stub: %p %p %p %p\n", device, create_info, allocator, swapchain); + return VK_ERROR_OUT_OF_HOST_MEMORY; +} + +static VkResult X11DRV_vkCreateWin32SurfaceKHR(VkInstance instance, + const VkWin32SurfaceCreateInfoKHR *create_info, + const VkAllocationCallbacks *allocator, VkSurfaceKHR *surface) +{ + FIXME("stub: %p %p %p %p\n", instance, create_info, allocator, surface); + return VK_ERROR_OUT_OF_HOST_MEMORY; +} + static void X11DRV_vkDestroyInstance(VkInstance instance, const VkAllocationCallbacks *allocator) { TRACE("%p %p\n", instance, allocator); @@ -87,10 +127,25 @@ static void X11DRV_vkDestroyInstance(VkInstance instance, const VkAllocationCall pvkDestroyInstance(instance, NULL /* allocator */); }
+static void X11DRV_vkDestroySurfaceKHR(VkInstance instance, VkSurfaceKHR surface, + const VkAllocationCallbacks *allocator) +{ + FIXME("stub: %p 0x%s %p\n", instance, wine_dbgstr_longlong(surface), allocator); +} + +static void X11DRV_vkDestroySwapchainKHR(VkDevice device, VkSwapchainKHR swapchain, + const VkAllocationCallbacks *allocator) +{ + FIXME("stub: %p, 0x%s %p\n", device, wine_dbgstr_longlong(swapchain), allocator); +} + static VkResult X11DRV_vkEnumerateInstanceExtensionProperties(const char *layer_name, uint32_t *count, VkExtensionProperties* properties) { - TRACE("layer_name %s, count %p, properties %p\n", debugstr_a(layer_name), count, properties); + VkResult res; + unsigned int i, num_copies; + + TRACE("layer_name %p, count %p, properties %p\n", debugstr_a(layer_name), count, properties);
/* This shouldn't get called with layer_name set, the ICD loader prevents it. */ if (layer_name) @@ -106,16 +161,32 @@ static VkResult X11DRV_vkEnumerateInstanceExtensionProperties(const char *layer_ * VK_KHR_win32_surface. Long-term this needs to be an intersection * between what the native library supports and what thunks we have. */ - *count = 0; + *count = ARRAY_SIZE(winex11_vk_instance_extensions); return VK_SUCCESS; }
- /* When properties is not NULL, we copy the extensions over and set count - * to the number of copied extensions. For now we don't have much to do as - * we don't support any extensions yet. - */ - *count = 0; - return VK_SUCCESS; + if (*count < ARRAY_SIZE(winex11_vk_instance_extensions)) + { + /* Incomplete is a type of success used to signal the application + * that not all devices got copied. + */ + num_copies = *count; + res = VK_INCOMPLETE; + } + else + { + num_copies = ARRAY_SIZE(winex11_vk_instance_extensions); + res = VK_SUCCESS; + } + + for (i = 0; i < num_copies; i++) + { + memcpy(&properties[i], &winex11_vk_instance_extensions[i], sizeof(winex11_vk_instance_extensions[i])); + } + *count = num_copies; + + TRACE("Result %d, extensions copied %d\n", res, num_copies); + return res; }
static void * X11DRV_vkGetDeviceProcAddr(VkDevice device, const char *name) @@ -130,13 +201,74 @@ static void * X11DRV_vkGetInstanceProcAddr(VkInstance instance, const char *name return pvkGetInstanceProcAddr(instance, name); }
-static const struct vulkan_funcs vulkan_funcs = +static VkResult X11DRV_vkGetPhysicalDeviceSurfaceCapabilitiesKHR(VkPhysicalDevice phys_dev, + VkSurfaceKHR surface, VkSurfaceCapabilitiesKHR *capabilities) +{ + FIXME("stub: %p, 0x%s, %p\n", phys_dev, wine_dbgstr_longlong(surface), capabilities); + return VK_ERROR_OUT_OF_HOST_MEMORY; +} + +static VkResult X11DRV_vkGetPhysicalDeviceSurfaceFormatsKHR(VkPhysicalDevice phys_dev, + VkSurfaceKHR surface, uint32_t *count, VkSurfaceFormatKHR *formats) +{ + FIXME("stub: %p, 0x%s, %p, %p\n", phys_dev, wine_dbgstr_longlong(surface), count, formats); + return VK_ERROR_OUT_OF_HOST_MEMORY; +} + +static VkResult X11DRV_vkGetPhysicalDeviceSurfacePresentModesKHR(VkPhysicalDevice phys_dev, + VkSurfaceKHR surface, uint32_t *count, VkPresentModeKHR *modes) +{ + FIXME("stub: %p, 0x%s, %p, %p\n", phys_dev, wine_dbgstr_longlong(surface), count, modes); + return VK_ERROR_OUT_OF_HOST_MEMORY; +} + +static VkResult X11DRV_vkGetPhysicalDeviceSurfaceSupportKHR(VkPhysicalDevice phys_dev, + uint32_t index, VkSurfaceKHR surface, VkBool32 *supported) +{ + FIXME("stub: %p, %u, 0x%s, %p\n", phys_dev, index, wine_dbgstr_longlong(surface), supported); + return VK_ERROR_OUT_OF_HOST_MEMORY; +} + +static VkBool32 X11DRV_vkGetPhysicalDeviceWin32PresentationSupportKHR(VkPhysicalDevice phys_dev, + uint32_t index) +{ + FIXME("stub %p %u\n", phys_dev, index); + return VK_FALSE; +} + +static VkResult X11DRV_vkGetSwapchainImagesKHR(VkDevice device, + VkSwapchainKHR swapchain, uint32_t *count, VkImage *images) +{ + FIXME("stub: %p, 0x%s %p %p\n", device, wine_dbgstr_longlong(swapchain), count, images); + return VK_ERROR_OUT_OF_HOST_MEMORY; +} + +static VkResult X11DRV_vkQueuePresentKHR(VkQueue queue, const VkPresentInfoKHR *present_info) +{ + FIXME("stub: %p, %p\n", queue, present_info); + return VK_ERROR_OUT_OF_HOST_MEMORY; +} + + +static struct vulkan_funcs vulkan_funcs = { + X11DRV_vkAcquireNextImageKHR, X11DRV_vkCreateInstance, + X11DRV_vkCreateSwapchainKHR, + X11DRV_vkCreateWin32SurfaceKHR, X11DRV_vkDestroyInstance, + X11DRV_vkDestroySurfaceKHR, + X11DRV_vkDestroySwapchainKHR, X11DRV_vkEnumerateInstanceExtensionProperties, X11DRV_vkGetDeviceProcAddr, - X11DRV_vkGetInstanceProcAddr + X11DRV_vkGetInstanceProcAddr, + X11DRV_vkGetPhysicalDeviceSurfaceCapabilitiesKHR, + X11DRV_vkGetPhysicalDeviceSurfaceFormatsKHR, + X11DRV_vkGetPhysicalDeviceSurfacePresentModesKHR, + X11DRV_vkGetPhysicalDeviceSurfaceSupportKHR, + X11DRV_vkGetPhysicalDeviceWin32PresentationSupportKHR, + X11DRV_vkGetSwapchainImagesKHR, + X11DRV_vkQueuePresentKHR };
const struct vulkan_funcs *get_vulkan_driver(UINT version) diff --git a/include/wine/vulkan.h b/include/wine/vulkan.h index fb0af61eb5..92dcb7d2b3 100644 --- a/include/wine/vulkan.h +++ b/include/wine/vulkan.h @@ -75,6 +75,8 @@ VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkRenderPass) VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkSampler) VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkSemaphore) VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkShaderModule) +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkSurfaceKHR) +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkSwapchainKHR)
typedef uint32_t VkBool32; typedef uint64_t VkDeviceSize; @@ -291,6 +293,12 @@ typedef enum VkColorComponentFlagBits VK_COLOR_COMPONENT_FLAG_BITS_MAX_ENUM = 0x7fffffff, } VkColorComponentFlagBits;
+typedef enum VkColorSpaceKHR +{ + VK_COLOR_SPACE_SRGB_NONLINEAR_KHR = 0, + VK_COLOR_SPACE_KHR_MAX_ENUM = 0x7fffffff, +} VkColorSpaceKHR; + typedef enum VkCommandBufferLevel { VK_COMMAND_BUFFER_LEVEL_PRIMARY = 0, @@ -338,6 +346,15 @@ typedef enum VkComponentSwizzle VK_COMPONENT_SWIZZLE_MAX_ENUM = 0x7fffffff, } VkComponentSwizzle;
+typedef enum VkCompositeAlphaFlagBitsKHR +{ + VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR = 0x00000001, + VK_COMPOSITE_ALPHA_PRE_MULTIPLIED_BIT_KHR = 0x00000002, + VK_COMPOSITE_ALPHA_POST_MULTIPLIED_BIT_KHR = 0x00000004, + VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR = 0x00000008, + VK_COMPOSITE_ALPHA_FLAG_BITS_KHR_MAX_ENUM = 0x7fffffff, +} VkCompositeAlphaFlagBitsKHR; + typedef enum VkCullModeFlagBits { VK_CULL_MODE_NONE = 0, @@ -652,6 +669,7 @@ typedef enum VkImageLayout VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL = 6, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL = 7, VK_IMAGE_LAYOUT_PREINITIALIZED = 8, + VK_IMAGE_LAYOUT_PRESENT_SRC_KHR = 1000001002, VK_IMAGE_LAYOUT_MAX_ENUM = 0x7fffffff, } VkImageLayout;
@@ -773,6 +791,8 @@ typedef enum VkObjectType VK_OBJECT_TYPE_DESCRIPTOR_SET = 23, VK_OBJECT_TYPE_FRAMEBUFFER = 24, VK_OBJECT_TYPE_COMMAND_POOL = 25, + VK_OBJECT_TYPE_SURFACE_KHR = 1000000000, + VK_OBJECT_TYPE_SWAPCHAIN_KHR = 1000001000, VK_OBJECT_TYPE_MAX_ENUM = 0x7fffffff, } VkObjectType;
@@ -837,6 +857,15 @@ typedef enum VkPolygonMode VK_POLYGON_MODE_MAX_ENUM = 0x7fffffff, } VkPolygonMode;
+typedef enum VkPresentModeKHR +{ + VK_PRESENT_MODE_IMMEDIATE_KHR = 0, + VK_PRESENT_MODE_MAILBOX_KHR = 1, + VK_PRESENT_MODE_FIFO_KHR = 2, + VK_PRESENT_MODE_FIFO_RELAXED_KHR = 3, + VK_PRESENT_MODE_KHR_MAX_ENUM = 0x7fffffff, +} VkPresentModeKHR; + typedef enum VkPrimitiveTopology { VK_PRIMITIVE_TOPOLOGY_POINT_LIST = 0, @@ -894,6 +923,9 @@ typedef enum VkQueueFlagBits
typedef enum VkResult { + VK_ERROR_OUT_OF_DATE_KHR = -1000001004, + VK_ERROR_NATIVE_WINDOW_IN_USE_KHR = -1000000001, + VK_ERROR_SURFACE_LOST_KHR = -1000000000, VK_ERROR_FRAGMENTED_POOL = -12, VK_ERROR_FORMAT_NOT_SUPPORTED = -11, VK_ERROR_TOO_MANY_OBJECTS = -10, @@ -912,6 +944,7 @@ typedef enum VkResult VK_EVENT_SET = 3, VK_EVENT_RESET = 4, VK_INCOMPLETE = 5, + VK_SUBOPTIMAL_KHR = 1000001003, VK_RESULT_MAX_ENUM = 0x7fffffff, } VkResult;
@@ -1041,6 +1074,9 @@ typedef enum VkStructureType VK_STRUCTURE_TYPE_MEMORY_BARRIER = 46, VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO = 47, VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO = 48, + VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR = 1000001000, + VK_STRUCTURE_TYPE_PRESENT_INFO_KHR = 1000001001, + VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR = 1000009000, VK_STRUCTURE_TYPE_MAX_ENUM = 0x7fffffff, } VkStructureType;
@@ -1056,6 +1092,25 @@ typedef enum VkSubpassDescriptionFlagBits VK_SUBPASS_DESCRIPTION_FLAG_BITS_MAX_ENUM = 0x7fffffff, } VkSubpassDescriptionFlagBits;
+typedef enum VkSurfaceTransformFlagBitsKHR +{ + VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR = 0x00000001, + VK_SURFACE_TRANSFORM_ROTATE_90_BIT_KHR = 0x00000002, + VK_SURFACE_TRANSFORM_ROTATE_180_BIT_KHR = 0x00000004, + VK_SURFACE_TRANSFORM_ROTATE_270_BIT_KHR = 0x00000008, + VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_BIT_KHR = 0x00000010, + VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_90_BIT_KHR = 0x00000020, + VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_180_BIT_KHR = 0x00000040, + VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_270_BIT_KHR = 0x00000080, + VK_SURFACE_TRANSFORM_INHERIT_BIT_KHR = 0x00000100, + VK_SURFACE_TRANSFORM_FLAG_BITS_KHR_MAX_ENUM = 0x7fffffff, +} VkSurfaceTransformFlagBitsKHR; + +typedef enum VkSwapchainCreateFlagBitsKHR +{ + VK_SWAPCHAIN_CREATE_FLAG_BITS_KHR_MAX_ENUM = 0x7fffffff, +} VkSwapchainCreateFlagBitsKHR; + typedef enum VkSystemAllocationScope { VK_SYSTEM_ALLOCATION_SCOPE_COMMAND = 0, @@ -1439,6 +1494,18 @@ typedef struct VkPipelineTessellationStateCreateInfo uint32_t patchControlPoints; } VkPipelineTessellationStateCreateInfo;
+typedef struct VkPresentInfoKHR +{ + VkStructureType sType; + const void *pNext; + uint32_t waitSemaphoreCount; + const VkSemaphore *pWaitSemaphores; + uint32_t swapchainCount; + const VkSwapchainKHR *pSwapchains; + const uint32_t *pImageIndices; + VkResult *pResults; +} VkPresentInfoKHR; + typedef struct VkQueryPoolCreateInfo { VkStructureType sType; @@ -1745,6 +1812,12 @@ typedef struct VkSubpassDependency VkDependencyFlags dependencyFlags; } VkSubpassDependency;
+typedef struct VkSurfaceFormatKHR +{ + VkFormat format; + VkColorSpaceKHR colorSpace; +} VkSurfaceFormatKHR; + typedef struct VkViewport { float x; @@ -1901,6 +1974,28 @@ typedef struct VkSubpassDescription const uint32_t *pPreserveAttachments; } VkSubpassDescription;
+typedef struct VkSwapchainCreateInfoKHR +{ + VkStructureType sType; + const void *pNext; + VkSwapchainCreateFlagsKHR flags; + VkSurfaceKHR WINE_VK_ALIGN(8) surface; + uint32_t minImageCount; + VkFormat imageFormat; + VkColorSpaceKHR imageColorSpace; + VkExtent2D imageExtent; + uint32_t imageArrayLayers; + VkImageUsageFlags imageUsage; + VkSharingMode imageSharingMode; + uint32_t queueFamilyIndexCount; + const uint32_t *pQueueFamilyIndices; + VkSurfaceTransformFlagBitsKHR preTransform; + VkCompositeAlphaFlagBitsKHR compositeAlpha; + VkPresentModeKHR presentMode; + VkBool32 clipped; + VkSwapchainKHR WINE_VK_ALIGN(8) oldSwapchain; +} VkSwapchainCreateInfoKHR; + typedef struct VkClearAttachment { VkImageAspectFlags aspectMask; @@ -1987,6 +2082,29 @@ typedef struct VkRenderPassBeginInfo const VkClearValue *pClearValues; } VkRenderPassBeginInfo;
+typedef struct VkSurfaceCapabilitiesKHR +{ + uint32_t minImageCount; + uint32_t maxImageCount; + VkExtent2D currentExtent; + VkExtent2D minImageExtent; + VkExtent2D maxImageExtent; + uint32_t maxImageArrayLayers; + VkSurfaceTransformFlagsKHR supportedTransforms; + VkSurfaceTransformFlagBitsKHR currentTransform; + VkCompositeAlphaFlagsKHR supportedCompositeAlpha; + VkImageUsageFlags supportedUsageFlags; +} VkSurfaceCapabilitiesKHR; + +typedef struct VkWin32SurfaceCreateInfoKHR +{ + VkStructureType sType; + const void *pNext; + VkWin32SurfaceCreateFlagsKHR flags; + HINSTANCE hinstance; + HWND hwnd; +} VkWin32SurfaceCreateInfoKHR; + typedef struct VkBindSparseInfo { VkStructureType sType; @@ -2282,6 +2400,7 @@ typedef struct VkGraphicsPipelineCreateInfo int32_t basePipelineIndex; } VkGraphicsPipelineCreateInfo;
+VkResult VKAPI_CALL vkAcquireNextImageKHR(VkDevice device, VkSwapchainKHR swapchain, uint64_t timeout, VkSemaphore semaphore, VkFence fence, uint32_t *pImageIndex); VkResult VKAPI_CALL vkAllocateCommandBuffers(VkDevice device, const VkCommandBufferAllocateInfo *pAllocateInfo, VkCommandBuffer *pCommandBuffers); VkResult VKAPI_CALL vkAllocateDescriptorSets(VkDevice device, const VkDescriptorSetAllocateInfo *pAllocateInfo, VkDescriptorSet *pDescriptorSets); VkResult VKAPI_CALL vkAllocateMemory(VkDevice device, const VkMemoryAllocateInfo *pAllocateInfo, const VkAllocationCallbacks *pAllocator, VkDeviceMemory *pMemory); @@ -2353,6 +2472,8 @@ VkResult VKAPI_CALL vkCreateRenderPass(VkDevice device, const VkRenderPassCreate VkResult VKAPI_CALL vkCreateSampler(VkDevice device, const VkSamplerCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkSampler *pSampler); VkResult VKAPI_CALL vkCreateSemaphore(VkDevice device, const VkSemaphoreCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkSemaphore *pSemaphore); VkResult VKAPI_CALL vkCreateShaderModule(VkDevice device, const VkShaderModuleCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkShaderModule *pShaderModule); +VkResult VKAPI_CALL vkCreateSwapchainKHR(VkDevice device, const VkSwapchainCreateInfoKHR *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkSwapchainKHR *pSwapchain); +VkResult VKAPI_CALL vkCreateWin32SurfaceKHR(VkInstance instance, const VkWin32SurfaceCreateInfoKHR *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface); void VKAPI_CALL vkDestroyBuffer(VkDevice device, VkBuffer buffer, const VkAllocationCallbacks *pAllocator); void VKAPI_CALL vkDestroyBufferView(VkDevice device, VkBufferView bufferView, const VkAllocationCallbacks *pAllocator); void VKAPI_CALL vkDestroyCommandPool(VkDevice device, VkCommandPool commandPool, const VkAllocationCallbacks *pAllocator); @@ -2373,6 +2494,8 @@ void VKAPI_CALL vkDestroyRenderPass(VkDevice device, VkRenderPass renderPass, co void VKAPI_CALL vkDestroySampler(VkDevice device, VkSampler sampler, const VkAllocationCallbacks *pAllocator); void VKAPI_CALL vkDestroySemaphore(VkDevice device, VkSemaphore semaphore, const VkAllocationCallbacks *pAllocator); void VKAPI_CALL vkDestroyShaderModule(VkDevice device, VkShaderModule shaderModule, const VkAllocationCallbacks *pAllocator); +void VKAPI_CALL vkDestroySurfaceKHR(VkInstance instance, VkSurfaceKHR surface, const VkAllocationCallbacks *pAllocator); +void VKAPI_CALL vkDestroySwapchainKHR(VkDevice device, VkSwapchainKHR swapchain, const VkAllocationCallbacks *pAllocator); VkResult VKAPI_CALL vkDeviceWaitIdle(VkDevice device); VkResult VKAPI_CALL vkEndCommandBuffer(VkCommandBuffer commandBuffer); VkResult VKAPI_CALL vkEnumerateDeviceExtensionProperties(VkPhysicalDevice physicalDevice, const char *pLayerName, uint32_t *pPropertyCount, VkExtensionProperties *pProperties); @@ -2401,13 +2524,20 @@ void VKAPI_CALL vkGetPhysicalDeviceMemoryProperties(VkPhysicalDevice physicalDev void VKAPI_CALL vkGetPhysicalDeviceProperties(VkPhysicalDevice physicalDevice, VkPhysicalDeviceProperties *pProperties); void VKAPI_CALL vkGetPhysicalDeviceQueueFamilyProperties(VkPhysicalDevice physicalDevice, uint32_t *pQueueFamilyPropertyCount, VkQueueFamilyProperties *pQueueFamilyProperties); void VKAPI_CALL vkGetPhysicalDeviceSparseImageFormatProperties(VkPhysicalDevice physicalDevice, VkFormat format, VkImageType type, VkSampleCountFlagBits samples, VkImageUsageFlags usage, VkImageTiling tiling, uint32_t *pPropertyCount, VkSparseImageFormatProperties *pProperties); +VkResult VKAPI_CALL vkGetPhysicalDeviceSurfaceCapabilitiesKHR(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, VkSurfaceCapabilitiesKHR *pSurfaceCapabilities); +VkResult VKAPI_CALL vkGetPhysicalDeviceSurfaceFormatsKHR(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, uint32_t *pSurfaceFormatCount, VkSurfaceFormatKHR *pSurfaceFormats); +VkResult VKAPI_CALL vkGetPhysicalDeviceSurfacePresentModesKHR(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, uint32_t *pPresentModeCount, VkPresentModeKHR *pPresentModes); +VkResult VKAPI_CALL vkGetPhysicalDeviceSurfaceSupportKHR(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, VkSurfaceKHR surface, VkBool32 *pSupported); +VkBool32 VKAPI_CALL vkGetPhysicalDeviceWin32PresentationSupportKHR(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex); VkResult VKAPI_CALL vkGetPipelineCacheData(VkDevice device, VkPipelineCache pipelineCache, size_t *pDataSize, void *pData); VkResult VKAPI_CALL vkGetQueryPoolResults(VkDevice device, VkQueryPool queryPool, uint32_t firstQuery, uint32_t queryCount, size_t dataSize, void *pData, VkDeviceSize stride, VkQueryResultFlags flags); void VKAPI_CALL vkGetRenderAreaGranularity(VkDevice device, VkRenderPass renderPass, VkExtent2D *pGranularity); +VkResult VKAPI_CALL vkGetSwapchainImagesKHR(VkDevice device, VkSwapchainKHR swapchain, uint32_t *pSwapchainImageCount, VkImage *pSwapchainImages); VkResult VKAPI_CALL vkInvalidateMappedMemoryRanges(VkDevice device, uint32_t memoryRangeCount, const VkMappedMemoryRange *pMemoryRanges); VkResult VKAPI_CALL vkMapMemory(VkDevice device, VkDeviceMemory memory, VkDeviceSize offset, VkDeviceSize size, VkMemoryMapFlags flags, void **ppData); VkResult VKAPI_CALL vkMergePipelineCaches(VkDevice device, VkPipelineCache dstCache, uint32_t srcCacheCount, const VkPipelineCache *pSrcCaches); VkResult VKAPI_CALL vkQueueBindSparse(VkQueue queue, uint32_t bindInfoCount, const VkBindSparseInfo *pBindInfo, VkFence fence); +VkResult VKAPI_CALL vkQueuePresentKHR(VkQueue queue, const VkPresentInfoKHR *pPresentInfo); VkResult VKAPI_CALL vkQueueSubmit(VkQueue queue, uint32_t submitCount, const VkSubmitInfo *pSubmits, VkFence fence); VkResult VKAPI_CALL vkQueueWaitIdle(VkQueue queue); VkResult VKAPI_CALL vkResetCommandBuffer(VkCommandBuffer commandBuffer, VkCommandBufferResetFlags flags); diff --git a/include/wine/vulkan_driver.h b/include/wine/vulkan_driver.h index 8d69222e03..60d16dd52a 100644 --- a/include/wine/vulkan_driver.h +++ b/include/wine/vulkan_driver.h @@ -4,7 +4,7 @@ #define __WINE_VULKAN_DRIVER_H
/* Wine internal vulkan driver version, needs to be bumped upon vulkan_funcs changes. */ -#define WINE_VULKAN_DRIVER_VERSION 2 +#define WINE_VULKAN_DRIVER_VERSION 3
struct vulkan_funcs { @@ -12,11 +12,23 @@ struct vulkan_funcs * needs to provide. Other function calls will be provided indirectly by dispatch * tables part of dispatchable Vulkan objects such as VkInstance or vkDevice. */ + VkResult (*p_vkAcquireNextImageKHR)(VkDevice, VkSwapchainKHR, uint64_t, VkSemaphore, VkFence, uint32_t *); VkResult (*p_vkCreateInstance)(const VkInstanceCreateInfo *, const VkAllocationCallbacks *, VkInstance *); + VkResult (*p_vkCreateSwapchainKHR)(VkDevice, const VkSwapchainCreateInfoKHR *, const VkAllocationCallbacks *, VkSwapchainKHR *); + VkResult (*p_vkCreateWin32SurfaceKHR)(VkInstance, const VkWin32SurfaceCreateInfoKHR *, const VkAllocationCallbacks *, VkSurfaceKHR *); void (*p_vkDestroyInstance)(VkInstance, const VkAllocationCallbacks *); + void (*p_vkDestroySurfaceKHR)(VkInstance, VkSurfaceKHR, const VkAllocationCallbacks *); + void (*p_vkDestroySwapchainKHR)(VkDevice, VkSwapchainKHR, const VkAllocationCallbacks *); VkResult (*p_vkEnumerateInstanceExtensionProperties)(const char *, uint32_t *, VkExtensionProperties *); void * (*p_vkGetDeviceProcAddr)(VkDevice, const char *); void * (*p_vkGetInstanceProcAddr)(VkInstance, const char *); + VkResult (*p_vkGetPhysicalDeviceSurfaceCapabilitiesKHR)(VkPhysicalDevice, VkSurfaceKHR, VkSurfaceCapabilitiesKHR *); + VkResult (*p_vkGetPhysicalDeviceSurfaceFormatsKHR)(VkPhysicalDevice, VkSurfaceKHR, uint32_t *, VkSurfaceFormatKHR *); + VkResult (*p_vkGetPhysicalDeviceSurfacePresentModesKHR)(VkPhysicalDevice, VkSurfaceKHR, uint32_t *, VkPresentModeKHR *); + VkResult (*p_vkGetPhysicalDeviceSurfaceSupportKHR)(VkPhysicalDevice, uint32_t, VkSurfaceKHR, VkBool32 *); + VkBool32 (*p_vkGetPhysicalDeviceWin32PresentationSupportKHR)(VkPhysicalDevice, uint32_t); + VkResult (*p_vkGetSwapchainImagesKHR)(VkDevice, VkSwapchainKHR, uint32_t *, VkImage *); + VkResult (*p_vkQueuePresentKHR)(VkQueue, const VkPresentInfoKHR *); };
extern const struct vulkan_funcs * CDECL __wine_get_vulkan_driver(HDC hdc, UINT version);
Signed-off-by: Roderick Colenbrander thunderbird2k@gmail.com --- dlls/winevulkan/vulkan.c | 69 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 68 insertions(+), 1 deletion(-)
diff --git a/dlls/winevulkan/vulkan.c b/dlls/winevulkan/vulkan.c index b17e290a66..a25015d806 100644 --- a/dlls/winevulkan/vulkan.c +++ b/dlls/winevulkan/vulkan.c @@ -38,6 +38,13 @@ WINE_DEFAULT_DEBUG_CHANNEL(vulkan); */ #define WINE_VULKAN_ICD_VERSION 4
+/* All Vulkan structures use this structure for the first elements. */ +struct wine_vk_structure_header +{ + VkStructureType sType; + const void *pNext; +}; + static void *wine_vk_get_global_proc_addr(const char *name);
static const struct vulkan_funcs *vk_funcs = NULL; @@ -74,6 +81,58 @@ static BOOL wine_vk_init(void) return TRUE; }
+/* Helper function for converting between win32 and host compatible VkInstanceCreateInfo. + * This function takes care of extensions handled at winevulkan layer, a Wine graphics + * driver is responsible for handling e.g. surface extensions. + */ +static VkResult wine_vk_instance_convert_create_info(const VkInstanceCreateInfo *src, + VkInstanceCreateInfo *dst) +{ + dst->sType = src->sType; + dst->flags = src->flags; + dst->pApplicationInfo = src->pApplicationInfo; + + /* Application and loader can pass in a chain of extensions through pNext. + * We can't blindy pass these through as often these contain callbacks or + * they can even be pass structures for loader / ICD internal use. For now + * we ignore everything in pNext chain, but we print FIXMEs. + */ + if (src->pNext) + { + const struct wine_vk_structure_header *header; + + for (header = src->pNext; header; header = header->pNext) + { + switch (header->sType) + { + case VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO: + /* Can be used to register new dispatchable object types + * to the loader. We should ignore it as it will confuse the + * host its loader. + */ + break; + + default: + FIXME("Application requested a linked structure of type %d\n", header->sType); + } + } + } + /* For now don't support anything. */ + dst->pNext = NULL; + + /* ICDs don't support any layers, so nothing to copy. Modern versions of the loader + * filter this data out as well. + */ + dst->enabledLayerCount = 0; + dst->ppEnabledLayerNames = NULL; + + /* TODO: convert non-WSI win32 extensions here to host specific ones. */ + dst->ppEnabledExtensionNames = src->ppEnabledExtensionNames; + dst->enabledExtensionCount = src->enabledExtensionCount; + + return VK_SUCCESS; +} + /* Helper function which stores wrapped physical devices in the instance object. */ static VkResult wine_vk_instance_load_physical_devices(struct VkInstance_T *instance) { @@ -229,6 +288,7 @@ static VkResult WINAPI wine_vkCreateInstance(const VkInstanceCreateInfo *create_ const VkAllocationCallbacks *allocator, VkInstance *instance) { struct VkInstance_T *object = NULL; + VkInstanceCreateInfo create_info_host; VkResult res;
TRACE("create_info %p, allocator %p, instance %p\n", create_info, allocator, instance); @@ -245,7 +305,14 @@ static VkResult WINAPI wine_vkCreateInstance(const VkInstanceCreateInfo *create_ } object->base.loader_magic = VULKAN_ICD_MAGIC_VALUE;
- res = vk_funcs->p_vkCreateInstance(create_info, NULL /* allocator */, &object->instance); + res = wine_vk_instance_convert_create_info(create_info, &create_info_host); + if (res != VK_SUCCESS) + { + ERR("Failed to convert instance create info, res=%d\n", res); + goto err; + } + + res = vk_funcs->p_vkCreateInstance(&create_info_host, NULL /* allocator */, &object->instance); if (res != VK_SUCCESS) { ERR("Failed to create instance, res=%d\n", res);
Signed-off-by: Roderick Colenbrander thunderbird2k@gmail.com --- dlls/winex11.drv/vulkan.c | 68 +++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 63 insertions(+), 5 deletions(-)
diff --git a/dlls/winex11.drv/vulkan.c b/dlls/winex11.drv/vulkan.c index eed09306d4..f93708c674 100644 --- a/dlls/winex11.drv/vulkan.c +++ b/dlls/winex11.drv/vulkan.c @@ -26,6 +26,7 @@ #include "winbase.h"
#include "wine/debug.h" +#include "wine/heap.h" #include "wine/library.h"
/* We only want host compatible structures and don't need alignment. */ @@ -73,6 +74,54 @@ LOAD_FUNCPTR(vkGetInstanceProcAddr) return TRUE; }
+/* Helper function for converting between win32 and X11 compatible VkInstanceCreateInfo. + * Caller is responsible for allocation and cleanup of 'dst'. + */ +static VkResult wine_vk_instance_convert_create_info(const VkInstanceCreateInfo *src, + VkInstanceCreateInfo *dst) +{ + unsigned int i; + const char **enabled_extensions = NULL; + + dst->sType = src->sType; + dst->flags = src->flags; + dst->pApplicationInfo = src->pApplicationInfo; + dst->pNext = src->pNext; + dst->enabledLayerCount = 0; + dst->ppEnabledLayerNames = NULL; + dst->enabledExtensionCount = 0; + dst->ppEnabledExtensionNames = NULL; + + if (src->enabledExtensionCount > 0) + { + enabled_extensions = heap_calloc(src->enabledExtensionCount, sizeof(*src->ppEnabledExtensionNames)); + if (!enabled_extensions) + { + ERR("Failed to allocate memory for enabled extensions\n"); + return VK_ERROR_OUT_OF_HOST_MEMORY; + } + + for (i = 0; i < src->enabledExtensionCount; i++) + { + /* Substitute extension with X11 ones else copy. Long-term, when we + * support more extensions, we should store these in a list. + */ + if (!strcmp(src->ppEnabledExtensionNames[i], "VK_KHR_win32_surface")) + { + enabled_extensions[i] = "VK_KHR_xlib_surface"; + } + else + { + enabled_extensions[i] = src->ppEnabledExtensionNames[i]; + } + } + dst->ppEnabledExtensionNames = (const char**)enabled_extensions; + dst->enabledExtensionCount = src->enabledExtensionCount; + } + + return VK_SUCCESS; +} + static VkResult X11DRV_vkAcquireNextImageKHR(VkDevice device, VkSwapchainKHR swapchain, uint64_t timeout, VkSemaphore semaphore, VkFence fence, uint32_t *index) { @@ -86,19 +135,28 @@ static VkResult X11DRV_vkAcquireNextImageKHR(VkDevice device, VkSwapchainKHR swa static VkResult X11DRV_vkCreateInstance(const VkInstanceCreateInfo *create_info, const VkAllocationCallbacks *allocator, VkInstance *instance) { + VkInstanceCreateInfo create_info_host; + VkResult res; TRACE("create_info %p, allocator %p, instance %p\n", create_info, allocator, instance);
if (allocator) FIXME("Support for allocation callbacks not implemented yet\n");
- /* TODO: convert win32 to x11 extensions here. */ - if (create_info->enabledExtensionCount > 0) + /* Perform a second pass on converting VkInstanceCreateInfo. Winevulkan + * performed a first pass in which it handles everything except for WSI + * functionality such as VK_KHR_win32_surface. Handle this now. + */ + res = wine_vk_instance_convert_create_info(create_info, &create_info_host); + if (res != VK_SUCCESS) { - FIXME("Extensions are not supported yet, aborting!\n"); - return VK_ERROR_INCOMPATIBLE_DRIVER; + ERR("Failed to convert instance create info, res=%d\n", res); + return res; }
- return pvkCreateInstance(create_info, NULL /* allocator */, instance); + res = pvkCreateInstance(&create_info_host, NULL /* allocator */, instance); + + heap_free((void *)create_info_host.ppEnabledExtensionNames); + return res; }
static VkResult X11DRV_vkCreateSwapchainKHR(VkDevice device,
Implement surface creation for top-level windows. Child window rendering is not yet supported.
Signed-off-by: Roderick Colenbrander thunderbird2k@gmail.com --- dlls/winex11.drv/vulkan.c | 66 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 64 insertions(+), 2 deletions(-)
diff --git a/dlls/winex11.drv/vulkan.c b/dlls/winex11.drv/vulkan.c index f93708c674..c5ecfd362b 100644 --- a/dlls/winex11.drv/vulkan.c +++ b/dlls/winex11.drv/vulkan.c @@ -28,6 +28,7 @@ #include "wine/debug.h" #include "wine/heap.h" #include "wine/library.h" +#include "x11drv.h"
/* We only want host compatible structures and don't need alignment. */ #define WINE_VK_ALIGN(x) @@ -43,7 +44,26 @@ WINE_DEFAULT_DEBUG_CHANNEL(vulkan); #define ARRAY_SIZE(array) (sizeof(array) / sizeof((array)[0])) #endif
+typedef VkFlags VkXlibSurfaceCreateFlagsKHR; +#define VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR 1000004000 + +struct wine_vk_surface +{ + Window window; + VkSurfaceKHR surface; /* native surface */ +}; + +typedef struct VkXlibSurfaceCreateInfoKHR +{ + VkStructureType sType; + const void *pNext; + VkXlibSurfaceCreateFlagsKHR flags; + Display *dpy; + Window window; +} VkXlibSurfaceCreateInfoKHR; + static VkResult (*pvkCreateInstance)(const VkInstanceCreateInfo *, const VkAllocationCallbacks *, VkInstance *); +static VkResult (*pvkCreateXlibSurfaceKHR)(VkInstance, const VkXlibSurfaceCreateInfoKHR *, const VkAllocationCallbacks *, VkSurfaceKHR *); static void (*pvkDestroyInstance)(VkInstance, const VkAllocationCallbacks *); static void * (*pvkGetDeviceProcAddr)(VkDevice, const char *); static void * (*pvkGetInstanceProcAddr)(VkInstance, const char *); @@ -66,6 +86,7 @@ static BOOL wine_vk_init(void)
#define LOAD_FUNCPTR(f) if((p##f = wine_dlsym(vulkan_handle, #f, NULL, 0)) == NULL) return FALSE; LOAD_FUNCPTR(vkCreateInstance) +LOAD_FUNCPTR(vkCreateXlibSurfaceKHR) LOAD_FUNCPTR(vkDestroyInstance) LOAD_FUNCPTR(vkGetDeviceProcAddr) LOAD_FUNCPTR(vkGetInstanceProcAddr) @@ -171,8 +192,49 @@ static VkResult X11DRV_vkCreateWin32SurfaceKHR(VkInstance instance, const VkWin32SurfaceCreateInfoKHR *create_info, const VkAllocationCallbacks *allocator, VkSurfaceKHR *surface) { - FIXME("stub: %p %p %p %p\n", instance, create_info, allocator, surface); - return VK_ERROR_OUT_OF_HOST_MEMORY; + VkResult res; + VkXlibSurfaceCreateInfoKHR create_info_host; + struct wine_vk_surface *x11_surface; + Window win; + + TRACE("%p %p %p %p\n", instance, create_info, allocator, surface); + + if (allocator) + FIXME("Support for allocation callbacks not implemented yet\n"); + + /* TODO: support child window rendering. */ + if (GetAncestor(create_info->hwnd, GA_PARENT) != GetDesktopWindow()) + { + FIXME("Application requires child window rendering, which is not implemented yet!\n"); + return VK_ERROR_INCOMPATIBLE_DRIVER; + } + + win = create_client_window(create_info->hwnd, &default_visual); + if (!win) + return VK_ERROR_OUT_OF_HOST_MEMORY; + + x11_surface = heap_alloc(sizeof(*x11_surface)); + if (!x11_surface) + return VK_ERROR_OUT_OF_HOST_MEMORY; + x11_surface->window = win; + + create_info_host.sType = VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR; + create_info_host.pNext = NULL; + create_info_host.flags = 0; /* reserved */ + create_info_host.dpy = gdi_display; + create_info_host.window = x11_surface->window; + + res = pvkCreateXlibSurfaceKHR(instance, &create_info_host, NULL /* allocator */, &x11_surface->surface); + if (res != VK_SUCCESS) + { + heap_free(x11_surface); + return res; + } + + *surface = (uintptr_t)x11_surface; + + TRACE("Created surface=0x%s\n", wine_dbgstr_longlong(*surface)); + return VK_SUCCESS; }
static void X11DRV_vkDestroyInstance(VkInstance instance, const VkAllocationCallbacks *allocator)
On Mon, Mar 12, 2018 at 1:21 AM, Roderick Colenbrander thunderbird2k@gmail.com wrote:
Implement surface creation for top-level windows. Child window rendering is not yet supported.
Signed-off-by: Roderick Colenbrander thunderbird2k@gmail.com
dlls/winex11.drv/vulkan.c | 66 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 64 insertions(+), 2 deletions(-)
diff --git a/dlls/winex11.drv/vulkan.c b/dlls/winex11.drv/vulkan.c index f93708c674..c5ecfd362b 100644 --- a/dlls/winex11.drv/vulkan.c +++ b/dlls/winex11.drv/vulkan.c @@ -28,6 +28,7 @@ #include "wine/debug.h" #include "wine/heap.h" #include "wine/library.h" +#include "x11drv.h"
/* We only want host compatible structures and don't need alignment. */ #define WINE_VK_ALIGN(x) @@ -43,7 +44,26 @@ WINE_DEFAULT_DEBUG_CHANNEL(vulkan); #define ARRAY_SIZE(array) (sizeof(array) / sizeof((array)[0])) #endif
+typedef VkFlags VkXlibSurfaceCreateFlagsKHR; +#define VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR 1000004000
+struct wine_vk_surface +{
- Window window;
- VkSurfaceKHR surface; /* native surface */
+};
+typedef struct VkXlibSurfaceCreateInfoKHR +{
- VkStructureType sType;
- const void *pNext;
- VkXlibSurfaceCreateFlagsKHR flags;
- Display *dpy;
- Window window;
+} VkXlibSurfaceCreateInfoKHR;
static VkResult (*pvkCreateInstance)(const VkInstanceCreateInfo *, const VkAllocationCallbacks *, VkInstance *); +static VkResult (*pvkCreateXlibSurfaceKHR)(VkInstance, const VkXlibSurfaceCreateInfoKHR *, const VkAllocationCallbacks *, VkSurfaceKHR *); static void (*pvkDestroyInstance)(VkInstance, const VkAllocationCallbacks *); static void * (*pvkGetDeviceProcAddr)(VkDevice, const char *); static void * (*pvkGetInstanceProcAddr)(VkInstance, const char *); @@ -66,6 +86,7 @@ static BOOL wine_vk_init(void)
#define LOAD_FUNCPTR(f) if((p##f = wine_dlsym(vulkan_handle, #f, NULL, 0)) == NULL) return FALSE; LOAD_FUNCPTR(vkCreateInstance) +LOAD_FUNCPTR(vkCreateXlibSurfaceKHR) LOAD_FUNCPTR(vkDestroyInstance) LOAD_FUNCPTR(vkGetDeviceProcAddr) LOAD_FUNCPTR(vkGetInstanceProcAddr) @@ -171,8 +192,49 @@ static VkResult X11DRV_vkCreateWin32SurfaceKHR(VkInstance instance, const VkWin32SurfaceCreateInfoKHR *create_info, const VkAllocationCallbacks *allocator, VkSurfaceKHR *surface) {
- FIXME("stub: %p %p %p %p\n", instance, create_info, allocator, surface);
- return VK_ERROR_OUT_OF_HOST_MEMORY;
- VkResult res;
- VkXlibSurfaceCreateInfoKHR create_info_host;
- struct wine_vk_surface *x11_surface;
- Window win;
- TRACE("%p %p %p %p\n", instance, create_info, allocator, surface);
- if (allocator)
FIXME("Support for allocation callbacks not implemented yet\n");
- /* TODO: support child window rendering. */
- if (GetAncestor(create_info->hwnd, GA_PARENT) != GetDesktopWindow())
- {
FIXME("Application requires child window rendering, which is not implemented yet!\n");
return VK_ERROR_INCOMPATIBLE_DRIVER;
- }
- win = create_client_window(create_info->hwnd, &default_visual);
- if (!win)
return VK_ERROR_OUT_OF_HOST_MEMORY;
- x11_surface = heap_alloc(sizeof(*x11_surface));
- if (!x11_surface)
return VK_ERROR_OUT_OF_HOST_MEMORY;
If it fails the client window isn't destroyed.
- x11_surface->window = win;
- create_info_host.sType = VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR;
- create_info_host.pNext = NULL;
- create_info_host.flags = 0; /* reserved */
- create_info_host.dpy = gdi_display;
- create_info_host.window = x11_surface->window;
- res = pvkCreateXlibSurfaceKHR(instance, &create_info_host, NULL /* allocator */, &x11_surface->surface);
- if (res != VK_SUCCESS)
- {
heap_free(x11_surface);
return res;
- }
Same as above.
- *surface = (uintptr_t)x11_surface;
- TRACE("Created surface=0x%s\n", wine_dbgstr_longlong(*surface));
- return VK_SUCCESS;
}
static void X11DRV_vkDestroyInstance(VkInstance instance, const VkAllocationCallbacks *allocator)
2.14.3
On Mon, Mar 12, 2018 at 7:58 AM, Józef Kucia joseph.kucia@gmail.com wrote:
On Mon, Mar 12, 2018 at 1:21 AM, Roderick Colenbrander thunderbird2k@gmail.com wrote:
Implement surface creation for top-level windows. Child window rendering is not yet supported.
Signed-off-by: Roderick Colenbrander thunderbird2k@gmail.com
dlls/winex11.drv/vulkan.c | 66 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 64 insertions(+), 2 deletions(-)
diff --git a/dlls/winex11.drv/vulkan.c b/dlls/winex11.drv/vulkan.c index f93708c674..c5ecfd362b 100644 --- a/dlls/winex11.drv/vulkan.c +++ b/dlls/winex11.drv/vulkan.c @@ -28,6 +28,7 @@ #include "wine/debug.h" #include "wine/heap.h" #include "wine/library.h" +#include "x11drv.h"
/* We only want host compatible structures and don't need alignment. */ #define WINE_VK_ALIGN(x) @@ -43,7 +44,26 @@ WINE_DEFAULT_DEBUG_CHANNEL(vulkan); #define ARRAY_SIZE(array) (sizeof(array) / sizeof((array)[0])) #endif
+typedef VkFlags VkXlibSurfaceCreateFlagsKHR; +#define VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR 1000004000
+struct wine_vk_surface +{
- Window window;
- VkSurfaceKHR surface; /* native surface */
+};
+typedef struct VkXlibSurfaceCreateInfoKHR +{
- VkStructureType sType;
- const void *pNext;
- VkXlibSurfaceCreateFlagsKHR flags;
- Display *dpy;
- Window window;
+} VkXlibSurfaceCreateInfoKHR;
static VkResult (*pvkCreateInstance)(const VkInstanceCreateInfo *, const VkAllocationCallbacks *, VkInstance *); +static VkResult (*pvkCreateXlibSurfaceKHR)(VkInstance, const VkXlibSurfaceCreateInfoKHR *, const VkAllocationCallbacks *, VkSurfaceKHR *); static void (*pvkDestroyInstance)(VkInstance, const VkAllocationCallbacks *); static void * (*pvkGetDeviceProcAddr)(VkDevice, const char *); static void * (*pvkGetInstanceProcAddr)(VkInstance, const char *); @@ -66,6 +86,7 @@ static BOOL wine_vk_init(void)
#define LOAD_FUNCPTR(f) if((p##f = wine_dlsym(vulkan_handle, #f, NULL, 0)) == NULL) return FALSE; LOAD_FUNCPTR(vkCreateInstance) +LOAD_FUNCPTR(vkCreateXlibSurfaceKHR) LOAD_FUNCPTR(vkDestroyInstance) LOAD_FUNCPTR(vkGetDeviceProcAddr) LOAD_FUNCPTR(vkGetInstanceProcAddr) @@ -171,8 +192,49 @@ static VkResult X11DRV_vkCreateWin32SurfaceKHR(VkInstance instance, const VkWin32SurfaceCreateInfoKHR *create_info, const VkAllocationCallbacks *allocator, VkSurfaceKHR *surface) {
- FIXME("stub: %p %p %p %p\n", instance, create_info, allocator, surface);
- return VK_ERROR_OUT_OF_HOST_MEMORY;
- VkResult res;
- VkXlibSurfaceCreateInfoKHR create_info_host;
- struct wine_vk_surface *x11_surface;
- Window win;
- TRACE("%p %p %p %p\n", instance, create_info, allocator, surface);
- if (allocator)
FIXME("Support for allocation callbacks not implemented yet\n");
- /* TODO: support child window rendering. */
- if (GetAncestor(create_info->hwnd, GA_PARENT) != GetDesktopWindow())
- {
FIXME("Application requires child window rendering, which is not implemented yet!\n");
return VK_ERROR_INCOMPATIBLE_DRIVER;
- }
- win = create_client_window(create_info->hwnd, &default_visual);
- if (!win)
return VK_ERROR_OUT_OF_HOST_MEMORY;
- x11_surface = heap_alloc(sizeof(*x11_surface));
- if (!x11_surface)
return VK_ERROR_OUT_OF_HOST_MEMORY;
If it fails the client window isn't destroyed.
- x11_surface->window = win;
- create_info_host.sType = VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR;
- create_info_host.pNext = NULL;
- create_info_host.flags = 0; /* reserved */
- create_info_host.dpy = gdi_display;
- create_info_host.window = x11_surface->window;
- res = pvkCreateXlibSurfaceKHR(instance, &create_info_host, NULL /* allocator */, &x11_surface->surface);
- if (res != VK_SUCCESS)
- {
heap_free(x11_surface);
return res;
- }
Same as above.
The opengl code works the same way. The client window cleanup code is deeply hidden in window.c and tied to deletion of 'whole_window'.
On Mon, Mar 12, 2018 at 4:38 PM, Roderick Colenbrander thunderbird2k@gmail.com wrote:
The opengl code works the same way. The client window cleanup code is deeply hidden in window.c and tied to deletion of 'whole_window'.
release_gl_drawable() destroys the client window.
On Mon, Mar 12, 2018 at 8:49 AM, Józef Kucia joseph.kucia@gmail.com wrote:
On Mon, Mar 12, 2018 at 4:38 PM, Roderick Colenbrander thunderbird2k@gmail.com wrote:
The opengl code works the same way. The client window cleanup code is deeply hidden in window.c and tied to deletion of 'whole_window'.
release_gl_drawable() destroys the client window.
I hadn't realized that, I remembered it being mostly for xcomposite/pixmap/glxwindow. I just wonder how window.c deals with the client window destroyed behind its back. Need to do some more digging.
Signed-off-by: Roderick Colenbrander thunderbird2k@gmail.com --- dlls/winex11.drv/vulkan.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/dlls/winex11.drv/vulkan.c b/dlls/winex11.drv/vulkan.c index c5ecfd362b..515806e421 100644 --- a/dlls/winex11.drv/vulkan.c +++ b/dlls/winex11.drv/vulkan.c @@ -67,6 +67,7 @@ static VkResult (*pvkCreateXlibSurfaceKHR)(VkInstance, const VkXlibSurfaceCreate static void (*pvkDestroyInstance)(VkInstance, const VkAllocationCallbacks *); static void * (*pvkGetDeviceProcAddr)(VkDevice, const char *); static void * (*pvkGetInstanceProcAddr)(VkInstance, const char *); +static VkBool32 (*pvkGetPhysicalDeviceXlibPresentationSupportKHR)(VkPhysicalDevice, uint32_t, Display *, VisualID);
/* TODO: dynamically generate based on host driver capabilities. */ struct VkExtensionProperties winex11_vk_instance_extensions[] = { @@ -90,6 +91,7 @@ LOAD_FUNCPTR(vkCreateXlibSurfaceKHR) LOAD_FUNCPTR(vkDestroyInstance) LOAD_FUNCPTR(vkGetDeviceProcAddr) LOAD_FUNCPTR(vkGetInstanceProcAddr) +LOAD_FUNCPTR(vkGetPhysicalDeviceXlibPresentationSupportKHR) #undef LOAD_FUNCPTR
return TRUE; @@ -352,8 +354,10 @@ static VkResult X11DRV_vkGetPhysicalDeviceSurfaceSupportKHR(VkPhysicalDevice phy static VkBool32 X11DRV_vkGetPhysicalDeviceWin32PresentationSupportKHR(VkPhysicalDevice phys_dev, uint32_t index) { - FIXME("stub %p %u\n", phys_dev, index); - return VK_FALSE; + TRACE("%p %u\n", phys_dev, index); + + return pvkGetPhysicalDeviceXlibPresentationSupportKHR(phys_dev, index, gdi_display, + default_visual.visual->visualid); }
static VkResult X11DRV_vkGetSwapchainImagesKHR(VkDevice device,
Signed-off-by: Roderick Colenbrander thunderbird2k@gmail.com --- dlls/winex11.drv/vulkan.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-)
diff --git a/dlls/winex11.drv/vulkan.c b/dlls/winex11.drv/vulkan.c index 515806e421..40d4f608e9 100644 --- a/dlls/winex11.drv/vulkan.c +++ b/dlls/winex11.drv/vulkan.c @@ -52,6 +52,8 @@ struct wine_vk_surface Window window; VkSurfaceKHR surface; /* native surface */ }; +/* Macro to help conversion from VkSurfaceKHR (uint64_t) to a surface pointer. */ +#define SURFACE_FROM_HANDLE(surface) ((struct wine_vk_surface *)(uintptr_t)surface)
typedef struct VkXlibSurfaceCreateInfoKHR { @@ -65,6 +67,7 @@ typedef struct VkXlibSurfaceCreateInfoKHR static VkResult (*pvkCreateInstance)(const VkInstanceCreateInfo *, const VkAllocationCallbacks *, VkInstance *); static VkResult (*pvkCreateXlibSurfaceKHR)(VkInstance, const VkXlibSurfaceCreateInfoKHR *, const VkAllocationCallbacks *, VkSurfaceKHR *); static void (*pvkDestroyInstance)(VkInstance, const VkAllocationCallbacks *); +static void (*pvkDestroySurfaceKHR)(VkInstance, VkSurfaceKHR, const VkAllocationCallbacks *); static void * (*pvkGetDeviceProcAddr)(VkDevice, const char *); static void * (*pvkGetInstanceProcAddr)(VkInstance, const char *); static VkBool32 (*pvkGetPhysicalDeviceXlibPresentationSupportKHR)(VkPhysicalDevice, uint32_t, Display *, VisualID); @@ -89,6 +92,7 @@ static BOOL wine_vk_init(void) LOAD_FUNCPTR(vkCreateInstance) LOAD_FUNCPTR(vkCreateXlibSurfaceKHR) LOAD_FUNCPTR(vkDestroyInstance) +LOAD_FUNCPTR(vkDestroySurfaceKHR) LOAD_FUNCPTR(vkGetDeviceProcAddr) LOAD_FUNCPTR(vkGetInstanceProcAddr) LOAD_FUNCPTR(vkGetPhysicalDeviceXlibPresentationSupportKHR) @@ -252,7 +256,15 @@ static void X11DRV_vkDestroyInstance(VkInstance instance, const VkAllocationCall static void X11DRV_vkDestroySurfaceKHR(VkInstance instance, VkSurfaceKHR surface, const VkAllocationCallbacks *allocator) { - FIXME("stub: %p 0x%s %p\n", instance, wine_dbgstr_longlong(surface), allocator); + struct wine_vk_surface *x11_surface = SURFACE_FROM_HANDLE(surface); + + TRACE("%p 0x%s %p\n", instance, wine_dbgstr_longlong(surface), allocator); + + if (allocator) + FIXME("Support for allocation callbacks not implemented yet\n"); + + pvkDestroySurfaceKHR(instance, x11_surface->surface, NULL /* allocator */); + heap_free(x11_surface); }
static void X11DRV_vkDestroySwapchainKHR(VkDevice device, VkSwapchainKHR swapchain,
On Mon, Mar 12, 2018 at 1:22 AM, Roderick Colenbrander thunderbird2k@gmail.com wrote:
Signed-off-by: Roderick Colenbrander thunderbird2k@gmail.com
dlls/winex11.drv/vulkan.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-)
diff --git a/dlls/winex11.drv/vulkan.c b/dlls/winex11.drv/vulkan.c index 515806e421..40d4f608e9 100644 --- a/dlls/winex11.drv/vulkan.c +++ b/dlls/winex11.drv/vulkan.c @@ -52,6 +52,8 @@ struct wine_vk_surface Window window; VkSurfaceKHR surface; /* native surface */ }; +/* Macro to help conversion from VkSurfaceKHR (uint64_t) to a surface pointer. */ +#define SURFACE_FROM_HANDLE(surface) ((struct wine_vk_surface *)(uintptr_t)surface)
An inline function would be preferred.
typedef struct VkXlibSurfaceCreateInfoKHR { @@ -65,6 +67,7 @@ typedef struct VkXlibSurfaceCreateInfoKHR static VkResult (*pvkCreateInstance)(const VkInstanceCreateInfo *, const VkAllocationCallbacks *, VkInstance *); static VkResult (*pvkCreateXlibSurfaceKHR)(VkInstance, const VkXlibSurfaceCreateInfoKHR *, const VkAllocationCallbacks *, VkSurfaceKHR *); static void (*pvkDestroyInstance)(VkInstance, const VkAllocationCallbacks *); +static void (*pvkDestroySurfaceKHR)(VkInstance, VkSurfaceKHR, const VkAllocationCallbacks *); static void * (*pvkGetDeviceProcAddr)(VkDevice, const char *); static void * (*pvkGetInstanceProcAddr)(VkInstance, const char *); static VkBool32 (*pvkGetPhysicalDeviceXlibPresentationSupportKHR)(VkPhysicalDevice, uint32_t, Display *, VisualID); @@ -89,6 +92,7 @@ static BOOL wine_vk_init(void) LOAD_FUNCPTR(vkCreateInstance) LOAD_FUNCPTR(vkCreateXlibSurfaceKHR) LOAD_FUNCPTR(vkDestroyInstance) +LOAD_FUNCPTR(vkDestroySurfaceKHR) LOAD_FUNCPTR(vkGetDeviceProcAddr) LOAD_FUNCPTR(vkGetInstanceProcAddr) LOAD_FUNCPTR(vkGetPhysicalDeviceXlibPresentationSupportKHR) @@ -252,7 +256,15 @@ static void X11DRV_vkDestroyInstance(VkInstance instance, const VkAllocationCall static void X11DRV_vkDestroySurfaceKHR(VkInstance instance, VkSurfaceKHR surface, const VkAllocationCallbacks *allocator) {
- FIXME("stub: %p 0x%s %p\n", instance, wine_dbgstr_longlong(surface), allocator);
- struct wine_vk_surface *x11_surface = SURFACE_FROM_HANDLE(surface);
- TRACE("%p 0x%s %p\n", instance, wine_dbgstr_longlong(surface), allocator);
- if (allocator)
FIXME("Support for allocation callbacks not implemented yet\n");
- pvkDestroySurfaceKHR(instance, x11_surface->surface, NULL /* allocator */);
- heap_free(x11_surface);
}
I think we may need to destroy the client window.
static void X11DRV_vkDestroySwapchainKHR(VkDevice device, VkSwapchainKHR swapchain,
2.14.3
On Mon, Mar 12, 2018 at 1:22 AM, Roderick Colenbrander thunderbird2k@gmail.com wrote:
Signed-off-by: Roderick Colenbrander thunderbird2k@gmail.com
dlls/winex11.drv/vulkan.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-)
diff --git a/dlls/winex11.drv/vulkan.c b/dlls/winex11.drv/vulkan.c index 515806e421..40d4f608e9 100644 --- a/dlls/winex11.drv/vulkan.c +++ b/dlls/winex11.drv/vulkan.c @@ -52,6 +52,8 @@ struct wine_vk_surface Window window; VkSurfaceKHR surface; /* native surface */ }; +/* Macro to help conversion from VkSurfaceKHR (uint64_t) to a surface pointer. */ +#define SURFACE_FROM_HANDLE(surface) ((struct wine_vk_surface *)(uintptr_t)surface)
typedef struct VkXlibSurfaceCreateInfoKHR { @@ -65,6 +67,7 @@ typedef struct VkXlibSurfaceCreateInfoKHR static VkResult (*pvkCreateInstance)(const VkInstanceCreateInfo *, const VkAllocationCallbacks *, VkInstance *); static VkResult (*pvkCreateXlibSurfaceKHR)(VkInstance, const VkXlibSurfaceCreateInfoKHR *, const VkAllocationCallbacks *, VkSurfaceKHR *); static void (*pvkDestroyInstance)(VkInstance, const VkAllocationCallbacks *); +static void (*pvkDestroySurfaceKHR)(VkInstance, VkSurfaceKHR, const VkAllocationCallbacks *); static void * (*pvkGetDeviceProcAddr)(VkDevice, const char *); static void * (*pvkGetInstanceProcAddr)(VkInstance, const char *); static VkBool32 (*pvkGetPhysicalDeviceXlibPresentationSupportKHR)(VkPhysicalDevice, uint32_t, Display *, VisualID); @@ -89,6 +92,7 @@ static BOOL wine_vk_init(void) LOAD_FUNCPTR(vkCreateInstance) LOAD_FUNCPTR(vkCreateXlibSurfaceKHR) LOAD_FUNCPTR(vkDestroyInstance) +LOAD_FUNCPTR(vkDestroySurfaceKHR) LOAD_FUNCPTR(vkGetDeviceProcAddr) LOAD_FUNCPTR(vkGetInstanceProcAddr) LOAD_FUNCPTR(vkGetPhysicalDeviceXlibPresentationSupportKHR) @@ -252,7 +256,15 @@ static void X11DRV_vkDestroyInstance(VkInstance instance, const VkAllocationCall static void X11DRV_vkDestroySurfaceKHR(VkInstance instance, VkSurfaceKHR surface, const VkAllocationCallbacks *allocator) {
- FIXME("stub: %p 0x%s %p\n", instance, wine_dbgstr_longlong(surface), allocator);
- struct wine_vk_surface *x11_surface = SURFACE_FROM_HANDLE(surface);
- TRACE("%p 0x%s %p\n", instance, wine_dbgstr_longlong(surface), allocator);
- if (allocator)
FIXME("Support for allocation callbacks not implemented yet\n");
- pvkDestroySurfaceKHR(instance, x11_surface->surface, NULL /* allocator */);
According to the Vulkan spec, vkDestroySurfaceKHR() should handle VK_NULL_HANDLE gracefully.
- heap_free(x11_surface);
}
static void X11DRV_vkDestroySwapchainKHR(VkDevice device, VkSwapchainKHR swapchain,
2.14.3
Signed-off-by: Roderick Colenbrander thunderbird2k@gmail.com --- dlls/winex11.drv/vulkan.c | 40 ++++++++++++++++++++++++++++++++-------- 1 file changed, 32 insertions(+), 8 deletions(-)
diff --git a/dlls/winex11.drv/vulkan.c b/dlls/winex11.drv/vulkan.c index 40d4f608e9..dc939e1ddb 100644 --- a/dlls/winex11.drv/vulkan.c +++ b/dlls/winex11.drv/vulkan.c @@ -70,6 +70,10 @@ static void (*pvkDestroyInstance)(VkInstance, const VkAllocationCallbacks *); static void (*pvkDestroySurfaceKHR)(VkInstance, VkSurfaceKHR, const VkAllocationCallbacks *); static void * (*pvkGetDeviceProcAddr)(VkDevice, const char *); static void * (*pvkGetInstanceProcAddr)(VkInstance, const char *); +static VkResult (*pvkGetPhysicalDeviceSurfaceCapabilitiesKHR)(VkPhysicalDevice, VkSurfaceKHR, VkSurfaceCapabilitiesKHR *); +static VkResult (*pvkGetPhysicalDeviceSurfaceFormatsKHR)(VkPhysicalDevice, VkSurfaceKHR, uint32_t *, VkSurfaceFormatKHR *); +static VkResult (*pvkGetPhysicalDeviceSurfacePresentModesKHR)(VkPhysicalDevice, VkSurfaceKHR, uint32_t *, VkPresentModeKHR *); +static VkResult (*pvkGetPhysicalDeviceSurfaceSupportKHR)(VkPhysicalDevice, uint32_t, VkSurfaceKHR, VkBool32 *); static VkBool32 (*pvkGetPhysicalDeviceXlibPresentationSupportKHR)(VkPhysicalDevice, uint32_t, Display *, VisualID);
/* TODO: dynamically generate based on host driver capabilities. */ @@ -95,6 +99,10 @@ LOAD_FUNCPTR(vkDestroyInstance) LOAD_FUNCPTR(vkDestroySurfaceKHR) LOAD_FUNCPTR(vkGetDeviceProcAddr) LOAD_FUNCPTR(vkGetInstanceProcAddr) +LOAD_FUNCPTR(vkGetPhysicalDeviceSurfaceCapabilitiesKHR) +LOAD_FUNCPTR(vkGetPhysicalDeviceSurfaceFormatsKHR) +LOAD_FUNCPTR(vkGetPhysicalDeviceSurfacePresentModesKHR) +LOAD_FUNCPTR(vkGetPhysicalDeviceSurfaceSupportKHR) LOAD_FUNCPTR(vkGetPhysicalDeviceXlibPresentationSupportKHR) #undef LOAD_FUNCPTR
@@ -338,29 +346,45 @@ static void * X11DRV_vkGetInstanceProcAddr(VkInstance instance, const char *name static VkResult X11DRV_vkGetPhysicalDeviceSurfaceCapabilitiesKHR(VkPhysicalDevice phys_dev, VkSurfaceKHR surface, VkSurfaceCapabilitiesKHR *capabilities) { - FIXME("stub: %p, 0x%s, %p\n", phys_dev, wine_dbgstr_longlong(surface), capabilities); - return VK_ERROR_OUT_OF_HOST_MEMORY; + struct wine_vk_surface *x11_surface = SURFACE_FROM_HANDLE(surface); + + TRACE("%p, 0x%s, %p\n", phys_dev, wine_dbgstr_longlong(surface), capabilities); + + return pvkGetPhysicalDeviceSurfaceCapabilitiesKHR(phys_dev, x11_surface->surface, + capabilities); }
static VkResult X11DRV_vkGetPhysicalDeviceSurfaceFormatsKHR(VkPhysicalDevice phys_dev, VkSurfaceKHR surface, uint32_t *count, VkSurfaceFormatKHR *formats) { - FIXME("stub: %p, 0x%s, %p, %p\n", phys_dev, wine_dbgstr_longlong(surface), count, formats); - return VK_ERROR_OUT_OF_HOST_MEMORY; + struct wine_vk_surface *x11_surface = SURFACE_FROM_HANDLE(surface); + + TRACE("%p, 0x%s, %p, %p\n", phys_dev, wine_dbgstr_longlong(surface), count, formats); + + return pvkGetPhysicalDeviceSurfaceFormatsKHR(phys_dev, x11_surface->surface, + count, formats); }
static VkResult X11DRV_vkGetPhysicalDeviceSurfacePresentModesKHR(VkPhysicalDevice phys_dev, VkSurfaceKHR surface, uint32_t *count, VkPresentModeKHR *modes) { - FIXME("stub: %p, 0x%s, %p, %p\n", phys_dev, wine_dbgstr_longlong(surface), count, modes); - return VK_ERROR_OUT_OF_HOST_MEMORY; + struct wine_vk_surface *x11_surface = SURFACE_FROM_HANDLE(surface); + + TRACE("%p, 0x%s, %p, %p\n", phys_dev, wine_dbgstr_longlong(surface), count, modes); + + return pvkGetPhysicalDeviceSurfacePresentModesKHR(phys_dev, x11_surface->surface, count, + modes); }
static VkResult X11DRV_vkGetPhysicalDeviceSurfaceSupportKHR(VkPhysicalDevice phys_dev, uint32_t index, VkSurfaceKHR surface, VkBool32 *supported) { - FIXME("stub: %p, %u, 0x%s, %p\n", phys_dev, index, wine_dbgstr_longlong(surface), supported); - return VK_ERROR_OUT_OF_HOST_MEMORY; + struct wine_vk_surface *x11_surface = SURFACE_FROM_HANDLE(surface); + + TRACE("%p, %u, 0x%s, %p\n", phys_dev, index, wine_dbgstr_longlong(surface), supported); + + return pvkGetPhysicalDeviceSurfaceSupportKHR(phys_dev, index, x11_surface->surface, + supported); }
static VkBool32 X11DRV_vkGetPhysicalDeviceWin32PresentationSupportKHR(VkPhysicalDevice phys_dev,