[PATCH 3/7] dxgi: Implement d3d12_swapchain_ResizeTarget().

Henri Verbeet hverbeet at codeweavers.com
Wed Jul 31 15:29:47 CDT 2019


From: Conor McCarthy <cmccarthy at codeweavers.com>

Signed-off-by: Henri Verbeet <hverbeet at codeweavers.com>
---
This supersedes patch 167238.

 dlls/dxgi/device.c        | 44 ++-------------------------
 dlls/dxgi/dxgi_private.h  |  5 ++--
 dlls/dxgi/swapchain.c     | 75 +++++++++++++++++++++++++++++++----------------
 dlls/dxgi/utils.c         | 53 +++++++++++++++++++++++++++++++--
 dlls/wined3d/swapchain.c  | 23 +++++++++++++++
 dlls/wined3d/wined3d.spec |  2 ++
 include/wine/wined3d.h    |  3 ++
 7 files changed, 133 insertions(+), 72 deletions(-)

diff --git a/dlls/dxgi/device.c b/dlls/dxgi/device.c
index e3dc52b8ed6..5500452653e 100644
--- a/dlls/dxgi/device.c
+++ b/dlls/dxgi/device.c
@@ -425,48 +425,8 @@ static HRESULT STDMETHODCALLTYPE dxgi_swapchain_factory_create_swapchain(IWineDX
     TRACE("iface %p, factory %p, window %p, desc %p, fullscreen_desc %p, output %p, swapchain %p.\n",
             iface, factory, window, desc, fullscreen_desc, output, swapchain);
 
-    if (desc->Scaling != DXGI_SCALING_STRETCH)
-        FIXME("Ignoring scaling %#x.\n", desc->Scaling);
-    if (desc->AlphaMode != DXGI_ALPHA_MODE_IGNORE)
-        FIXME("Ignoring alpha mode %#x.\n", desc->AlphaMode);
-    if (fullscreen_desc && fullscreen_desc->ScanlineOrdering)
-        FIXME("Unhandled scanline ordering %#x.\n", fullscreen_desc->ScanlineOrdering);
-    if (fullscreen_desc && fullscreen_desc->Scaling)
-        FIXME("Unhandled mode scaling %#x.\n", fullscreen_desc->Scaling);
-
-    switch (desc->SwapEffect)
-    {
-        case DXGI_SWAP_EFFECT_DISCARD:
-            wined3d_desc.swap_effect = WINED3D_SWAP_EFFECT_DISCARD;
-            break;
-        case DXGI_SWAP_EFFECT_SEQUENTIAL:
-            wined3d_desc.swap_effect = WINED3D_SWAP_EFFECT_SEQUENTIAL;
-            break;
-        case DXGI_SWAP_EFFECT_FLIP_DISCARD:
-            wined3d_desc.swap_effect = WINED3D_SWAP_EFFECT_FLIP_DISCARD;
-            break;
-        case DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL:
-            wined3d_desc.swap_effect = WINED3D_SWAP_EFFECT_FLIP_SEQUENTIAL;
-            break;
-        default:
-            WARN("Invalid swap effect %#x.\n", desc->SwapEffect);
-            return DXGI_ERROR_INVALID_CALL;
-    }
-
-    wined3d_desc.backbuffer_width = desc->Width;
-    wined3d_desc.backbuffer_height = desc->Height;
-    wined3d_desc.backbuffer_format = wined3dformat_from_dxgi_format(desc->Format);
-    wined3d_desc.backbuffer_count = desc->BufferCount;
-    wined3d_desc.backbuffer_bind_flags = wined3d_bind_flags_from_dxgi_usage(desc->BufferUsage);
-    wined3d_sample_desc_from_dxgi(&wined3d_desc.multisample_type,
-            &wined3d_desc.multisample_quality, &desc->SampleDesc);
-    wined3d_desc.device_window = window;
-    wined3d_desc.windowed = fullscreen_desc ? fullscreen_desc->Windowed : TRUE;
-    wined3d_desc.enable_auto_depth_stencil = FALSE;
-    wined3d_desc.auto_depth_stencil_format = 0;
-    wined3d_desc.flags = wined3d_swapchain_flags_from_dxgi(desc->Flags);
-    wined3d_desc.refresh_rate = fullscreen_desc ? dxgi_rational_to_uint(&fullscreen_desc->RefreshRate) : 0;
-    wined3d_desc.auto_restore_display_mode = TRUE;
+    if (FAILED(hr = wined3d_swapchain_desc_from_dxgi(&wined3d_desc, window, desc, fullscreen_desc)))
+        return hr;
 
     if (!(object = heap_alloc_zero(sizeof(*object))))
     {
diff --git a/dlls/dxgi/dxgi_private.h b/dlls/dxgi/dxgi_private.h
index a17c4da83c1..5b934498349 100644
--- a/dlls/dxgi/dxgi_private.h
+++ b/dlls/dxgi/dxgi_private.h
@@ -85,7 +85,6 @@ void dump_feature_levels(const D3D_FEATURE_LEVEL *feature_levels, unsigned int l
 
 DXGI_FORMAT dxgi_format_from_wined3dformat(enum wined3d_format_id format) DECLSPEC_HIDDEN;
 enum wined3d_format_id wined3dformat_from_dxgi_format(DXGI_FORMAT format) DECLSPEC_HIDDEN;
-UINT dxgi_rational_to_uint(const DXGI_RATIONAL *rational) DECLSPEC_HIDDEN;
 void dxgi_sample_desc_from_wined3d(DXGI_SAMPLE_DESC *desc,
         enum wined3d_multisample_type wined3d_type, unsigned int wined3d_quality) DECLSPEC_HIDDEN;
 void wined3d_sample_desc_from_dxgi(enum wined3d_multisample_type *wined3d_type,
@@ -97,7 +96,9 @@ void wined3d_display_mode_from_dxgi1(struct wined3d_display_mode *wined3d_mode,
 DXGI_USAGE dxgi_usage_from_wined3d_bind_flags(unsigned int wined3d_bind_flags) DECLSPEC_HIDDEN;
 unsigned int wined3d_bind_flags_from_dxgi_usage(DXGI_USAGE usage) DECLSPEC_HIDDEN;
 unsigned int dxgi_swapchain_flags_from_wined3d(unsigned int wined3d_flags) DECLSPEC_HIDDEN;
-unsigned int wined3d_swapchain_flags_from_dxgi(unsigned int flags) DECLSPEC_HIDDEN;
+HRESULT wined3d_swapchain_desc_from_dxgi(struct wined3d_swapchain_desc *wined3d_desc,
+        HWND window, const DXGI_SWAP_CHAIN_DESC1 *dxgi_desc,
+        const DXGI_SWAP_CHAIN_FULLSCREEN_DESC *dxgi_fullscreen_desc) DECLSPEC_HIDDEN;
 
 HRESULT dxgi_get_private_data(struct wined3d_private_store *store,
         REFGUID guid, UINT *data_size, void *data) DECLSPEC_HIDDEN;
diff --git a/dlls/dxgi/swapchain.c b/dlls/dxgi/swapchain.c
index 6741b3d489c..728fcacccf6 100644
--- a/dlls/dxgi/swapchain.c
+++ b/dlls/dxgi/swapchain.c
@@ -152,6 +152,37 @@ static HRESULT dxgi_get_output_from_window(IDXGIAdapter *adapter, HWND window, I
     return DXGI_ERROR_NOT_FOUND;
 }
 
+static HRESULT dxgi_swapchain_resize_target(IDXGISwapChain1 *swapchain,
+        struct wined3d_swapchain_state *state, const DXGI_MODE_DESC *target_mode_desc)
+{
+    struct wined3d_display_mode mode;
+    struct dxgi_output *dxgi_output;
+    struct dxgi_adapter *adapter;
+    IDXGIOutput *output;
+    HRESULT hr;
+
+    if (!target_mode_desc)
+    {
+        WARN("Invalid pointer.\n");
+        return DXGI_ERROR_INVALID_CALL;
+    }
+
+    if (FAILED(hr = IDXGISwapChain1_GetContainingOutput(swapchain, &output)))
+        return hr;
+    dxgi_output = unsafe_impl_from_IDXGIOutput(output);
+    adapter = dxgi_output->adapter;
+    IDXGIOutput_Release(output);
+
+    TRACE("Mode: %s.\n", debug_dxgi_mode(target_mode_desc));
+
+    if (target_mode_desc->Scaling)
+        FIXME("Ignoring scaling %#x.\n", target_mode_desc->Scaling);
+
+    wined3d_display_mode_from_dxgi(&mode, target_mode_desc);
+
+    return wined3d_swapchain_state_resize_target(state, adapter->factory->wined3d, adapter->ordinal, &mode);
+}
+
 static HWND d3d11_swapchain_get_hwnd(struct d3d11_swapchain *swapchain)
 {
     struct wined3d_swapchain_desc wined3d_desc;
@@ -521,35 +552,12 @@ static HRESULT STDMETHODCALLTYPE d3d11_swapchain_ResizeTarget(IDXGISwapChain1 *i
 {
     struct d3d11_swapchain *swapchain = d3d11_swapchain_from_IDXGISwapChain1(iface);
     struct wined3d_swapchain_state *state;
-    struct wined3d_display_mode mode;
-    struct dxgi_output *dxgi_output;
-    struct dxgi_adapter *adapter;
-    IDXGIOutput *output;
-    HRESULT hr;
 
     TRACE("iface %p, target_mode_desc %p.\n", iface, target_mode_desc);
 
-    if (!target_mode_desc)
-    {
-        WARN("Invalid pointer.\n");
-        return DXGI_ERROR_INVALID_CALL;
-    }
-
-    if (FAILED(hr = IDXGISwapChain1_GetContainingOutput(iface, &output)))
-        return hr;
-    dxgi_output = unsafe_impl_from_IDXGIOutput(output);
-    adapter = dxgi_output->adapter;
-    IDXGIOutput_Release(output);
-
-    TRACE("Mode: %s.\n", debug_dxgi_mode(target_mode_desc));
-
-    if (target_mode_desc->Scaling)
-        FIXME("Ignoring scaling %#x.\n", target_mode_desc->Scaling);
-
     state = wined3d_swapchain_get_state(swapchain->wined3d_swapchain);
-    wined3d_display_mode_from_dxgi(&mode, target_mode_desc);
 
-    return wined3d_swapchain_state_resize_target(state, adapter->factory->wined3d, adapter->ordinal, &mode);
+    return dxgi_swapchain_resize_target(iface, state, target_mode_desc);
 }
 
 static HRESULT STDMETHODCALLTYPE d3d11_swapchain_GetContainingOutput(IDXGISwapChain1 *iface, IDXGIOutput **output)
@@ -1030,6 +1038,8 @@ struct d3d12_swapchain
     LONG refcount;
     struct wined3d_private_store private_store;
 
+    struct wined3d_swapchain_state *state;
+
     VkSwapchainKHR vk_swapchain;
     VkSurfaceKHR vk_surface;
     VkFence vk_fence;
@@ -1862,6 +1872,8 @@ static void d3d12_swapchain_destroy(struct d3d12_swapchain *swapchain)
         IWineDXGIFactory_Release(swapchain->factory);
 
     close_library(vulkan_module);
+
+    wined3d_swapchain_state_destroy(swapchain->state);
 }
 
 static ULONG STDMETHODCALLTYPE d3d12_swapchain_Release(IDXGISwapChain3 *iface)
@@ -2262,9 +2274,11 @@ static HRESULT STDMETHODCALLTYPE d3d12_swapchain_ResizeBuffers(IDXGISwapChain3 *
 static HRESULT STDMETHODCALLTYPE d3d12_swapchain_ResizeTarget(IDXGISwapChain3 *iface,
         const DXGI_MODE_DESC *target_mode_desc)
 {
-    FIXME("iface %p, target_mode_desc %p stub!\n", iface, target_mode_desc);
+    struct d3d12_swapchain *swapchain = d3d12_swapchain_from_IDXGISwapChain3(iface);
 
-    return E_NOTIMPL;
+    TRACE("iface %p, target_mode_desc %p.\n", iface, target_mode_desc);
+
+    return dxgi_swapchain_resize_target((IDXGISwapChain1 *)iface, swapchain->state, target_mode_desc);
 }
 
 static HRESULT STDMETHODCALLTYPE d3d12_swapchain_GetContainingOutput(IDXGISwapChain3 *iface,
@@ -2701,6 +2715,7 @@ 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 wined3d_swapchain_desc wined3d_desc;
     VkWin32SurfaceCreateInfoKHR surface_desc;
     VkPhysicalDevice vk_physical_device;
     VkFenceCreateInfo fence_desc;
@@ -2745,6 +2760,11 @@ static HRESULT d3d12_swapchain_init(struct d3d12_swapchain *swapchain, IWineDXGI
         return DXGI_ERROR_UNSUPPORTED;
     }
 
+    if (FAILED(hr = wined3d_swapchain_desc_from_dxgi(&wined3d_desc, window, swapchain_desc, fullscreen_desc)))
+        return hr;
+    if (FAILED(hr = wined3d_swapchain_state_create(&wined3d_desc, window, &swapchain->state)))
+        return hr;
+
     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)
@@ -2771,7 +2791,10 @@ static HRESULT d3d12_swapchain_init(struct d3d12_swapchain *swapchain, IWineDXGI
     swapchain->vk_physical_device = vk_physical_device;
 
     if (!init_vk_funcs(&swapchain->vk_funcs, vk_instance, vk_device))
+    {
+        wined3d_swapchain_state_destroy(swapchain->state);
         return E_FAIL;
+    }
 
     wined3d_private_store_init(&swapchain->private_store);
 
diff --git a/dlls/dxgi/utils.c b/dlls/dxgi/utils.c
index be94bde8478..aece3a6af1c 100644
--- a/dlls/dxgi/utils.c
+++ b/dlls/dxgi/utils.c
@@ -415,7 +415,7 @@ void dump_feature_levels(const D3D_FEATURE_LEVEL *feature_levels, unsigned int l
         TRACE("    [%u] = %s.\n", i, debug_feature_level(feature_levels[i]));
 }
 
-UINT dxgi_rational_to_uint(const DXGI_RATIONAL *rational)
+static unsigned int dxgi_rational_to_uint(const DXGI_RATIONAL *rational)
 {
     if (rational->Denominator)
         return rational->Numerator / rational->Denominator;
@@ -537,7 +537,7 @@ unsigned int dxgi_swapchain_flags_from_wined3d(unsigned int wined3d_flags)
     return flags;
 }
 
-unsigned int wined3d_swapchain_flags_from_dxgi(unsigned int flags)
+static unsigned int wined3d_swapchain_flags_from_dxgi(unsigned int flags)
 {
     unsigned int wined3d_flags = DXGI_WINED3D_SWAPCHAIN_FLAGS; /* WINED3D_SWAPCHAIN_DISCARD_DEPTHSTENCIL? */
 
@@ -559,6 +559,55 @@ unsigned int wined3d_swapchain_flags_from_dxgi(unsigned int flags)
     return wined3d_flags;
 }
 
+HRESULT wined3d_swapchain_desc_from_dxgi(struct wined3d_swapchain_desc *wined3d_desc, HWND window,
+        const DXGI_SWAP_CHAIN_DESC1 *dxgi_desc, const DXGI_SWAP_CHAIN_FULLSCREEN_DESC *dxgi_fullscreen_desc)
+{
+    if (dxgi_desc->Scaling != DXGI_SCALING_STRETCH)
+        FIXME("Ignoring scaling %#x.\n", dxgi_desc->Scaling);
+    if (dxgi_desc->AlphaMode != DXGI_ALPHA_MODE_IGNORE)
+        FIXME("Ignoring alpha mode %#x.\n", dxgi_desc->AlphaMode);
+    if (dxgi_fullscreen_desc && dxgi_fullscreen_desc->ScanlineOrdering)
+        FIXME("Unhandled scanline ordering %#x.\n", dxgi_fullscreen_desc->ScanlineOrdering);
+    if (dxgi_fullscreen_desc && dxgi_fullscreen_desc->Scaling)
+        FIXME("Unhandled mode scaling %#x.\n", dxgi_fullscreen_desc->Scaling);
+
+    switch (dxgi_desc->SwapEffect)
+    {
+        case DXGI_SWAP_EFFECT_DISCARD:
+            wined3d_desc->swap_effect = WINED3D_SWAP_EFFECT_DISCARD;
+            break;
+        case DXGI_SWAP_EFFECT_SEQUENTIAL:
+            wined3d_desc->swap_effect = WINED3D_SWAP_EFFECT_SEQUENTIAL;
+            break;
+        case DXGI_SWAP_EFFECT_FLIP_DISCARD:
+            wined3d_desc->swap_effect = WINED3D_SWAP_EFFECT_FLIP_DISCARD;
+            break;
+        case DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL:
+            wined3d_desc->swap_effect = WINED3D_SWAP_EFFECT_FLIP_SEQUENTIAL;
+            break;
+        default:
+            WARN("Invalid swap effect %#x.\n", dxgi_desc->SwapEffect);
+            return DXGI_ERROR_INVALID_CALL;
+    }
+
+    wined3d_desc->backbuffer_width = dxgi_desc->Width;
+    wined3d_desc->backbuffer_height = dxgi_desc->Height;
+    wined3d_desc->backbuffer_format = wined3dformat_from_dxgi_format(dxgi_desc->Format);
+    wined3d_desc->backbuffer_count = dxgi_desc->BufferCount;
+    wined3d_desc->backbuffer_bind_flags = wined3d_bind_flags_from_dxgi_usage(dxgi_desc->BufferUsage);
+    wined3d_sample_desc_from_dxgi(&wined3d_desc->multisample_type,
+            &wined3d_desc->multisample_quality, &dxgi_desc->SampleDesc);
+    wined3d_desc->device_window = window;
+    wined3d_desc->windowed = dxgi_fullscreen_desc ? dxgi_fullscreen_desc->Windowed : TRUE;
+    wined3d_desc->enable_auto_depth_stencil = FALSE;
+    wined3d_desc->auto_depth_stencil_format = 0;
+    wined3d_desc->flags = wined3d_swapchain_flags_from_dxgi(dxgi_desc->Flags);
+    wined3d_desc->refresh_rate = dxgi_fullscreen_desc ? dxgi_rational_to_uint(&dxgi_fullscreen_desc->RefreshRate) : 0;
+    wined3d_desc->auto_restore_display_mode = TRUE;
+
+    return S_OK;
+}
+
 HRESULT dxgi_get_private_data(struct wined3d_private_store *store,
         REFGUID guid, UINT *data_size, void *data)
 {
diff --git a/dlls/wined3d/swapchain.c b/dlls/wined3d/swapchain.c
index 2669207cfa3..333c3153f68 100644
--- a/dlls/wined3d/swapchain.c
+++ b/dlls/wined3d/swapchain.c
@@ -1588,3 +1588,26 @@ HRESULT CDECL wined3d_swapchain_set_fullscreen(struct wined3d_swapchain *swapcha
 
     return WINED3D_OK;
 }
+
+void CDECL wined3d_swapchain_state_destroy(struct wined3d_swapchain_state *state)
+{
+    heap_free(state);
+}
+
+HRESULT CDECL wined3d_swapchain_state_create(const struct wined3d_swapchain_desc *desc,
+        HWND window, struct wined3d_swapchain_state **state)
+{
+    struct wined3d_swapchain_state *s;
+
+    TRACE("desc %p, window %p, state %p.\n", desc, window, state);
+
+    if (!(s = heap_alloc_zero(sizeof(*s))))
+        return E_OUTOFMEMORY;
+
+    s->desc = *desc;
+    s->device_window = window;
+
+    *state = s;
+
+    return WINED3D_OK;
+}
diff --git a/dlls/wined3d/wined3d.spec b/dlls/wined3d/wined3d.spec
index bd91e92c683..01e466e0147 100644
--- a/dlls/wined3d/wined3d.spec
+++ b/dlls/wined3d/wined3d.spec
@@ -278,6 +278,8 @@
 @ cdecl wined3d_swapchain_set_palette(ptr ptr)
 @ cdecl wined3d_swapchain_set_window(ptr ptr)
 
+@ cdecl wined3d_swapchain_state_create(ptr ptr ptr)
+@ cdecl wined3d_swapchain_state_destroy(ptr)
 @ cdecl wined3d_swapchain_state_resize_target(ptr ptr long ptr)
 
 @ cdecl wined3d_texture_add_dirty_region(ptr long ptr)
diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h
index bbb58ba8320..bae2cf86184 100644
--- a/include/wine/wined3d.h
+++ b/include/wine/wined3d.h
@@ -2691,6 +2691,9 @@ HRESULT __cdecl wined3d_swapchain_set_gamma_ramp(const struct wined3d_swapchain
 void __cdecl wined3d_swapchain_set_palette(struct wined3d_swapchain *swapchain, struct wined3d_palette *palette);
 void __cdecl wined3d_swapchain_set_window(struct wined3d_swapchain *swapchain, HWND window);
 
+HRESULT __cdecl wined3d_swapchain_state_create(const struct wined3d_swapchain_desc *desc,
+        HWND window, struct wined3d_swapchain_state **state);
+void __cdecl wined3d_swapchain_state_destroy(struct wined3d_swapchain_state *state);
 HRESULT __cdecl wined3d_swapchain_state_resize_target(struct wined3d_swapchain_state *state,
         struct wined3d *wined3d, unsigned int adapter_idx, const struct wined3d_display_mode *mode);
 
-- 
2.11.0




More information about the wine-devel mailing list