[prev in list] [next in list] [prev in thread] [next in thread] 

List:       wine-devel
Subject:    [PATCH 3/7] dxgi: Implement d3d12_swapchain_ResizeTarget().
From:       Henri Verbeet <hverbeet () codeweavers ! com>
Date:       2019-07-31 20:41:47
Message-ID: 20190731202951.3683-3-hverbeet () codeweavers ! com
[Download RAW message or body]

From: Conor McCarthy <cmccarthy@codeweavers.com>

Signed-off-by: Henri Verbeet <hverbeet@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


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic