[PATCH 3/5] wined3d: Take scanline ordering into account in the mode setting code.

Henri Verbeet hverbeet at codeweavers.com
Wed Jun 27 12:02:27 CDT 2012


---
 dlls/d3d8/device.c       |   10 ++++++++--
 dlls/d3d8/directx.c      |   21 ++++++++++++++++-----
 dlls/d3d9/device.c       |   10 ++++++++--
 dlls/d3d9/directx.c      |   20 ++++++++++++++++----
 dlls/d3d9/swapchain.c    |   10 ++++++++--
 dlls/ddraw/ddraw.c       |    1 +
 dlls/dxgi/output.c       |    2 +-
 dlls/wined3d/device.c    |    2 ++
 dlls/wined3d/directx.c   |   39 ++++++++++++++++++++++++++++++++-------
 dlls/wined3d/swapchain.c |    2 ++
 include/wine/wined3d.h   |    8 ++++++++
 11 files changed, 102 insertions(+), 23 deletions(-)

diff --git a/dlls/d3d8/device.c b/dlls/d3d8/device.c
index 48e4d65..22d3b88 100644
--- a/dlls/d3d8/device.c
+++ b/dlls/d3d8/device.c
@@ -415,16 +415,22 @@ static HRESULT WINAPI d3d8_device_GetDeviceCaps(IDirect3DDevice8 *iface, D3DCAPS
 static HRESULT WINAPI d3d8_device_GetDisplayMode(IDirect3DDevice8 *iface, D3DDISPLAYMODE *mode)
 {
     struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
+    struct wined3d_display_mode wined3d_mode;
     HRESULT hr;
 
     TRACE("iface %p, mode %p.\n", iface, mode);
 
     wined3d_mutex_lock();
-    hr = wined3d_device_get_display_mode(device->wined3d_device, 0, (struct wined3d_display_mode *)mode);
+    hr = wined3d_device_get_display_mode(device->wined3d_device, 0, &wined3d_mode);
     wined3d_mutex_unlock();
 
     if (SUCCEEDED(hr))
-        mode->Format = d3dformat_from_wined3dformat(mode->Format);
+    {
+        mode->Width = wined3d_mode.width;
+        mode->Height = wined3d_mode.height;
+        mode->RefreshRate = wined3d_mode.refresh_rate;
+        mode->Format = d3dformat_from_wined3dformat(wined3d_mode.format_id);
+    }
 
     return hr;
 }
diff --git a/dlls/d3d8/directx.c b/dlls/d3d8/directx.c
index 224a063..96113fb 100644
--- a/dlls/d3d8/directx.c
+++ b/dlls/d3d8/directx.c
@@ -166,18 +166,23 @@ static UINT WINAPI d3d8_GetAdapterModeCount(IDirect3D8 *iface, UINT adapter)
 static HRESULT WINAPI d3d8_EnumAdapterModes(IDirect3D8 *iface, UINT adapter, UINT mode_idx, D3DDISPLAYMODE *mode)
 {
     struct d3d8 *d3d8 = impl_from_IDirect3D8(iface);
+    struct wined3d_display_mode wined3d_mode;
     HRESULT hr;
 
     TRACE("iface %p, adapter %u, mode_idx %u, mode %p.\n",
             iface, adapter, mode_idx, mode);
 
     wined3d_mutex_lock();
-    hr = wined3d_enum_adapter_modes(d3d8->wined3d, adapter, WINED3DFMT_UNKNOWN,
-            mode_idx, (struct wined3d_display_mode *)mode);
+    hr = wined3d_enum_adapter_modes(d3d8->wined3d, adapter, WINED3DFMT_UNKNOWN, mode_idx, &wined3d_mode);
     wined3d_mutex_unlock();
 
     if (SUCCEEDED(hr))
-        mode->Format = d3dformat_from_wined3dformat(mode->Format);
+    {
+        mode->Width = wined3d_mode.width;
+        mode->Height = wined3d_mode.height;
+        mode->RefreshRate = wined3d_mode.refresh_rate;
+        mode->Format = d3dformat_from_wined3dformat(wined3d_mode.format_id);
+    }
 
     return hr;
 }
@@ -185,17 +190,23 @@ static HRESULT WINAPI d3d8_EnumAdapterModes(IDirect3D8 *iface, UINT adapter, UIN
 static HRESULT WINAPI d3d8_GetAdapterDisplayMode(IDirect3D8 *iface, UINT adapter, D3DDISPLAYMODE *mode)
 {
     struct d3d8 *d3d8 = impl_from_IDirect3D8(iface);
+    struct wined3d_display_mode wined3d_mode;
     HRESULT hr;
 
     TRACE("iface %p, adapter %u, mode %p.\n",
             iface, adapter, mode);
 
     wined3d_mutex_lock();
-    hr = wined3d_get_adapter_display_mode(d3d8->wined3d, adapter, (struct wined3d_display_mode *)mode);
+    hr = wined3d_get_adapter_display_mode(d3d8->wined3d, adapter, &wined3d_mode);
     wined3d_mutex_unlock();
 
     if (SUCCEEDED(hr))
-        mode->Format = d3dformat_from_wined3dformat(mode->Format);
+    {
+        mode->Width = wined3d_mode.width;
+        mode->Height = wined3d_mode.height;
+        mode->RefreshRate = wined3d_mode.refresh_rate;
+        mode->Format = d3dformat_from_wined3dformat(wined3d_mode.format_id);
+    }
 
     return hr;
 }
diff --git a/dlls/d3d9/device.c b/dlls/d3d9/device.c
index 1014c27..44f6490 100644
--- a/dlls/d3d9/device.c
+++ b/dlls/d3d9/device.c
@@ -357,16 +357,22 @@ static HRESULT WINAPI d3d9_device_GetDeviceCaps(IDirect3DDevice9Ex *iface, D3DCA
 static HRESULT WINAPI d3d9_device_GetDisplayMode(IDirect3DDevice9Ex *iface, UINT swapchain, D3DDISPLAYMODE *mode)
 {
     struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
+    struct wined3d_display_mode wined3d_mode;
     HRESULT hr;
 
     TRACE("iface %p, swapchain %u, mode %p.\n", iface, swapchain, mode);
 
     wined3d_mutex_lock();
-    hr = wined3d_device_get_display_mode(device->wined3d_device, swapchain, (struct wined3d_display_mode *)mode);
+    hr = wined3d_device_get_display_mode(device->wined3d_device, swapchain, &wined3d_mode);
     wined3d_mutex_unlock();
 
     if (SUCCEEDED(hr))
-        mode->Format = d3dformat_from_wined3dformat(mode->Format);
+    {
+        mode->Width = wined3d_mode.width;
+        mode->Height = wined3d_mode.height;
+        mode->RefreshRate = wined3d_mode.refresh_rate;
+        mode->Format = d3dformat_from_wined3dformat(wined3d_mode.format_id);
+    }
 
     return hr;
 }
diff --git a/dlls/d3d9/directx.c b/dlls/d3d9/directx.c
index ae315e3..c96d1a6 100644
--- a/dlls/d3d9/directx.c
+++ b/dlls/d3d9/directx.c
@@ -174,6 +174,7 @@ static HRESULT WINAPI d3d9_EnumAdapterModes(IDirect3D9Ex *iface, UINT adapter,
         D3DFORMAT format, UINT mode_idx, D3DDISPLAYMODE *mode)
 {
     struct d3d9 *d3d9 = impl_from_IDirect3D9Ex(iface);
+    struct wined3d_display_mode wined3d_mode;
     HRESULT hr;
 
     TRACE("iface %p, adapter %u, format %#x, mode_idx %u, mode %p.\n",
@@ -184,11 +185,16 @@ static HRESULT WINAPI d3d9_EnumAdapterModes(IDirect3D9Ex *iface, UINT adapter,
 
     wined3d_mutex_lock();
     hr = wined3d_enum_adapter_modes(d3d9->wined3d, adapter, wined3dformat_from_d3dformat(format),
-            mode_idx, (struct wined3d_display_mode *)mode);
+            mode_idx, &wined3d_mode);
     wined3d_mutex_unlock();
 
     if (SUCCEEDED(hr))
-        mode->Format = d3dformat_from_wined3dformat(mode->Format);
+    {
+        mode->Width = wined3d_mode.width;
+        mode->Height = wined3d_mode.height;
+        mode->RefreshRate = wined3d_mode.refresh_rate;
+        mode->Format = d3dformat_from_wined3dformat(wined3d_mode.format_id);
+    }
 
     return hr;
 }
@@ -196,16 +202,22 @@ static HRESULT WINAPI d3d9_EnumAdapterModes(IDirect3D9Ex *iface, UINT adapter,
 static HRESULT WINAPI d3d9_GetAdapterDisplayMode(IDirect3D9Ex *iface, UINT adapter, D3DDISPLAYMODE *mode)
 {
     struct d3d9 *d3d9 = impl_from_IDirect3D9Ex(iface);
+    struct wined3d_display_mode wined3d_mode;
     HRESULT hr;
 
     TRACE("iface %p, adapter %u, mode %p.\n", iface, adapter, mode);
 
     wined3d_mutex_lock();
-    hr = wined3d_get_adapter_display_mode(d3d9->wined3d, adapter, (struct wined3d_display_mode *)mode);
+    hr = wined3d_get_adapter_display_mode(d3d9->wined3d, adapter, &wined3d_mode);
     wined3d_mutex_unlock();
 
     if (SUCCEEDED(hr))
-        mode->Format = d3dformat_from_wined3dformat(mode->Format);
+    {
+        mode->Width = wined3d_mode.width;
+        mode->Height = wined3d_mode.height;
+        mode->RefreshRate = wined3d_mode.refresh_rate;
+        mode->Format = d3dformat_from_wined3dformat(wined3d_mode.format_id);
+    }
 
     return hr;
 }
diff --git a/dlls/d3d9/swapchain.c b/dlls/d3d9/swapchain.c
index b70067d..b8439a9 100644
--- a/dlls/d3d9/swapchain.c
+++ b/dlls/d3d9/swapchain.c
@@ -169,16 +169,22 @@ static HRESULT WINAPI d3d9_swapchain_GetRasterStatus(IDirect3DSwapChain9 *iface,
 static HRESULT WINAPI d3d9_swapchain_GetDisplayMode(IDirect3DSwapChain9 *iface, D3DDISPLAYMODE *mode)
 {
     struct d3d9_swapchain *swapchain = impl_from_IDirect3DSwapChain9(iface);
+    struct wined3d_display_mode wined3d_mode;
     HRESULT hr;
 
     TRACE("iface %p, mode %p.\n", iface, mode);
 
     wined3d_mutex_lock();
-    hr = wined3d_swapchain_get_display_mode(swapchain->wined3d_swapchain, (struct wined3d_display_mode *)mode);
+    hr = wined3d_swapchain_get_display_mode(swapchain->wined3d_swapchain, &wined3d_mode);
     wined3d_mutex_unlock();
 
     if (SUCCEEDED(hr))
-        mode->Format = d3dformat_from_wined3dformat(mode->Format);
+    {
+        mode->Width = wined3d_mode.width;
+        mode->Height = wined3d_mode.height;
+        mode->RefreshRate = wined3d_mode.refresh_rate;
+        mode->Format = d3dformat_from_wined3dformat(wined3d_mode.format_id);
+    }
 
     return hr;
 }
diff --git a/dlls/ddraw/ddraw.c b/dlls/ddraw/ddraw.c
index 7b07089..05e382d 100644
--- a/dlls/ddraw/ddraw.c
+++ b/dlls/ddraw/ddraw.c
@@ -1069,6 +1069,7 @@ static HRESULT ddraw_set_display_mode(struct ddraw *ddraw, DWORD Width, DWORD He
     mode.height = Height;
     mode.refresh_rate = RefreshRate;
     mode.format_id = format;
+    mode.scanline_ordering = WINED3D_SCANLINE_ORDERING_UNKNOWN;
 
     /* TODO: The possible return values from msdn suggest that
      * the screen mode can't be changed if a surface is locked
diff --git a/dlls/dxgi/output.c b/dlls/dxgi/output.c
index ce78202..ecc9a10 100644
--- a/dlls/dxgi/output.c
+++ b/dlls/dxgi/output.c
@@ -177,7 +177,7 @@ static HRESULT STDMETHODCALLTYPE dxgi_output_GetDisplayModeList(IDXGIOutput *ifa
         desc[i].RefreshRate.Numerator = mode.refresh_rate;
         desc[i].RefreshRate.Denominator = 1;
         desc[i].Format = format;
-        desc[i].ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED; /* FIXME */
+        desc[i].ScanlineOrdering = mode.scanline_ordering;
         desc[i].Scaling = DXGI_MODE_SCALING_UNSPECIFIED; /* FIXME */
     }
     wined3d_decref(wined3d);
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index 92962df..e7c0bd0 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -5259,6 +5259,7 @@ HRESULT CDECL wined3d_device_reset(struct wined3d_device *device,
         mode.height = swapchain->orig_height;
         mode.refresh_rate = 0;
         mode.format_id = swapchain->desc.backbuffer_format;
+        mode.scanline_ordering = WINED3D_SCANLINE_ORDERING_UNKNOWN;
     }
     else
     {
@@ -5266,6 +5267,7 @@ HRESULT CDECL wined3d_device_reset(struct wined3d_device *device,
         mode.height = swapchain_desc->backbuffer_height;
         mode.refresh_rate = swapchain_desc->refresh_rate;
         mode.format_id = swapchain_desc->backbuffer_format;
+        mode.scanline_ordering = WINED3D_SCANLINE_ORDERING_UNKNOWN;
     }
 
     /* Should Width == 800 && Height == 0 set 800x600? */
diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c
index 1d0407d..7cc4387 100644
--- a/dlls/wined3d/directx.c
+++ b/dlls/wined3d/directx.c
@@ -2998,6 +2998,13 @@ HRESULT CDECL wined3d_enum_adapter_modes(const struct wined3d *wined3d, UINT ada
                 mode->format_id = pixelformat_for_depth(DevModeW.dmBitsPerPel);
             else
                 mode->format_id = format_id;
+
+            if (!(DevModeW.dmFields & DM_DISPLAYFLAGS))
+                mode->scanline_ordering = WINED3D_SCANLINE_ORDERING_UNKNOWN;
+            else if (DevModeW.u2.dmDisplayFlags & DM_INTERLACED)
+                mode->scanline_ordering = WINED3D_SCANLINE_ORDERING_INTERLACED;
+            else
+                mode->scanline_ordering = WINED3D_SCANLINE_ORDERING_PROGRESSIVE;
         }
         else
         {
@@ -3005,8 +3012,8 @@ HRESULT CDECL wined3d_enum_adapter_modes(const struct wined3d *wined3d, UINT ada
             return WINED3DERR_INVALIDCALL;
         }
 
-        TRACE("%ux%u@%u %u bpp, %s.\n", mode->width, mode->height, mode->refresh_rate,
-                DevModeW.dmBitsPerPel, debug_d3dformat(mode->format_id));
+        TRACE("%ux%u@%u %u bpp, %s %#x.\n", mode->width, mode->height, mode->refresh_rate,
+                DevModeW.dmBitsPerPel, debug_d3dformat(mode->format_id), mode->scanline_ordering);
     }
     else
     {
@@ -3054,14 +3061,22 @@ HRESULT CDECL wined3d_get_adapter_display_mode(const struct wined3d *wined3d, UI
                     debug_d3dformat(adapter->screen_format));
             mode->format_id = adapter->screen_format;
         }
+
+        if (!(DevModeW.dmFields & DM_DISPLAYFLAGS))
+            mode->scanline_ordering = WINED3D_SCANLINE_ORDERING_UNKNOWN;
+        else if (DevModeW.u2.dmDisplayFlags & DM_INTERLACED)
+            mode->scanline_ordering = WINED3D_SCANLINE_ORDERING_INTERLACED;
+        else
+            mode->scanline_ordering = WINED3D_SCANLINE_ORDERING_PROGRESSIVE;
     }
     else
     {
         FIXME("Adapter not primary display.\n");
     }
 
-    TRACE("Returning %ux%u@%u %s.\n", mode->width, mode->height,
-            mode->refresh_rate, debug_d3dformat(mode->format_id));
+    TRACE("Returning %ux%u@%u %s %#x.\n", mode->width, mode->height,
+            mode->refresh_rate, debug_d3dformat(mode->format_id),
+            mode->scanline_ordering);
     return WINED3D_OK;
 }
 
@@ -3076,8 +3091,9 @@ HRESULT CDECL wined3d_set_adapter_display_mode(struct wined3d *wined3d,
     HRESULT hr;
     LONG ret;
 
-    TRACE("wined3d %p, adapter_idx %u, mode %p (%ux%u@%u %s).\n", wined3d, adapter_idx, mode,
-            mode->width, mode->height, mode->refresh_rate, debug_d3dformat(mode->format_id));
+    TRACE("wined3d %p, adapter_idx %u, mode %p (%ux%u@%u %s %#x).\n", wined3d, adapter_idx, mode,
+            mode->width, mode->height, mode->refresh_rate, debug_d3dformat(mode->format_id),
+            mode->scanline_ordering);
 
     if (adapter_idx >= wined3d->adapter_count)
         return WINED3DERR_INVALIDCALL;
@@ -3096,6 +3112,13 @@ HRESULT CDECL wined3d_set_adapter_display_mode(struct wined3d *wined3d,
     if (mode->refresh_rate)
         devmode.dmFields |= DM_DISPLAYFREQUENCY;
 
+    if (mode->scanline_ordering != WINED3D_SCANLINE_ORDERING_UNKNOWN)
+    {
+        devmode.dmFields |= DM_DISPLAYFLAGS;
+        if (mode->scanline_ordering == WINED3D_SCANLINE_ORDERING_INTERLACED)
+            devmode.u2.dmDisplayFlags |= DM_INTERLACED;
+    }
+
     /* Only change the mode if necessary. */
     if (FAILED(hr = wined3d_get_adapter_display_mode(wined3d, adapter_idx, &current_mode)))
     {
@@ -3105,7 +3128,9 @@ HRESULT CDECL wined3d_set_adapter_display_mode(struct wined3d *wined3d,
             && current_mode.height == mode->height
             && current_mode.format_id == mode->format_id
             && (current_mode.refresh_rate == mode->refresh_rate
-            || !mode->refresh_rate))
+            || !mode->refresh_rate)
+            && (current_mode.scanline_ordering == mode->scanline_ordering
+            || mode->scanline_ordering == WINED3D_SCANLINE_ORDERING_UNKNOWN))
     {
         TRACE("Skipping redundant mode setting call.\n");
         return WINED3D_OK;
diff --git a/dlls/wined3d/swapchain.c b/dlls/wined3d/swapchain.c
index 3f93e83..d4f4e05 100644
--- a/dlls/wined3d/swapchain.c
+++ b/dlls/wined3d/swapchain.c
@@ -80,6 +80,7 @@ static void swapchain_cleanup(struct wined3d_swapchain *swapchain)
         mode.height = swapchain->orig_height;
         mode.refresh_rate = 0;
         mode.format_id = swapchain->orig_fmt;
+        mode.scanline_ordering = WINED3D_SCANLINE_ORDERING_UNKNOWN;
         if (FAILED(hr = wined3d_set_adapter_display_mode(swapchain->device->wined3d,
                 swapchain->device->adapter->ordinal, &mode)))
             ERR("Failed to restore display mode, hr %#x.\n", hr);
@@ -966,6 +967,7 @@ static HRESULT swapchain_init(struct wined3d_swapchain *swapchain, enum wined3d_
         mode.height = desc->backbuffer_height;
         mode.format_id = desc->backbuffer_format;
         mode.refresh_rate = desc->refresh_rate;
+        mode.scanline_ordering = WINED3D_SCANLINE_ORDERING_UNKNOWN;
 
         if (FAILED(hr = wined3d_set_adapter_display_mode(device->wined3d, device->adapter->ordinal, &mode)))
         {
diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h
index 47a519d..e64da92 100644
--- a/include/wine/wined3d.h
+++ b/include/wine/wined3d.h
@@ -767,6 +767,13 @@ enum wined3d_sysval_semantic
     WINED3D_SV_TARGET7 = 7,
 };
 
+enum wined3d_scanline_ordering
+{
+    WINED3D_SCANLINE_ORDERING_UNKNOWN       = 0,
+    WINED3D_SCANLINE_ORDERING_PROGRESSIVE   = 1,
+    WINED3D_SCANLINE_ORDERING_INTERLACED    = 2,
+};
+
 #define WINED3DCOLORWRITEENABLE_RED                             (1 << 0)
 #define WINED3DCOLORWRITEENABLE_GREEN                           (1 << 1)
 #define WINED3DCOLORWRITEENABLE_BLUE                            (1 << 2)
@@ -1488,6 +1495,7 @@ struct wined3d_display_mode
     UINT height;
     UINT refresh_rate;
     enum wined3d_format_id format_id;
+    enum wined3d_scanline_ordering scanline_ordering;
 };
 
 struct wined3d_color
-- 
1.7.8.6




More information about the wine-patches mailing list