[PATCH 03/11] dxgi: Introduce helper function to destroy partially initialized swapchain.
Józef Kucia
jkucia at codeweavers.com
Wed Aug 8 09:11:34 CDT 2018
Signed-off-by: Józef Kucia <jkucia at codeweavers.com>
---
dlls/dxgi/swapchain.c | 117 +++++++++++++++++++++++++++-----------------------
1 file changed, 63 insertions(+), 54 deletions(-)
diff --git a/dlls/dxgi/swapchain.c b/dlls/dxgi/swapchain.c
index 3537f117d1b6..7a305554dbeb 100644
--- a/dlls/dxgi/swapchain.c
+++ b/dlls/dxgi/swapchain.c
@@ -926,33 +926,47 @@ static ULONG STDMETHODCALLTYPE d3d12_swapchain_AddRef(IDXGISwapChain3 *iface)
return refcount;
}
-static ULONG STDMETHODCALLTYPE d3d12_swapchain_Release(IDXGISwapChain3 *iface)
+static void d3d12_swapchain_destroy(struct d3d12_swapchain *swapchain)
{
- struct d3d12_swapchain *swapchain = d3d12_swapchain_from_IDXGISwapChain3(iface);
const struct dxgi_vk_funcs *vk_funcs = &swapchain->vk_funcs;
- ULONG refcount = InterlockedDecrement(&swapchain->refcount);
unsigned int i;
- TRACE("%p decreasing refcount to %u.\n", swapchain, refcount);
-
- if (!refcount)
- {
+ if (swapchain->command_queue)
ID3D12CommandQueue_Release(swapchain->command_queue);
+ if (swapchain->factory)
IWineDXGIFactory_Release(swapchain->factory);
- wined3d_private_store_cleanup(&swapchain->private_store);
+ wined3d_private_store_cleanup(&swapchain->private_store);
- for (i = 0; i < swapchain->buffer_count; ++i)
- {
+ for (i = 0; i < swapchain->buffer_count; ++i)
+ {
+ if (swapchain->buffers[i])
vkd3d_resource_decref(swapchain->buffers[i]);
- }
+ }
+ if (swapchain->vk_device)
+ {
vk_funcs->p_vkDestroyFence(swapchain->vk_device, swapchain->vk_fence, NULL);
vk_funcs->p_vkDestroySwapchainKHR(swapchain->vk_device, swapchain->vk_swapchain, NULL);
+ }
+
+ if (swapchain->vk_instance)
vk_funcs->p_vkDestroySurfaceKHR(swapchain->vk_instance, swapchain->vk_surface, NULL);
+ if (swapchain->device)
ID3D12Device_Release(swapchain->device);
+}
+
+static ULONG STDMETHODCALLTYPE d3d12_swapchain_Release(IDXGISwapChain3 *iface)
+{
+ struct d3d12_swapchain *swapchain = d3d12_swapchain_from_IDXGISwapChain3(iface);
+ ULONG refcount = InterlockedDecrement(&swapchain->refcount);
+ TRACE("%p decreasing refcount to %u.\n", swapchain, refcount);
+
+ if (!refcount)
+ {
+ d3d12_swapchain_destroy(swapchain);
heap_free(swapchain);
}
@@ -1621,9 +1635,9 @@ static HRESULT d3d12_swapchain_init(struct d3d12_swapchain *swapchain, IWineDXGI
VkSurfaceCapabilitiesKHR surface_caps;
VkPhysicalDevice vk_physical_device;
VkFence vk_fence = VK_NULL_HANDLE;
- unsigned int image_count, i, j;
VkFenceCreateInfo fence_desc;
uint32_t queue_family_index;
+ unsigned int image_count, i;
VkImageUsageFlags usage;
VkInstance vk_instance;
VkBool32 supported;
@@ -1677,9 +1691,14 @@ static HRESULT d3d12_swapchain_init(struct d3d12_swapchain *swapchain, IWineDXGI
vk_physical_device = vkd3d_get_vk_physical_device(device);
vk_device = vkd3d_get_vk_device(device);
+ swapchain->vk_instance = vk_instance;
+ swapchain->vk_device = vk_device;
+
if (!init_vk_funcs(&swapchain->vk_funcs, vk_device))
return E_FAIL;
+ wined3d_private_store_init(&swapchain->private_store);
+
surface_desc.sType = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR;
surface_desc.pNext = NULL;
surface_desc.flags = 0;
@@ -1688,28 +1707,32 @@ static HRESULT d3d12_swapchain_init(struct d3d12_swapchain *swapchain, IWineDXGI
if ((vr = vk_funcs->p_vkCreateWin32SurfaceKHR(vk_instance, &surface_desc, NULL, &vk_surface)) < 0)
{
WARN("Failed to create Vulkan surface, vr %d.\n", vr);
- hr = hresult_from_vk_result(vr);
- goto fail;
+ d3d12_swapchain_destroy(swapchain);
+ return hresult_from_vk_result(vr);
}
+ swapchain->vk_surface = vk_surface;
queue_family_index = vkd3d_get_vk_queue_family_index(queue);
if ((vr = vk_funcs->p_vkGetPhysicalDeviceSurfaceSupportKHR(vk_physical_device,
queue_family_index, vk_surface, &supported)) < 0 || !supported)
{
FIXME("Queue family does not support presentation, vr %d.\n", vr);
- hr = DXGI_ERROR_UNSUPPORTED;
- goto fail;
+ d3d12_swapchain_destroy(swapchain);
+ return DXGI_ERROR_UNSUPPORTED;
}
if (FAILED(hr = select_vk_format(vk_funcs, vk_physical_device, vk_surface, swapchain_desc, &vk_format)))
- goto fail;
+ {
+ 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);
- hr = hresult_from_vk_result(vr);
- goto fail;
+ d3d12_swapchain_destroy(swapchain);
+ return hresult_from_vk_result(vr);
}
if (surface_caps.maxImageCount && (swapchain_desc->BufferCount > surface_caps.maxImageCount
@@ -1717,8 +1740,8 @@ static HRESULT d3d12_swapchain_init(struct d3d12_swapchain *swapchain, IWineDXGI
{
WARN("Buffer count %u is not supported (%u-%u).\n", swapchain_desc->BufferCount,
surface_caps.minImageCount, surface_caps.maxImageCount);
- hr = DXGI_ERROR_UNSUPPORTED;
- goto fail;
+ d3d12_swapchain_destroy(swapchain);
+ return DXGI_ERROR_UNSUPPORTED;
}
if (swapchain_desc->Width > surface_caps.maxImageExtent.width
@@ -1735,8 +1758,8 @@ static HRESULT d3d12_swapchain_init(struct d3d12_swapchain *swapchain, IWineDXGI
if (!(surface_caps.supportedCompositeAlpha & VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR))
{
FIXME("Unsupported alpha mode.\n");
- hr = DXGI_ERROR_UNSUPPORTED;
- goto fail;
+ d3d12_swapchain_destroy(swapchain);
+ return DXGI_ERROR_UNSUPPORTED;
}
usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
@@ -1767,9 +1790,10 @@ static HRESULT d3d12_swapchain_init(struct d3d12_swapchain *swapchain, IWineDXGI
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);
- hr = hresult_from_vk_result(vr);
- goto fail;
+ 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;
@@ -1777,40 +1801,37 @@ static HRESULT d3d12_swapchain_init(struct d3d12_swapchain *swapchain, IWineDXGI
if ((vr = vk_funcs->p_vkCreateFence(vk_device, &fence_desc, NULL, &vk_fence)) < 0)
{
WARN("Failed to create Vulkan fence, vr %d.\n", vr);
- hr = hresult_from_vk_result(vr);
- goto fail;
+ d3d12_swapchain_destroy(swapchain);
+ return hresult_from_vk_result(vr);
}
+ swapchain->vk_fence = vk_fence;
if ((vr = vk_funcs->p_vkGetSwapchainImagesKHR(vk_device, vk_swapchain, &image_count, NULL)) < 0)
{
WARN("Failed to get Vulkan swapchain images, vr %d.\n", vr);
- hr = hresult_from_vk_result(vr);
- goto fail;
+ d3d12_swapchain_destroy(swapchain);
+ 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 > ARRAY_SIZE(vk_images))
{
- hr = E_FAIL;
- goto fail;
+ d3d12_swapchain_destroy(swapchain);
+ return E_FAIL;
}
+ swapchain->buffer_count = image_count;
if ((vr = vk_funcs->p_vkGetSwapchainImagesKHR(vk_device, vk_swapchain, &image_count, vk_images)) < 0)
{
WARN("Failed to get Vulkan swapchain images, vr %d.\n", vr);
- hr = hresult_from_vk_result(vr);
- goto fail;
+ d3d12_swapchain_destroy(swapchain);
+ return hresult_from_vk_result(vr);
}
- swapchain->vk_swapchain = vk_swapchain;
- swapchain->vk_surface = vk_surface;
- swapchain->vk_fence = vk_fence;
- swapchain->vk_instance = vk_instance;
- swapchain->vk_device = vk_device;
-
if (FAILED(hr = d3d12_swapchain_acquire_next_image(swapchain)))
{
WARN("Failed to acquire Vulkan image, hr %#x.\n", hr);
- goto fail;
+ d3d12_swapchain_destroy(swapchain);
+ return hr;
}
resource_info.type = VKD3D_STRUCTURE_TYPE_IMAGE_RESOURCE_CREATE_INFO;
@@ -1839,28 +1860,16 @@ static HRESULT d3d12_swapchain_init(struct d3d12_swapchain *swapchain, IWineDXGI
else
{
ERR("Failed to create vkd3d resource for Vulkan image %u, hr %#x.\n", i, hr);
- for (j = 0; j < i; ++j)
- {
- vkd3d_resource_decref(swapchain->buffers[j]);
- }
- goto fail;
+ d3d12_swapchain_destroy(swapchain);
+ return hr;
}
}
- swapchain->buffer_count = image_count;
-
- wined3d_private_store_init(&swapchain->private_store);
ID3D12CommandQueue_AddRef(swapchain->command_queue = queue);
ID3D12Device_AddRef(swapchain->device = device);
IWineDXGIFactory_AddRef(swapchain->factory = factory);
return S_OK;
-
-fail:
- vk_funcs->p_vkDestroyFence(vk_device, vk_fence, NULL);
- vk_funcs->p_vkDestroySwapchainKHR(vk_device, vk_swapchain, NULL);
- vk_funcs->p_vkDestroySurfaceKHR(vk_instance, vk_surface, NULL);
- return hr;
}
HRESULT d3d12_swapchain_create(IWineDXGIFactory *factory, ID3D12CommandQueue *queue, HWND window,
--
2.16.4
More information about the wine-devel
mailing list