From 9902af08ce45baa672b04d7e7eac3e1979e140f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B3zef=20Kucia?= Date: Wed, 29 Aug 2018 12:53:36 +0200 Subject: [PATCH] dxgi: Factor out d3d12_swapchain_create_vulkan_swapchain(). MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Józef Kucia Signed-off-by: Henri Verbeet Signed-off-by: Alexandre Julliard --- dlls/dxgi/swapchain.c | 228 ++++++++++++++++++++++-------------------- 1 file changed, 119 insertions(+), 109 deletions(-) diff --git a/dlls/dxgi/swapchain.c b/dlls/dxgi/swapchain.c index 0b651c4853b..71183f6f20b 100644 --- a/dlls/dxgi/swapchain.c +++ b/dlls/dxgi/swapchain.c @@ -1023,8 +1023,7 @@ static HRESULT vk_select_memory_type(const struct dxgi_vk_funcs *vk_funcs, return E_FAIL; } -static HRESULT d3d12_swapchain_create_user_buffers(struct d3d12_swapchain *swapchain, - const DXGI_SWAP_CHAIN_DESC1 *swapchain_desc, VkFormat vk_format) +static HRESULT d3d12_swapchain_create_user_buffers(struct d3d12_swapchain *swapchain, VkFormat vk_format) { const struct dxgi_vk_funcs *vk_funcs = &swapchain->vk_funcs; VkDeviceSize image_offset[DXGI_MAX_SWAP_CHAIN_BUFFERS]; @@ -1043,8 +1042,8 @@ static HRESULT d3d12_swapchain_create_user_buffers(struct d3d12_swapchain *swapc image_info.flags = VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT; image_info.imageType = VK_IMAGE_TYPE_2D; image_info.format = vk_format; - image_info.extent.width = swapchain_desc->Width; - image_info.extent.height = swapchain_desc->Height; + image_info.extent.width = swapchain->desc.Width; + image_info.extent.height = swapchain->desc.Height; image_info.extent.depth = 1; image_info.mipLevels = 1; image_info.arrayLayers = 1; @@ -1141,8 +1140,7 @@ static void vk_cmd_image_barrier(const struct dxgi_vk_funcs *vk_funcs, VkCommand } static HRESULT d3d12_swapchain_prepare_command_buffers(struct d3d12_swapchain *swapchain, - const DXGI_SWAP_CHAIN_DESC1 *swapchain_desc, uint32_t queue_family_index, - VkImage vk_swapchain_images[DXGI_MAX_SWAP_CHAIN_BUFFERS]) + uint32_t queue_family_index, VkImage vk_swapchain_images[DXGI_MAX_SWAP_CHAIN_BUFFERS]) { const struct dxgi_vk_funcs *vk_funcs = &swapchain->vk_funcs; VkDevice vk_device = swapchain->vk_device; @@ -1208,8 +1206,8 @@ static HRESULT d3d12_swapchain_prepare_command_buffers(struct d3d12_swapchain *s blit.srcOffsets[0].x = 0; blit.srcOffsets[0].y = 0; blit.srcOffsets[0].z = 0; - blit.srcOffsets[1].x = swapchain_desc->Width; - blit.srcOffsets[1].y = swapchain_desc->Height; + blit.srcOffsets[1].x = swapchain->desc.Width; + blit.srcOffsets[1].y = swapchain->desc.Height; blit.srcOffsets[1].z = 1; blit.dstSubresource = blit.srcSubresource; blit.dstOffsets[0] = blit.srcOffsets[0]; @@ -1252,14 +1250,15 @@ static HRESULT d3d12_swapchain_prepare_command_buffers(struct d3d12_swapchain *s } static HRESULT d3d12_swapchain_create_buffers(struct d3d12_swapchain *swapchain, - ID3D12Device *device, ID3D12CommandQueue *queue, - const DXGI_SWAP_CHAIN_DESC1 *swapchain_desc, VkFormat vk_swapchain_format, VkFormat vk_format) + VkFormat vk_swapchain_format, VkFormat vk_format) { const struct dxgi_vk_funcs *vk_funcs = &swapchain->vk_funcs; VkImage vk_swapchain_images[DXGI_MAX_SWAP_CHAIN_BUFFERS]; struct vkd3d_image_resource_create_info resource_info; VkSwapchainKHR vk_swapchain = swapchain->vk_swapchain; + ID3D12CommandQueue *queue = swapchain->command_queue; VkDevice vk_device = swapchain->vk_device; + ID3D12Device *device = swapchain->device; uint32_t image_count, queue_family_index; D3D12_COMMAND_QUEUE_DESC queue_desc; unsigned int i; @@ -1271,8 +1270,8 @@ static HRESULT d3d12_swapchain_create_buffers(struct d3d12_swapchain *swapchain, WARN("Failed to get Vulkan swapchain images, vr %d.\n", vr); return hresult_from_vk_result(vr); } - if (image_count != swapchain_desc->BufferCount) - FIXME("Got %u swapchain images, expected %u.\n", image_count, swapchain_desc->BufferCount); + if (image_count != swapchain->desc.BufferCount) + FIXME("Got %u swapchain images, expected %u.\n", image_count, swapchain->desc.BufferCount); if (image_count > ARRAY_SIZE(vk_swapchain_images)) return E_FAIL; swapchain->buffer_count = image_count; @@ -1287,8 +1286,8 @@ static HRESULT d3d12_swapchain_create_buffers(struct d3d12_swapchain *swapchain, resource_info.next = NULL; resource_info.desc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D; resource_info.desc.Alignment = 0; - resource_info.desc.Width = swapchain_desc->Width; - resource_info.desc.Height = swapchain_desc->Height; + resource_info.desc.Width = swapchain->desc.Width; + resource_info.desc.Height = swapchain->desc.Height; resource_info.desc.DepthOrArraySize = 1; resource_info.desc.MipLevels = 1; resource_info.desc.Format = dxgi_format_from_vk_format(vk_format); @@ -1311,10 +1310,10 @@ static HRESULT d3d12_swapchain_create_buffers(struct d3d12_swapchain *swapchain, TRACE("Creating user swapchain buffers for format conversion.\n"); - if (FAILED(hr = d3d12_swapchain_create_user_buffers(swapchain, swapchain_desc, vk_format))) + if (FAILED(hr = d3d12_swapchain_create_user_buffers(swapchain, vk_format))) return hr; - if (FAILED(hr = d3d12_swapchain_prepare_command_buffers(swapchain, swapchain_desc, + if (FAILED(hr = d3d12_swapchain_prepare_command_buffers(swapchain, queue_family_index, vk_swapchain_images))) return hr; } @@ -1391,6 +1390,103 @@ static void d3d12_swapchain_destroy_buffers(struct d3d12_swapchain *swapchain) } } +static HRESULT d3d12_swapchain_create_vulkan_swapchain(struct d3d12_swapchain *swapchain) +{ + VkPhysicalDevice vk_physical_device = swapchain->vk_physical_device; + const struct dxgi_vk_funcs *vk_funcs = &swapchain->vk_funcs; + VkSwapchainCreateInfoKHR vk_swapchain_desc; + VkDevice vk_device = swapchain->vk_device; + VkFormat vk_format, vk_swapchain_format; + VkSurfaceCapabilitiesKHR surface_caps; + VkSwapchainKHR vk_swapchain; + VkImageUsageFlags usage; + VkResult vr; + HRESULT hr; + + if (!(vk_format = vkd3d_get_vk_format(swapchain->desc.Format))) + { + WARN("Invalid format %#x.\n", swapchain->desc.Format); + return DXGI_ERROR_INVALID_CALL; + } + + if (FAILED(hr = select_vk_format(vk_funcs, vk_physical_device, + swapchain->vk_surface, &swapchain->desc, &vk_swapchain_format))) + return hr; + + if ((vr = vk_funcs->p_vkGetPhysicalDeviceSurfaceCapabilitiesKHR(vk_physical_device, + swapchain->vk_surface, &surface_caps)) < 0) + { + WARN("Failed to get surface capabilities, vr %d.\n", vr); + return hresult_from_vk_result(vr); + } + + if (surface_caps.maxImageCount && (swapchain->desc.BufferCount > surface_caps.maxImageCount + || swapchain->desc.BufferCount < surface_caps.minImageCount)) + { + WARN("Buffer count %u is not supported (%u-%u).\n", swapchain->desc.BufferCount, + surface_caps.minImageCount, surface_caps.maxImageCount); + return DXGI_ERROR_UNSUPPORTED; + } + + if (swapchain->desc.Width > surface_caps.maxImageExtent.width + || swapchain->desc.Width < surface_caps.minImageExtent.width + || swapchain->desc.Height > surface_caps.maxImageExtent.height + || swapchain->desc.Height < surface_caps.minImageExtent.height) + { + FIXME("Swapchain dimensions %ux%u are not supported (%u-%u x %u-%u).\n", + swapchain->desc.Width, swapchain->desc.Height, + surface_caps.minImageExtent.width, surface_caps.maxImageExtent.width, + surface_caps.minImageExtent.height, surface_caps.maxImageExtent.height); + } + + if (!(surface_caps.supportedCompositeAlpha & VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR)) + { + FIXME("Unsupported alpha mode.\n"); + return DXGI_ERROR_UNSUPPORTED; + } + + usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; + usage |= surface_caps.supportedUsageFlags & VK_IMAGE_USAGE_TRANSFER_SRC_BIT; + usage |= surface_caps.supportedUsageFlags & VK_IMAGE_USAGE_TRANSFER_DST_BIT; + if (!(usage & VK_IMAGE_USAGE_TRANSFER_SRC_BIT) || !(usage & VK_IMAGE_USAGE_TRANSFER_DST_BIT)) + WARN("Transfer not supported for swapchain images.\n"); + + vk_swapchain_desc.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR; + vk_swapchain_desc.pNext = NULL; + vk_swapchain_desc.flags = 0; + vk_swapchain_desc.surface = swapchain->vk_surface; + vk_swapchain_desc.minImageCount = swapchain->desc.BufferCount; + vk_swapchain_desc.imageFormat = vk_swapchain_format; + vk_swapchain_desc.imageColorSpace = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR; + vk_swapchain_desc.imageExtent.width = swapchain->desc.Width; + vk_swapchain_desc.imageExtent.height = swapchain->desc.Height; + vk_swapchain_desc.imageArrayLayers = 1; + vk_swapchain_desc.imageUsage = usage; + vk_swapchain_desc.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE; + vk_swapchain_desc.queueFamilyIndexCount = 0; + vk_swapchain_desc.pQueueFamilyIndices = NULL; + vk_swapchain_desc.preTransform = surface_caps.currentTransform; + vk_swapchain_desc.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR; + vk_swapchain_desc.presentMode = VK_PRESENT_MODE_FIFO_KHR; + vk_swapchain_desc.clipped = VK_TRUE; + vk_swapchain_desc.oldSwapchain = swapchain->vk_swapchain; + if ((vr = vk_funcs->p_vkCreateSwapchainKHR(vk_device, &vk_swapchain_desc, NULL, &vk_swapchain)) < 0) + { + WARN("Failed to create Vulkan swapchain, vr %d.\n", vr); + return hresult_from_vk_result(vr); + } + + if (swapchain->vk_swapchain) + vk_funcs->p_vkDestroySwapchainKHR(swapchain->vk_device, swapchain->vk_swapchain, NULL); + + swapchain->vk_swapchain = vk_swapchain; + + if (FAILED(hr = d3d12_swapchain_create_buffers(swapchain, vk_swapchain_format, vk_format))) + return hr; + + return S_OK; +} + static inline struct d3d12_swapchain *d3d12_swapchain_from_IDXGISwapChain3(IDXGISwapChain3 *iface) { return CONTAINING_RECORD(iface, struct d3d12_swapchain, IDXGISwapChain3_iface); @@ -2153,20 +2249,15 @@ static HRESULT d3d12_swapchain_init(struct d3d12_swapchain *swapchain, IWineDXGI const DXGI_SWAP_CHAIN_DESC1 *swapchain_desc, const DXGI_SWAP_CHAIN_FULLSCREEN_DESC *fullscreen_desc) { const struct dxgi_vk_funcs *vk_funcs = &swapchain->vk_funcs; - struct VkSwapchainCreateInfoKHR vk_swapchain_desc; - struct VkWin32SurfaceCreateInfoKHR surface_desc; - VkSwapchainKHR vk_swapchain = VK_NULL_HANDLE; - VkSurfaceKHR vk_surface = VK_NULL_HANDLE; - VkFormat vk_swapchain_format, vk_format; - VkSurfaceCapabilitiesKHR surface_caps; + VkWin32SurfaceCreateInfoKHR surface_desc; VkPhysicalDevice vk_physical_device; - VkFence vk_fence = VK_NULL_HANDLE; VkFenceCreateInfo fence_desc; uint32_t queue_family_index; - VkImageUsageFlags usage; + VkSurfaceKHR vk_surface; VkInstance vk_instance; VkBool32 supported; VkDevice vk_device; + VkFence vk_fence; VkResult vr; HRESULT hr; @@ -2194,12 +2285,6 @@ static HRESULT d3d12_swapchain_init(struct d3d12_swapchain *swapchain, IWineDXGI return DXGI_ERROR_UNSUPPORTED; } - if (!(vk_format = vkd3d_get_vk_format(swapchain_desc->Format))) - { - WARN("Invalid format %#x.\n", swapchain_desc->Format); - return DXGI_ERROR_INVALID_CALL; - } - if (swapchain_desc->BufferUsage && swapchain_desc->BufferUsage != DXGI_USAGE_RENDER_TARGET_OUTPUT) FIXME("Ignoring buffer usage %#x.\n", swapchain_desc->BufferUsage); if (swapchain_desc->Scaling != DXGI_SCALING_STRETCH) @@ -2252,81 +2337,15 @@ static HRESULT d3d12_swapchain_init(struct d3d12_swapchain *swapchain, IWineDXGI return DXGI_ERROR_UNSUPPORTED; } - if (FAILED(hr = select_vk_format(vk_funcs, vk_physical_device, - vk_surface, swapchain_desc, &vk_swapchain_format))) + ID3D12CommandQueue_AddRef(swapchain->command_queue = queue); + ID3D12Device_AddRef(swapchain->device = device); + + if (FAILED(hr = d3d12_swapchain_create_vulkan_swapchain(swapchain))) { d3d12_swapchain_destroy(swapchain); return hr; } - if ((vr = vk_funcs->p_vkGetPhysicalDeviceSurfaceCapabilitiesKHR(vk_physical_device, - vk_surface, &surface_caps)) < 0) - { - WARN("Failed to get surface capabilities, vr %d.\n", vr); - d3d12_swapchain_destroy(swapchain); - return hresult_from_vk_result(vr); - } - - if (surface_caps.maxImageCount && (swapchain_desc->BufferCount > surface_caps.maxImageCount - || swapchain_desc->BufferCount < surface_caps.minImageCount)) - { - WARN("Buffer count %u is not supported (%u-%u).\n", swapchain_desc->BufferCount, - surface_caps.minImageCount, surface_caps.maxImageCount); - d3d12_swapchain_destroy(swapchain); - return DXGI_ERROR_UNSUPPORTED; - } - - if (swapchain_desc->Width > surface_caps.maxImageExtent.width - || swapchain_desc->Width < surface_caps.minImageExtent.width - || swapchain_desc->Height > surface_caps.maxImageExtent.height - || swapchain_desc->Height < surface_caps.minImageExtent.height) - { - FIXME("Swapchain dimensions %ux%u are not supported (%u-%u x %u-%u).\n", - swapchain_desc->Width, swapchain_desc->Height, - surface_caps.minImageExtent.width, surface_caps.maxImageExtent.width, - surface_caps.minImageExtent.height, surface_caps.maxImageExtent.height); - } - - if (!(surface_caps.supportedCompositeAlpha & VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR)) - { - FIXME("Unsupported alpha mode.\n"); - d3d12_swapchain_destroy(swapchain); - return DXGI_ERROR_UNSUPPORTED; - } - - usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; - usage |= surface_caps.supportedUsageFlags & VK_IMAGE_USAGE_TRANSFER_SRC_BIT; - usage |= surface_caps.supportedUsageFlags & VK_IMAGE_USAGE_TRANSFER_DST_BIT; - if (!(usage & VK_IMAGE_USAGE_TRANSFER_SRC_BIT) || !(usage & VK_IMAGE_USAGE_TRANSFER_DST_BIT)) - WARN("Transfer not supported for swapchain images.\n"); - - vk_swapchain_desc.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR; - vk_swapchain_desc.pNext = NULL; - vk_swapchain_desc.flags = 0; - vk_swapchain_desc.surface = vk_surface; - vk_swapchain_desc.minImageCount = swapchain_desc->BufferCount; - vk_swapchain_desc.imageFormat = vk_swapchain_format; - vk_swapchain_desc.imageColorSpace = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR; - vk_swapchain_desc.imageExtent.width = swapchain_desc->Width; - vk_swapchain_desc.imageExtent.height = swapchain_desc->Height; - vk_swapchain_desc.imageArrayLayers = 1; - vk_swapchain_desc.imageUsage = usage; - vk_swapchain_desc.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE; - vk_swapchain_desc.queueFamilyIndexCount = 0; - vk_swapchain_desc.pQueueFamilyIndices = NULL; - vk_swapchain_desc.preTransform = surface_caps.currentTransform; - vk_swapchain_desc.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR; - vk_swapchain_desc.presentMode = VK_PRESENT_MODE_FIFO_KHR; - vk_swapchain_desc.clipped = VK_TRUE; - vk_swapchain_desc.oldSwapchain = VK_NULL_HANDLE; - if ((vr = vk_funcs->p_vkCreateSwapchainKHR(vk_device, &vk_swapchain_desc, NULL, &vk_swapchain)) < 0) - { - WARN("Failed to create Vulkan swapchain, vr %d.\n", vr); - d3d12_swapchain_destroy(swapchain); - return hresult_from_vk_result(vr); - } - swapchain->vk_swapchain = vk_swapchain; - fence_desc.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; fence_desc.pNext = NULL; fence_desc.flags = 0; @@ -2338,13 +2357,6 @@ static HRESULT d3d12_swapchain_init(struct d3d12_swapchain *swapchain, IWineDXGI } swapchain->vk_fence = vk_fence; - if (FAILED(hr = d3d12_swapchain_create_buffers(swapchain, device, queue, - swapchain_desc, vk_swapchain_format, vk_format))) - { - d3d12_swapchain_destroy(swapchain); - return hr; - } - if (FAILED(hr = d3d12_swapchain_acquire_next_image(swapchain))) { WARN("Failed to acquire Vulkan image, hr %#x.\n", hr); @@ -2352,8 +2364,6 @@ static HRESULT d3d12_swapchain_init(struct d3d12_swapchain *swapchain, IWineDXGI return hr; } - ID3D12CommandQueue_AddRef(swapchain->command_queue = queue); - ID3D12Device_AddRef(swapchain->device = device); IWineDXGIFactory_AddRef(swapchain->factory = factory); return S_OK;