=?UTF-8?Q?J=C3=B3zef=20Kucia=20?=: dxgi: Implement d3d12_swapchain_ResizeBuffers().
Alexandre Julliard
julliard at winehq.org
Wed Aug 29 16:10:45 CDT 2018
Module: wine
Branch: master
Commit: d10a9faa46382a86cec53996e5ffa3d5c6d7307d
URL: https://source.winehq.org/git/wine.git/?a=commit;h=d10a9faa46382a86cec53996e5ffa3d5c6d7307d
Author: Józef Kucia <jkucia at codeweavers.com>
Date: Wed Aug 29 12:53:37 2018 +0200
dxgi: Implement d3d12_swapchain_ResizeBuffers().
Signed-off-by: Józef Kucia <jkucia at codeweavers.com>
Signed-off-by: Henri Verbeet <hverbeet at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/dxgi/swapchain.c | 118 +++++++++++++++++++++++++++++++++++++-------------
1 file changed, 88 insertions(+), 30 deletions(-)
diff --git a/dlls/dxgi/swapchain.c b/dlls/dxgi/swapchain.c
index 71183f6..b285f3d 100644
--- a/dlls/dxgi/swapchain.c
+++ b/dlls/dxgi/swapchain.c
@@ -1344,6 +1344,34 @@ static HRESULT d3d12_swapchain_create_buffers(struct d3d12_swapchain *swapchain,
return S_OK;
}
+static HRESULT d3d12_swapchain_acquire_next_image(struct d3d12_swapchain *swapchain)
+{
+ const struct dxgi_vk_funcs *vk_funcs = &swapchain->vk_funcs;
+ VkDevice vk_device = swapchain->vk_device;
+ VkFence vk_fence = swapchain->vk_fence;
+ VkResult vr;
+
+ if ((vr = vk_funcs->p_vkAcquireNextImageKHR(vk_device, swapchain->vk_swapchain, UINT64_MAX,
+ VK_NULL_HANDLE, vk_fence, &swapchain->current_buffer_index)) < 0)
+ {
+ ERR("Failed to acquire next Vulkan image, vr %d.\n", vr);
+ return hresult_from_vk_result(vr);
+ }
+
+ if ((vr = vk_funcs->p_vkWaitForFences(vk_device, 1, &vk_fence, VK_TRUE, UINT64_MAX)) != VK_SUCCESS)
+ {
+ ERR("Failed to wait for fence, vr %d.\n", vr);
+ return hresult_from_vk_result(vr);
+ }
+ if ((vr = vk_funcs->p_vkResetFences(vk_device, 1, &vk_fence)) < 0)
+ {
+ ERR("Failed to reset fence, vr %d.\n", vr);
+ return hresult_from_vk_result(vr);
+ }
+
+ return S_OK;
+}
+
static void d3d12_swapchain_destroy_buffers(struct d3d12_swapchain *swapchain)
{
const struct dxgi_vk_funcs *vk_funcs = &swapchain->vk_funcs;
@@ -1700,10 +1728,68 @@ static HRESULT STDMETHODCALLTYPE d3d12_swapchain_GetDesc(IDXGISwapChain3 *iface,
static HRESULT STDMETHODCALLTYPE d3d12_swapchain_ResizeBuffers(IDXGISwapChain3 *iface,
UINT buffer_count, UINT width, UINT height, DXGI_FORMAT format, UINT flags)
{
- FIXME("iface %p, buffer_count %u, width %u, height %u, format %s, flags %#x stub!\n",
+ struct d3d12_swapchain *swapchain = d3d12_swapchain_from_IDXGISwapChain3(iface);
+ DXGI_SWAP_CHAIN_DESC1 *desc;
+ unsigned int i;
+ ULONG refcount;
+ HRESULT hr;
+
+ TRACE("iface %p, buffer_count %u, width %u, height %u, format %s, flags %#x.\n",
iface, buffer_count, width, height, debug_dxgi_format(format), flags);
- return E_NOTIMPL;
+ if (flags)
+ FIXME("Ignoring flags %#x.\n", flags);
+
+ for (i = 0; i < swapchain->buffer_count; ++i)
+ {
+ ID3D12Resource_AddRef(swapchain->buffers[i]);
+ if ((refcount = ID3D12Resource_Release(swapchain->buffers[i])))
+ {
+ WARN("Buffer %p has %u references left.\n", swapchain->buffers[i], refcount);
+ return DXGI_ERROR_INVALID_CALL;
+ }
+ }
+
+ desc = &swapchain->desc;
+
+ if (!buffer_count)
+ buffer_count = desc->BufferCount;
+ if (!width || !height)
+ {
+ RECT client_rect;
+
+ if (!GetClientRect(swapchain->window, &client_rect))
+ {
+ WARN("Failed to get client rect, last error %#x.\n", GetLastError());
+ return DXGI_ERROR_INVALID_CALL;
+ }
+
+ if (!width)
+ width = client_rect.right;
+ if (!height)
+ height = client_rect.bottom;
+ }
+ if (!format)
+ format = desc->Format;
+
+ if (desc->Width == width && desc->Height == height
+ && desc->Format == format && desc->BufferCount == buffer_count)
+ return S_OK;
+
+ d3d12_swapchain_destroy_buffers(swapchain);
+
+ desc->Width = width;
+ desc->Height = height;
+ desc->Format = format;
+ desc->BufferCount = buffer_count;
+
+ if (FAILED(hr = d3d12_swapchain_create_vulkan_swapchain(swapchain)))
+ {
+ ERR("Failed to recreate Vulkan swapchain, hr %#x.\n", hr);
+ return hr;
+ }
+
+ return d3d12_swapchain_acquire_next_image(swapchain);
}
static HRESULT STDMETHODCALLTYPE d3d12_swapchain_ResizeTarget(IDXGISwapChain3 *iface,
@@ -1800,34 +1886,6 @@ static HRESULT STDMETHODCALLTYPE d3d12_swapchain_GetCoreWindow(IDXGISwapChain3 *
return DXGI_ERROR_INVALID_CALL;
}
-static HRESULT d3d12_swapchain_acquire_next_image(struct d3d12_swapchain *swapchain)
-{
- const struct dxgi_vk_funcs *vk_funcs = &swapchain->vk_funcs;
- VkDevice vk_device = swapchain->vk_device;
- VkFence vk_fence = swapchain->vk_fence;
- VkResult vr;
-
- if ((vr = vk_funcs->p_vkAcquireNextImageKHR(vk_device, swapchain->vk_swapchain, UINT64_MAX,
- VK_NULL_HANDLE, vk_fence, &swapchain->current_buffer_index)) < 0)
- {
- ERR("Failed to acquire next Vulkan image, vr %d.\n", vr);
- return hresult_from_vk_result(vr);
- }
-
- if ((vr = vk_funcs->p_vkWaitForFences(vk_device, 1, &vk_fence, VK_TRUE, UINT64_MAX)) != VK_SUCCESS)
- {
- ERR("Failed to wait for fence, vr %d.\n", vr);
- return hresult_from_vk_result(vr);
- }
- if ((vr = vk_funcs->p_vkResetFences(vk_device, 1, &vk_fence)) < 0)
- {
- ERR("Failed to reset fence, vr %d.\n", vr);
- return hresult_from_vk_result(vr);
- }
-
- return S_OK;
-}
-
static HRESULT d3d12_swapchain_blit_buffer(struct d3d12_swapchain *swapchain, VkQueue vk_queue)
{
const struct dxgi_vk_funcs *vk_funcs = &swapchain->vk_funcs;
More information about the wine-cvs
mailing list