[1/3] d3d9: Partial implementation of IDirect3DSwapChain9Ex (try 3)

Michael Müller michael at fds-team.de
Thu Sep 19 14:54:46 CDT 2013


(the first part of this series of patches adding the header fields is
already upstream)

This patch implements the IDirect3DSwapChain9Ex interface as an
extension of IDirect3DSwapChain9 and thus fixes bug 34252 - "Silverlight
accelerated graphics cause a D3D critical section lockup" since
Silverlight does no longer try to create a Direct3D context in an
endless loop. The functions d3d9_swapchain_GetLastPresentCount and
d3d9_swapchain_GetPresentStatistics are just stubs so far.

Changelog:
* Fixed hopefully all style issues and other remarks by Henri Verbeet
and Stefan Dösinger
* Added tests for IDirect3DSwapChain9Ex_GetDisplayModeEx

---
 dlls/d3d9/d3d9_private.h |    7 ++-
 dlls/d3d9/device.c       |   13 ++---
 dlls/d3d9/swapchain.c    |  123
+++++++++++++++++++++++++++++++++++++---------
 3 files changed, 109 insertions(+), 34 deletions(-)

-------------- next part --------------
From 33a2c83322798187866262e333b593006b10cdbd Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael at fds-team.de>
Date: Mon, 9 Sep 2013 15:43:00 +0200
Subject: d3d9: Partial implementation of IDirect3DSwapChain9Ex

---
 dlls/d3d9/d3d9_private.h |    7 ++-
 dlls/d3d9/device.c       |   13 ++---
 dlls/d3d9/swapchain.c    |  123 +++++++++++++++++++++++++++++++++++++---------
 3 files changed, 109 insertions(+), 34 deletions(-)

diff --git a/dlls/d3d9/d3d9_private.h b/dlls/d3d9/d3d9_private.h
index 8ef7f9b..a27de15 100644
--- a/dlls/d3d9/d3d9_private.h
+++ b/dlls/d3d9/d3d9_private.h
@@ -181,7 +181,7 @@ HRESULT volume_init(struct d3d9_volume *volume, struct d3d9_device *device, UINT
 
 struct d3d9_swapchain
 {
-    IDirect3DSwapChain9 IDirect3DSwapChain9_iface;
+    IDirect3DSwapChain9Ex IDirect3DSwapChain9Ex_iface;
     LONG refcount;
     struct wined3d_swapchain *wined3d_swapchain;
     IDirect3DDevice9Ex *parent_device;
@@ -312,4 +312,9 @@ struct d3d9_query
 
 HRESULT query_init(struct d3d9_query *query, struct d3d9_device *device, D3DQUERYTYPE type) DECLSPEC_HIDDEN;
 
+static inline struct d3d9_device *impl_from_IDirect3DDevice9Ex(IDirect3DDevice9Ex *iface)
+{
+    return CONTAINING_RECORD(iface, struct d3d9_device, IDirect3DDevice9Ex_iface);
+}
+
 #endif /* __WINE_D3D9_PRIVATE_H */
diff --git a/dlls/d3d9/device.c b/dlls/d3d9/device.c
index 17664b1..6387def 100644
--- a/dlls/d3d9/device.c
+++ b/dlls/d3d9/device.c
@@ -229,11 +229,6 @@ static void wined3d_swapchain_desc_from_present_parameters(struct wined3d_swapch
     swapchain_desc->auto_restore_display_mode = TRUE;
 }
 
-static inline struct d3d9_device *impl_from_IDirect3DDevice9Ex(IDirect3DDevice9Ex *iface)
-{
-    return CONTAINING_RECORD(iface, struct d3d9_device, IDirect3DDevice9Ex_iface);
-}
-
 static HRESULT WINAPI d3d9_device_QueryInterface(IDirect3DDevice9Ex *iface, REFIID riid, void **out)
 {
     TRACE("iface %p, riid %s, out %p.\n", iface, debugstr_guid(riid), out);
@@ -507,7 +502,7 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH d3d9_device_CreateAdditionalSwapChain(ID
 
     wined3d_swapchain_desc_from_present_parameters(&desc, present_parameters);
     if (SUCCEEDED(hr = d3d9_swapchain_create(device, &desc, &object)))
-        *swapchain = &object->IDirect3DSwapChain9_iface;
+        *swapchain = (IDirect3DSwapChain9 *)&object->IDirect3DSwapChain9Ex_iface;
     present_parameters_from_wined3d_swapchain_desc(present_parameters, &desc);
 
     return hr;
@@ -527,8 +522,8 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH d3d9_device_GetSwapChain(IDirect3DDevice
     if ((wined3d_swapchain = wined3d_device_get_swapchain(device->wined3d_device, swapchain_idx)))
     {
        swapchain_impl = wined3d_swapchain_get_parent(wined3d_swapchain);
-       *swapchain = &swapchain_impl->IDirect3DSwapChain9_iface;
-       IDirect3DSwapChain9_AddRef(*swapchain);
+       *swapchain = (IDirect3DSwapChain9 *)&swapchain_impl->IDirect3DSwapChain9Ex_iface;
+       IDirect3DSwapChain9Ex_AddRef(*swapchain);
        hr = D3D_OK;
     }
     else
@@ -3443,7 +3438,7 @@ static HRESULT CDECL device_parent_create_swapchain(struct wined3d_device_parent
 
     *swapchain = d3d_swapchain->wined3d_swapchain;
     wined3d_swapchain_incref(*swapchain);
-    IDirect3DSwapChain9_Release(&d3d_swapchain->IDirect3DSwapChain9_iface);
+    IDirect3DSwapChain9Ex_Release(&d3d_swapchain->IDirect3DSwapChain9Ex_iface);
 
     return hr;
 }
diff --git a/dlls/d3d9/swapchain.c b/dlls/d3d9/swapchain.c
index 8177336..d44b449 100644
--- a/dlls/d3d9/swapchain.c
+++ b/dlls/d3d9/swapchain.c
@@ -25,19 +25,38 @@
 
 WINE_DEFAULT_DEBUG_CHANNEL(d3d9);
 
-static inline struct d3d9_swapchain *impl_from_IDirect3DSwapChain9(IDirect3DSwapChain9 *iface)
+static inline struct d3d9_swapchain *impl_from_IDirect3DSwapChain9Ex(IDirect3DSwapChain9Ex *iface)
 {
-    return CONTAINING_RECORD(iface, struct d3d9_swapchain, IDirect3DSwapChain9_iface);
+    return CONTAINING_RECORD(iface, struct d3d9_swapchain, IDirect3DSwapChain9Ex_iface);
 }
 
-static HRESULT WINAPI d3d9_swapchain_QueryInterface(IDirect3DSwapChain9 *iface, REFIID riid, void **out)
+static HRESULT WINAPI d3d9_swapchain_QueryInterface(IDirect3DSwapChain9Ex *iface, REFIID riid, void **out)
 {
     TRACE("iface %p, riid %s, out %p.\n", iface, debugstr_guid(riid), out);
 
     if (IsEqualGUID(riid, &IID_IDirect3DSwapChain9)
             || IsEqualGUID(riid, &IID_IUnknown))
     {
-        IDirect3DSwapChain9_AddRef(iface);
+        IDirect3DSwapChain9Ex_AddRef(iface);
+        *out = iface;
+        return S_OK;
+    }
+
+    if (IsEqualGUID(riid, &IID_IDirect3DSwapChain9Ex))
+    {
+        struct d3d9_swapchain *swapchain = impl_from_IDirect3DSwapChain9Ex(iface);
+        struct d3d9_device *device       = impl_from_IDirect3DDevice9Ex(swapchain->parent_device);
+
+        /* Find out if the creating d3d9 interface was created with Direct3DCreate9Ex.
+         * It doesn't matter with which function the device was created. */
+        if (!device->d3d_parent->extended)
+        {
+            WARN("IDirect3D9 instance wasn't created with CreateDirect3D9Ex, returning E_NOINTERFACE.\n");
+            *out = NULL;
+            return E_NOINTERFACE;
+        }
+
+        IDirect3DSwapChain9Ex_AddRef(iface);
         *out = iface;
         return S_OK;
     }
@@ -48,9 +67,9 @@ static HRESULT WINAPI d3d9_swapchain_QueryInterface(IDirect3DSwapChain9 *iface,
     return E_NOINTERFACE;
 }
 
-static ULONG WINAPI d3d9_swapchain_AddRef(IDirect3DSwapChain9 *iface)
+static ULONG WINAPI d3d9_swapchain_AddRef(IDirect3DSwapChain9Ex *iface)
 {
-    struct d3d9_swapchain *swapchain = impl_from_IDirect3DSwapChain9(iface);
+    struct d3d9_swapchain *swapchain = impl_from_IDirect3DSwapChain9Ex(iface);
     ULONG refcount = InterlockedIncrement(&swapchain->refcount);
 
     TRACE("%p increasing refcount to %u.\n", iface, refcount);
@@ -68,9 +87,9 @@ static ULONG WINAPI d3d9_swapchain_AddRef(IDirect3DSwapChain9 *iface)
     return refcount;
 }
 
-static ULONG WINAPI d3d9_swapchain_Release(IDirect3DSwapChain9 *iface)
+static ULONG WINAPI d3d9_swapchain_Release(IDirect3DSwapChain9Ex *iface)
 {
-    struct d3d9_swapchain *swapchain = impl_from_IDirect3DSwapChain9(iface);
+    struct d3d9_swapchain *swapchain = impl_from_IDirect3DSwapChain9Ex(iface);
     ULONG refcount = InterlockedDecrement(&swapchain->refcount);
 
     TRACE("%p decreasing refcount to %u.\n", iface, refcount);
@@ -91,11 +110,11 @@ static ULONG WINAPI d3d9_swapchain_Release(IDirect3DSwapChain9 *iface)
     return refcount;
 }
 
-static HRESULT WINAPI DECLSPEC_HOTPATCH d3d9_swapchain_Present(IDirect3DSwapChain9 *iface,
+static HRESULT WINAPI DECLSPEC_HOTPATCH d3d9_swapchain_Present(IDirect3DSwapChain9Ex *iface,
         const RECT *src_rect, const RECT *dst_rect, HWND dst_window_override,
         const RGNDATA *dirty_region, DWORD flags)
 {
-    struct d3d9_swapchain *swapchain = impl_from_IDirect3DSwapChain9(iface);
+    struct d3d9_swapchain *swapchain = impl_from_IDirect3DSwapChain9Ex(iface);
     HRESULT hr;
 
     TRACE("iface %p, src_rect %s, dst_rect %s, dst_window_override %p, dirty_region %p, flags %#x.\n",
@@ -110,9 +129,9 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH d3d9_swapchain_Present(IDirect3DSwapChai
     return hr;
 }
 
-static HRESULT WINAPI d3d9_swapchain_GetFrontBufferData(IDirect3DSwapChain9 *iface, IDirect3DSurface9 *surface)
+static HRESULT WINAPI d3d9_swapchain_GetFrontBufferData(IDirect3DSwapChain9Ex *iface, IDirect3DSurface9 *surface)
 {
-    struct d3d9_swapchain *swapchain = impl_from_IDirect3DSwapChain9(iface);
+    struct d3d9_swapchain *swapchain = impl_from_IDirect3DSwapChain9Ex(iface);
     struct d3d9_surface *dst = unsafe_impl_from_IDirect3DSurface9(surface);
     HRESULT hr;
 
@@ -125,10 +144,10 @@ static HRESULT WINAPI d3d9_swapchain_GetFrontBufferData(IDirect3DSwapChain9 *ifa
     return hr;
 }
 
-static HRESULT WINAPI d3d9_swapchain_GetBackBuffer(IDirect3DSwapChain9 *iface,
+static HRESULT WINAPI d3d9_swapchain_GetBackBuffer(IDirect3DSwapChain9Ex *iface,
         UINT backbuffer_idx, D3DBACKBUFFER_TYPE backbuffer_type, IDirect3DSurface9 **backbuffer)
 {
-    struct d3d9_swapchain *swapchain = impl_from_IDirect3DSwapChain9(iface);
+    struct d3d9_swapchain *swapchain = impl_from_IDirect3DSwapChain9Ex(iface);
     struct wined3d_surface *wined3d_surface = NULL;
     struct d3d9_surface *surface_impl;
     HRESULT hr = D3D_OK;
@@ -153,9 +172,9 @@ static HRESULT WINAPI d3d9_swapchain_GetBackBuffer(IDirect3DSwapChain9 *iface,
     return hr;
 }
 
-static HRESULT WINAPI d3d9_swapchain_GetRasterStatus(IDirect3DSwapChain9 *iface, D3DRASTER_STATUS *raster_status)
+static HRESULT WINAPI d3d9_swapchain_GetRasterStatus(IDirect3DSwapChain9Ex *iface, D3DRASTER_STATUS *raster_status)
 {
-    struct d3d9_swapchain *swapchain = impl_from_IDirect3DSwapChain9(iface);
+    struct d3d9_swapchain *swapchain = impl_from_IDirect3DSwapChain9Ex(iface);
     HRESULT hr;
 
     TRACE("iface %p, raster_status %p.\n", iface, raster_status);
@@ -168,9 +187,9 @@ static HRESULT WINAPI d3d9_swapchain_GetRasterStatus(IDirect3DSwapChain9 *iface,
     return hr;
 }
 
-static HRESULT WINAPI d3d9_swapchain_GetDisplayMode(IDirect3DSwapChain9 *iface, D3DDISPLAYMODE *mode)
+static HRESULT WINAPI d3d9_swapchain_GetDisplayMode(IDirect3DSwapChain9Ex *iface, D3DDISPLAYMODE *mode)
 {
-    struct d3d9_swapchain *swapchain = impl_from_IDirect3DSwapChain9(iface);
+    struct d3d9_swapchain *swapchain = impl_from_IDirect3DSwapChain9Ex(iface);
     struct wined3d_display_mode wined3d_mode;
     HRESULT hr;
 
@@ -191,9 +210,9 @@ static HRESULT WINAPI d3d9_swapchain_GetDisplayMode(IDirect3DSwapChain9 *iface,
     return hr;
 }
 
-static HRESULT WINAPI d3d9_swapchain_GetDevice(IDirect3DSwapChain9 *iface, IDirect3DDevice9 **device)
+static HRESULT WINAPI d3d9_swapchain_GetDevice(IDirect3DSwapChain9Ex *iface, IDirect3DDevice9 **device)
 {
-    struct d3d9_swapchain *swapchain = impl_from_IDirect3DSwapChain9(iface);
+    struct d3d9_swapchain *swapchain = impl_from_IDirect3DSwapChain9Ex(iface);
 
     TRACE("iface %p, device %p.\n", iface, device);
 
@@ -205,10 +224,10 @@ static HRESULT WINAPI d3d9_swapchain_GetDevice(IDirect3DSwapChain9 *iface, IDire
     return D3D_OK;
 }
 
-static HRESULT WINAPI d3d9_swapchain_GetPresentParameters(IDirect3DSwapChain9 *iface,
+static HRESULT WINAPI d3d9_swapchain_GetPresentParameters(IDirect3DSwapChain9Ex *iface,
         D3DPRESENT_PARAMETERS *parameters)
 {
-    struct d3d9_swapchain *swapchain = impl_from_IDirect3DSwapChain9(iface);
+    struct d3d9_swapchain *swapchain = impl_from_IDirect3DSwapChain9Ex(iface);
     struct wined3d_swapchain_desc desc;
 
     TRACE("iface %p, parameters %p.\n", iface, parameters);
@@ -221,12 +240,64 @@ static HRESULT WINAPI d3d9_swapchain_GetPresentParameters(IDirect3DSwapChain9 *i
     return D3D_OK;
 }
 
+static HRESULT WINAPI d3d9_swapchain_GetLastPresentCount(IDirect3DSwapChain9Ex *iface,
+        UINT *last_present_count)
+{
+    FIXME("iface %p, last_present_count %p, stub!\n", iface, last_present_count);
+
+    if (last_present_count)
+        *last_present_count = 0;
+
+    return D3D_OK;
+}
+
+static HRESULT WINAPI d3d9_swapchain_GetPresentStatistics(IDirect3DSwapChain9Ex *iface,
+        D3DPRESENTSTATS *present_stats)
+{
+    FIXME("iface %p, present_stats %p, stub!\n", iface, present_stats);
+
+    if (present_stats)
+        memset(present_stats, 0, sizeof(*present_stats));
+
+    return D3D_OK;
+}
+
+static HRESULT WINAPI d3d9_swapchain_GetDisplayModeEx(IDirect3DSwapChain9Ex *iface,
+        D3DDISPLAYMODEEX *mode, D3DDISPLAYROTATION *rotation)
+{
+    struct d3d9_swapchain *swapchain = impl_from_IDirect3DSwapChain9Ex(iface);
+    struct wined3d_display_mode wined3d_mode;
+    HRESULT hr;
+
+    TRACE("iface %p, mode %p, rotation %p.\n", iface, mode, rotation);
+
+    if (mode->Size != sizeof(*mode))
+        return D3DERR_INVALIDCALL;
+
+    wined3d_mutex_lock();
+    hr = wined3d_swapchain_get_display_mode(swapchain->wined3d_swapchain, &wined3d_mode,
+            (enum wined3d_display_rotation *)rotation);
+    wined3d_mutex_unlock();
+
+    if (SUCCEEDED(hr))
+    {
+        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);
+        mode->ScanLineOrdering = wined3d_mode.scanline_ordering;
+    }
+
+    return hr;
+}
 
-static const struct IDirect3DSwapChain9Vtbl d3d9_swapchain_vtbl =
+static const struct IDirect3DSwapChain9ExVtbl d3d9_swapchain_vtbl =
 {
+    /* IUnknown */
     d3d9_swapchain_QueryInterface,
     d3d9_swapchain_AddRef,
     d3d9_swapchain_Release,
+    /* IDirect3DSwapChain9 */
     d3d9_swapchain_Present,
     d3d9_swapchain_GetFrontBufferData,
     d3d9_swapchain_GetBackBuffer,
@@ -234,6 +305,10 @@ static const struct IDirect3DSwapChain9Vtbl d3d9_swapchain_vtbl =
     d3d9_swapchain_GetDisplayMode,
     d3d9_swapchain_GetDevice,
     d3d9_swapchain_GetPresentParameters,
+    /* IDirect3DSwapChain9Ex */
+    d3d9_swapchain_GetLastPresentCount,
+    d3d9_swapchain_GetPresentStatistics,
+    d3d9_swapchain_GetDisplayModeEx
 };
 
 static void STDMETHODCALLTYPE d3d9_swapchain_wined3d_object_released(void *parent)
@@ -252,7 +327,7 @@ static HRESULT swapchain_init(struct d3d9_swapchain *swapchain, struct d3d9_devi
     HRESULT hr;
 
     swapchain->refcount = 1;
-    swapchain->IDirect3DSwapChain9_iface.lpVtbl = &d3d9_swapchain_vtbl;
+    swapchain->IDirect3DSwapChain9Ex_iface.lpVtbl = &d3d9_swapchain_vtbl;
 
     wined3d_mutex_lock();
     hr = wined3d_swapchain_create(device->wined3d_device, desc, swapchain,
-- 
1.7.9.5



More information about the wine-patches mailing list