[PATCH 02/11] wined3d: Add WINED3DSWAPCHAIN_ALLOW_MODE_SWITCH flag.

Józef Kucia jkucia at codeweavers.com
Mon Aug 1 15:28:36 CDT 2016


Signed-off-by: Józef Kucia <jkucia at codeweavers.com>
---
 dlls/d3d8/d3d8_private.h |  2 ++
 dlls/d3d8/device.c       |  8 +++--
 dlls/d3d9/d3d9_private.h |  2 ++
 dlls/d3d9/device.c       |  8 +++--
 dlls/ddraw/ddraw.c       |  1 +
 dlls/dxgi/dxgi_private.h |  2 ++
 dlls/dxgi/factory.c      |  8 ++---
 dlls/dxgi/swapchain.c    |  4 +--
 dlls/dxgi/utils.c        | 32 +++++++++++++++++
 dlls/wined3d/cs.c        |  2 +-
 dlls/wined3d/swapchain.c | 91 ++++++++++++++++++++++++++++++------------------
 include/wine/wined3d.h   | 13 +++----
 12 files changed, 122 insertions(+), 51 deletions(-)

diff --git a/dlls/d3d8/d3d8_private.h b/dlls/d3d8/d3d8_private.h
index 958b3c0..c26912b 100644
--- a/dlls/d3d8/d3d8_private.h
+++ b/dlls/d3d8/d3d8_private.h
@@ -36,6 +36,8 @@
 #include "d3d8.h"
 #include "wine/wined3d.h"
 
+#define D3DPRESENTFLAGS_MASK 0x00000fff
+
 /* CreateVertexShader can return > 0xFFFF */
 #define VS_HIGHESTFIXEDFXF 0xF0000000
 
diff --git a/dlls/d3d8/device.c b/dlls/d3d8/device.c
index bf333c1..8d21956 100644
--- a/dlls/d3d8/device.c
+++ b/dlls/d3d8/device.c
@@ -183,7 +183,7 @@ static void present_parameters_from_wined3d_swapchain_desc(D3DPRESENT_PARAMETERS
     present_parameters->EnableAutoDepthStencil = swapchain_desc->enable_auto_depth_stencil;
     present_parameters->AutoDepthStencilFormat
             = d3dformat_from_wined3dformat(swapchain_desc->auto_depth_stencil_format);
-    present_parameters->Flags = swapchain_desc->flags;
+    present_parameters->Flags = swapchain_desc->flags & D3DPRESENTFLAGS_MASK;
     present_parameters->FullScreen_RefreshRateInHz = swapchain_desc->refresh_rate;
     present_parameters->FullScreen_PresentationInterval = swapchain_desc->swap_interval;
 }
@@ -217,11 +217,15 @@ static BOOL wined3d_swapchain_desc_from_present_parameters(struct wined3d_swapch
     swapchain_desc->enable_auto_depth_stencil = present_parameters->EnableAutoDepthStencil;
     swapchain_desc->auto_depth_stencil_format
             = wined3dformat_from_d3dformat(present_parameters->AutoDepthStencilFormat);
-    swapchain_desc->flags = present_parameters->Flags;
+    swapchain_desc->flags
+            = (present_parameters->Flags & D3DPRESENTFLAGS_MASK) | WINED3DSWAPCHAIN_ALLOW_MODE_SWITCH;
     swapchain_desc->refresh_rate = present_parameters->FullScreen_RefreshRateInHz;
     swapchain_desc->swap_interval = present_parameters->FullScreen_PresentationInterval;
     swapchain_desc->auto_restore_display_mode = TRUE;
 
+    if (present_parameters->Flags & ~D3DPRESENTFLAGS_MASK)
+        FIXME("Unhandled flags %#x.\n", present_parameters->Flags & ~D3DPRESENTFLAGS_MASK);
+
     return TRUE;
 }
 
diff --git a/dlls/d3d9/d3d9_private.h b/dlls/d3d9/d3d9_private.h
index b618ff4..697164e 100644
--- a/dlls/d3d9/d3d9_private.h
+++ b/dlls/d3d9/d3d9_private.h
@@ -39,6 +39,8 @@
 #include "d3d9.h"
 #include "wine/wined3d.h"
 
+#define D3DPRESENTFLAGS_MASK 0x00000fff
+
 extern HRESULT vdecl_convert_fvf(DWORD FVF, D3DVERTEXELEMENT9 **ppVertexElements) DECLSPEC_HIDDEN;
 D3DFORMAT d3dformat_from_wined3dformat(enum wined3d_format_id format) DECLSPEC_HIDDEN;
 enum wined3d_format_id wined3dformat_from_d3dformat(D3DFORMAT format) DECLSPEC_HIDDEN;
diff --git a/dlls/d3d9/device.c b/dlls/d3d9/device.c
index 85bc1d0..0c03476 100644
--- a/dlls/d3d9/device.c
+++ b/dlls/d3d9/device.c
@@ -203,7 +203,7 @@ void present_parameters_from_wined3d_swapchain_desc(D3DPRESENT_PARAMETERS *prese
     present_parameters->EnableAutoDepthStencil = swapchain_desc->enable_auto_depth_stencil;
     present_parameters->AutoDepthStencilFormat
             = d3dformat_from_wined3dformat(swapchain_desc->auto_depth_stencil_format);
-    present_parameters->Flags = swapchain_desc->flags;
+    present_parameters->Flags = swapchain_desc->flags & D3DPRESENTFLAGS_MASK;
     present_parameters->FullScreen_RefreshRateInHz = swapchain_desc->refresh_rate;
     present_parameters->PresentationInterval = swapchain_desc->swap_interval;
 }
@@ -239,11 +239,15 @@ static BOOL wined3d_swapchain_desc_from_present_parameters(struct wined3d_swapch
     swapchain_desc->enable_auto_depth_stencil = present_parameters->EnableAutoDepthStencil;
     swapchain_desc->auto_depth_stencil_format
             = wined3dformat_from_d3dformat(present_parameters->AutoDepthStencilFormat);
-    swapchain_desc->flags = present_parameters->Flags;
+    swapchain_desc->flags
+            = (present_parameters->Flags & D3DPRESENTFLAGS_MASK) | WINED3DSWAPCHAIN_ALLOW_MODE_SWITCH;
     swapchain_desc->refresh_rate = present_parameters->FullScreen_RefreshRateInHz;
     swapchain_desc->swap_interval = present_parameters->PresentationInterval;
     swapchain_desc->auto_restore_display_mode = TRUE;
 
+    if (present_parameters->Flags & ~D3DPRESENTFLAGS_MASK)
+        FIXME("Unhandled flags %#x.\n", present_parameters->Flags & ~D3DPRESENTFLAGS_MASK);
+
     return TRUE;
 }
 
diff --git a/dlls/ddraw/ddraw.c b/dlls/ddraw/ddraw.c
index 68e4f33..fadf856 100644
--- a/dlls/ddraw/ddraw.c
+++ b/dlls/ddraw/ddraw.c
@@ -631,6 +631,7 @@ static HRESULT ddraw_create_swapchain(struct ddraw *ddraw, HWND window, BOOL win
     swapchain_desc.swap_effect = WINED3D_SWAP_EFFECT_COPY;
     swapchain_desc.device_window = window;
     swapchain_desc.windowed = windowed;
+    swapchain_desc.flags = WINED3DSWAPCHAIN_ALLOW_MODE_SWITCH;
 
     if (!(ddraw->flags & DDRAW_NO3D))
         hr = ddraw_attach_d3d_device(ddraw, &swapchain_desc);
diff --git a/dlls/dxgi/dxgi_private.h b/dlls/dxgi/dxgi_private.h
index 804ae99..680f835 100644
--- a/dlls/dxgi/dxgi_private.h
+++ b/dlls/dxgi/dxgi_private.h
@@ -87,6 +87,8 @@ 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,
         unsigned int *wined3d_quality, const DXGI_SAMPLE_DESC *dxgi_desc) 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 dxgi_get_private_data(struct wined3d_private_store *store,
         REFGUID guid, UINT *data_size, void *data) DECLSPEC_HIDDEN;
 HRESULT dxgi_set_private_data(struct wined3d_private_store *store,
diff --git a/dlls/dxgi/factory.c b/dlls/dxgi/factory.c
index 1af7f72..3aa8597 100644
--- a/dlls/dxgi/factory.c
+++ b/dlls/dxgi/factory.c
@@ -193,9 +193,9 @@ static HRESULT STDMETHODCALLTYPE dxgi_factory_CreateSwapChain(IDXGIFactory1 *ifa
 {
     struct wined3d_swapchain *wined3d_swapchain;
     struct wined3d_swapchain_desc wined3d_desc;
+    unsigned int min_buffer_count;
     IWineDXGIDevice *dxgi_device;
     HRESULT hr;
-    UINT min_buffer_count;
 
     FIXME("iface %p, device %p, desc %p, swapchain %p partial stub!\n", iface, device, desc, swapchain);
 
@@ -223,7 +223,7 @@ static HRESULT STDMETHODCALLTYPE dxgi_factory_CreateSwapChain(IDXGIFactory1 *ifa
     }
     if (!desc->OutputWindow)
     {
-        FIXME("No output window, should use factory output window\n");
+        FIXME("No output window, should use factory output window.\n");
     }
 
     hr = IUnknown_QueryInterface(device, &IID_IWineDXGIDevice, (void **)&dxgi_device);
@@ -233,7 +233,7 @@ static HRESULT STDMETHODCALLTYPE dxgi_factory_CreateSwapChain(IDXGIFactory1 *ifa
         return hr;
     }
 
-    FIXME("Ignoring SwapEffect and Flags\n");
+    FIXME("Ignoring SwapEffect %#x.\n", desc->SwapEffect);
 
     wined3d_desc.backbuffer_width = desc->BufferDesc.Width;
     wined3d_desc.backbuffer_height = desc->BufferDesc.Height;
@@ -246,7 +246,7 @@ static HRESULT STDMETHODCALLTYPE dxgi_factory_CreateSwapChain(IDXGIFactory1 *ifa
     wined3d_desc.windowed = desc->Windowed;
     wined3d_desc.enable_auto_depth_stencil = FALSE;
     wined3d_desc.auto_depth_stencil_format = 0;
-    wined3d_desc.flags = 0; /* WINED3DPRESENTFLAG_DISCARD_DEPTHSTENCIL? */
+    wined3d_desc.flags = wined3d_swapchain_flags_from_dxgi(desc->Flags);
     wined3d_desc.refresh_rate = dxgi_rational_to_uint(&desc->BufferDesc.RefreshRate);
     wined3d_desc.swap_interval = WINED3DPRESENT_INTERVAL_DEFAULT;
     wined3d_desc.auto_restore_display_mode = TRUE;
diff --git a/dlls/dxgi/swapchain.c b/dlls/dxgi/swapchain.c
index 921fcdf..54bd52d 100644
--- a/dlls/dxgi/swapchain.c
+++ b/dlls/dxgi/swapchain.c
@@ -231,7 +231,7 @@ static HRESULT STDMETHODCALLTYPE dxgi_swapchain_GetDesc(IDXGISwapChain *iface, D
     wined3d_swapchain_get_desc(swapchain->wined3d_swapchain, &wined3d_desc);
     wined3d_mutex_unlock();
 
-    FIXME("Ignoring ScanlineOrdering, Scaling, SwapEffect and Flags\n");
+    FIXME("Ignoring ScanlineOrdering, Scaling and SwapEffect.\n");
 
     desc->BufferDesc.Width = wined3d_desc.backbuffer_width;
     desc->BufferDesc.Height = wined3d_desc.backbuffer_height;
@@ -245,7 +245,7 @@ static HRESULT STDMETHODCALLTYPE dxgi_swapchain_GetDesc(IDXGISwapChain *iface, D
     desc->OutputWindow = wined3d_desc.device_window;
     desc->Windowed = wined3d_desc.windowed;
     desc->SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
-    desc->Flags = 0;
+    desc->Flags = dxgi_swapchain_flags_from_wined3d(wined3d_desc.flags);
 
     return S_OK;
 }
diff --git a/dlls/dxgi/utils.c b/dlls/dxgi/utils.c
index c01dd9b..1273832 100644
--- a/dlls/dxgi/utils.c
+++ b/dlls/dxgi/utils.c
@@ -401,6 +401,38 @@ void wined3d_sample_desc_from_dxgi(enum wined3d_multisample_type *wined3d_type,
     }
 }
 
+unsigned int dxgi_swapchain_flags_from_wined3d(unsigned int wined3d_flags)
+{
+    unsigned int flags = 0;
+
+    if (wined3d_flags & WINED3DSWAPCHAIN_ALLOW_MODE_SWITCH)
+    {
+        wined3d_flags &= ~WINED3DSWAPCHAIN_ALLOW_MODE_SWITCH;
+        flags |= DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;
+    }
+
+    if (wined3d_flags)
+        FIXME("Unhandled flags %#x.\n", flags);
+
+    return flags;
+}
+
+unsigned int wined3d_swapchain_flags_from_dxgi(unsigned int flags)
+{
+    unsigned int wined3d_flags = 0; /* WINED3DSWAPCHAIN_DISCARD_DEPTHSTENCIL? */
+
+    if (flags & DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH)
+    {
+        flags &= ~DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;
+        wined3d_flags |= WINED3DSWAPCHAIN_ALLOW_MODE_SWITCH;
+    }
+
+    if (flags)
+        FIXME("Unhandled flags %#x.\n", flags);
+
+    return wined3d_flags;
+}
+
 HRESULT dxgi_get_private_data(struct wined3d_private_store *store,
         REFGUID guid, UINT *data_size, void *data)
 {
diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c
index b52e887..4344b89 100644
--- a/dlls/wined3d/cs.c
+++ b/dlls/wined3d/cs.c
@@ -586,7 +586,7 @@ static void wined3d_cs_exec_set_depth_stencil_view(struct wined3d_cs *cs, const
     {
         struct wined3d_surface *prev_surface = wined3d_rendertarget_view_get_surface(prev);
 
-        if (prev_surface && (device->swapchains[0]->desc.flags & WINED3DPRESENTFLAG_DISCARD_DEPTHSTENCIL
+        if (prev_surface && (device->swapchains[0]->desc.flags & WINED3DSWAPCHAIN_DISCARD_DEPTHSTENCIL
                 || prev_surface->container->flags & WINED3D_TEXTURE_DISCARD))
         {
             surface_modify_ds_location(prev_surface, WINED3D_LOCATION_DISCARDED, prev->width, prev->height);
diff --git a/dlls/wined3d/swapchain.c b/dlls/wined3d/swapchain.c
index 28629ab..e7fd25f 100644
--- a/dlls/wined3d/swapchain.c
+++ b/dlls/wined3d/swapchain.c
@@ -614,7 +614,7 @@ static void swapchain_gl_present(struct wined3d_swapchain *swapchain,
     {
         struct wined3d_surface *ds = wined3d_rendertarget_view_get_surface(fb->depth_stencil);
 
-        if (ds && (swapchain->desc.flags & WINED3DPRESENTFLAG_DISCARD_DEPTHSTENCIL
+        if (ds && (swapchain->desc.flags & WINED3DSWAPCHAIN_DISCARD_DEPTHSTENCIL
                 || ds->container->flags & WINED3D_TEXTURE_DISCARD))
         {
             surface_modify_ds_location(ds, WINED3D_LOCATION_DISCARDED,
@@ -841,11 +841,8 @@ static HRESULT swapchain_init(struct wined3d_swapchain *swapchain, struct wined3
     }
 
     GetClientRect(window, &client_rect);
-    if (desc->windowed
-            && (!desc->backbuffer_width || !desc->backbuffer_height
-            || desc->backbuffer_format == WINED3DFMT_UNKNOWN))
+    if (desc->windowed)
     {
-
         if (!desc->backbuffer_width)
         {
             desc->backbuffer_width = client_rect.right;
@@ -899,22 +896,29 @@ static HRESULT swapchain_init(struct wined3d_swapchain *swapchain, struct wined3
     /* MSDN says we're only allowed a single fullscreen swapchain per device,
      * so we should really check to see if there is a fullscreen swapchain
      * already. Does a single head count as full screen? */
-
     if (!desc->windowed)
     {
-        /* Change the display settings */
-        swapchain->d3d_mode.width = desc->backbuffer_width;
-        swapchain->d3d_mode.height = desc->backbuffer_height;
-        swapchain->d3d_mode.format_id = desc->backbuffer_format;
-        swapchain->d3d_mode.refresh_rate = desc->refresh_rate;
-        swapchain->d3d_mode.scanline_ordering = WINED3D_SCANLINE_ORDERING_UNKNOWN;
-
-        if (FAILED(hr = wined3d_set_adapter_display_mode(device->wined3d, adapter->ordinal, &swapchain->d3d_mode)))
+        if (desc->flags & WINED3DSWAPCHAIN_ALLOW_MODE_SWITCH)
         {
-            WARN("Failed to set display mode, hr %#x.\n", hr);
-            goto err;
+            /* Change the display settings */
+            swapchain->d3d_mode.width = desc->backbuffer_width;
+            swapchain->d3d_mode.height = desc->backbuffer_height;
+            swapchain->d3d_mode.format_id = desc->backbuffer_format;
+            swapchain->d3d_mode.refresh_rate = desc->refresh_rate;
+            swapchain->d3d_mode.scanline_ordering = WINED3D_SCANLINE_ORDERING_UNKNOWN;
+
+            if (FAILED(hr = wined3d_set_adapter_display_mode(device->wined3d,
+                    adapter->ordinal, &swapchain->d3d_mode)))
+            {
+                WARN("Failed to set display mode, hr %#x.\n", hr);
+                goto err;
+            }
+            displaymode_set = TRUE;
+        }
+        else
+        {
+            swapchain->d3d_mode = swapchain->original_mode;
         }
-        displaymode_set = TRUE;
     }
 
     if (!(device->wined3d->flags & WINED3D_NO3D))
@@ -1398,30 +1402,49 @@ HRESULT CDECL wined3d_swapchain_set_fullscreen(struct wined3d_swapchain *swapcha
 
     TRACE("swapchain %p, desc %p, mode %p.\n", swapchain, swapchain_desc, mode);
 
-    width = swapchain_desc->backbuffer_width;
-    height = swapchain_desc->backbuffer_height;
-
-    if (!mode)
+    if (swapchain->desc.flags & WINED3DSWAPCHAIN_ALLOW_MODE_SWITCH)
     {
-        if (!swapchain_desc->windowed)
+        width = swapchain_desc->backbuffer_width;
+        height = swapchain_desc->backbuffer_height;
+
+        if (!mode)
+        {
+            if (!swapchain_desc->windowed)
+            {
+                default_mode.width = swapchain_desc->backbuffer_width;
+                default_mode.height = swapchain_desc->backbuffer_height;
+                default_mode.refresh_rate = swapchain_desc->refresh_rate;
+                default_mode.format_id = swapchain_desc->backbuffer_format;
+                default_mode.scanline_ordering = WINED3D_SCANLINE_ORDERING_UNKNOWN;
+            }
+            else
+            {
+                default_mode = swapchain->original_mode;
+            }
+            mode = &default_mode;
+        }
+
+        if (FAILED(hr = wined3d_set_adapter_display_mode(device->wined3d, device->adapter->ordinal, mode)))
         {
-            default_mode.width = swapchain_desc->backbuffer_width;
-            default_mode.height = swapchain_desc->backbuffer_height;
-            default_mode.refresh_rate = swapchain_desc->refresh_rate;
-            default_mode.format_id = swapchain_desc->backbuffer_format;
-            default_mode.scanline_ordering = WINED3D_SCANLINE_ORDERING_UNKNOWN;
+            WARN("Failed to set display mode, hr %#x.\n", hr);
+            return WINED3DERR_INVALIDCALL;
         }
-        else
+    }
+    else
+    {
+        if (mode)
+            ERR("Ignoring mode.\n");
+
+        if (FAILED(hr = wined3d_get_adapter_display_mode(device->wined3d, device->adapter->ordinal,
+                &default_mode, NULL)))
         {
-            default_mode = swapchain->original_mode;
+            ERR("Failed to get display mode, hr %#x.\n", hr);
+            return WINED3DERR_INVALIDCALL;
         }
         mode = &default_mode;
-    }
 
-    if (FAILED(hr = wined3d_set_adapter_display_mode(device->wined3d, device->adapter->ordinal, mode)))
-    {
-        WARN("Failed to set display mode, hr %#x.\n", hr);
-        return WINED3DERR_INVALIDCALL;
+        width = mode->width;
+        height = mode->height;
     }
 
     if (!swapchain_desc->windowed)
diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h
index 948a57b..0808f65 100644
--- a/include/wine/wined3d.h
+++ b/include/wine/wined3d.h
@@ -818,12 +818,13 @@ enum wined3d_display_rotation
 #define WINED3DTA_COMPLEMENT                                    0x00000010
 #define WINED3DTA_ALPHAREPLICATE                                0x00000020
 
-#define WINED3DPRESENTFLAG_LOCKABLE_BACKBUFFER                  0x00000001
-#define WINED3DPRESENTFLAG_DISCARD_DEPTHSTENCIL                 0x00000002
-#define WINED3DPRESENTFLAG_DEVICECLIP                           0x00000004
-#define WINED3DPRESENTFLAG_VIDEO                                0x00000010
-#define WINED3DPRESENTFLAG_NOAUTOROTATE                         0x00000020
-#define WINED3DPRESENTFLAG_UNPRUNEDMODE                         0x00000040
+#define WINED3DSWAPCHAIN_LOCKABLE_BACKBUFFER                    0x00000001
+#define WINED3DSWAPCHAIN_DISCARD_DEPTHSTENCIL                   0x00000002
+#define WINED3DSWAPCHAIN_DEVICECLIP                             0x00000004
+#define WINED3DSWAPCHAIN_VIDEO                                  0x00000010
+#define WINED3DSWAPCHAIN_NOAUTOROTATE                           0x00000020
+#define WINED3DSWAPCHAIN_UNPRUNEDMODE                           0x00000040
+#define WINED3DSWAPCHAIN_ALLOW_MODE_SWITCH                      0x00001000
 
 #define WINED3DDP_MAXTEXCOORD                                   8
 
-- 
2.7.3




More information about the wine-patches mailing list