From a1bfd0988f77c41842171a4f24ac8a5b5826de3b Mon Sep 17 00:00:00 2001 From: Henri Verbeet Date: Wed, 27 Jun 2012 19:02:27 +0200 Subject: [PATCH] wined3d: Take scanline ordering into account in the mode setting code. --- 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 48e4d65f1eb..22d3b88512a 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 224a063d458..96113fbc40a 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 1014c277ebf..44f64903dc4 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 ae315e38930..c96d1a65088 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 b70067dd89b..b8439a92e1a 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 7b07089b660..05e382d3abd 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 ce782026022..ecc9a10159b 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 92962dfc3ab..e7c0bd0d12a 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 1d0407d282e..7cc438749a4 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, ¤t_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 3f93e8390a7..d4f4e051d3d 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 47a519d1d4c..e64da926ca5 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 -- 2.11.4.GIT