=?UTF-8?Q?J=C3=B3zef=20Kucia=20?=: dxgi: Implement dxgi_swapchain_GetDevice().

Alexandre Julliard julliard at wine.codeweavers.com
Tue Apr 12 10:20:48 CDT 2016


Module: wine
Branch: master
Commit: 282afc4450e71339ce366b55cdf454e05cc04a2b
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=282afc4450e71339ce366b55cdf454e05cc04a2b

Author: Józef Kucia <jkucia at codeweavers.com>
Date:   Tue Apr 12 12:29:38 2016 +0200

dxgi: Implement dxgi_swapchain_GetDevice().

Signed-off-by: Józef Kucia <jkucia at codeweavers.com>
Signed-off-by: Henri Verbeet <hverbeet at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/d3d11/device.c       |  2 +-
 dlls/dxgi/device.c        | 12 +++++-------
 dlls/dxgi/dxgi_private.h  |  3 ++-
 dlls/dxgi/factory.c       |  2 +-
 dlls/dxgi/swapchain.c     | 41 ++++++++++++++++++++++++++++++++++-------
 dlls/dxgi/tests/device.c  |  2 +-
 include/wine/winedxgi.idl |  1 +
 7 files changed, 45 insertions(+), 18 deletions(-)

diff --git a/dlls/d3d11/device.c b/dlls/d3d11/device.c
index 4f24c48..9144438 100644
--- a/dlls/d3d11/device.c
+++ b/dlls/d3d11/device.c
@@ -5064,7 +5064,7 @@ static HRESULT CDECL device_parent_create_swapchain(struct wined3d_device_parent
         return E_FAIL;
     }
 
-    hr = IWineDXGIDevice_create_swapchain(wine_device, desc, swapchain);
+    hr = IWineDXGIDevice_create_swapchain(wine_device, desc, TRUE, swapchain);
     IWineDXGIDevice_Release(wine_device);
     if (FAILED(hr))
     {
diff --git a/dlls/dxgi/device.c b/dlls/dxgi/device.c
index a10bb01..0c82383 100644
--- a/dlls/dxgi/device.c
+++ b/dlls/dxgi/device.c
@@ -310,31 +310,29 @@ static HRESULT STDMETHODCALLTYPE dxgi_device_create_surface(IWineDXGIDevice *ifa
 }
 
 static HRESULT STDMETHODCALLTYPE dxgi_device_create_swapchain(IWineDXGIDevice *iface,
-        struct wined3d_swapchain_desc *desc, struct wined3d_swapchain **wined3d_swapchain)
+        struct wined3d_swapchain_desc *desc, BOOL implicit, struct wined3d_swapchain **wined3d_swapchain)
 {
-    struct dxgi_device *This = impl_from_IWineDXGIDevice(iface);
+    struct dxgi_device *device = impl_from_IWineDXGIDevice(iface);
     struct dxgi_swapchain *object;
     HRESULT hr;
 
     TRACE("iface %p, desc %p, wined3d_swapchain %p.\n",
             iface, desc, wined3d_swapchain);
 
-    object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
-    if (!object)
+    if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object))))
     {
         ERR("Failed to allocate DXGI swapchain object memory\n");
         return E_OUTOFMEMORY;
     }
 
-    hr = dxgi_swapchain_init(object, This, desc);
-    if (FAILED(hr))
+    if (FAILED(hr = dxgi_swapchain_init(object, device, desc, implicit)))
     {
         WARN("Failed to initialize swapchain, hr %#x.\n", hr);
         HeapFree(GetProcessHeap(), 0, object);
         return hr;
     }
 
-    TRACE("Created IDXGISwapChain %p\n", object);
+    TRACE("Created IDXGISwapChain %p.\n", object);
     *wined3d_swapchain = object->wined3d_swapchain;
 
     return S_OK;
diff --git a/dlls/dxgi/dxgi_private.h b/dlls/dxgi/dxgi_private.h
index 86d8608..fb49b21 100644
--- a/dlls/dxgi/dxgi_private.h
+++ b/dlls/dxgi/dxgi_private.h
@@ -157,10 +157,11 @@ struct dxgi_swapchain
     LONG refcount;
     struct wined3d_private_store private_store;
     struct wined3d_swapchain *wined3d_swapchain;
+    IWineDXGIDevice *device;
 };
 
 HRESULT dxgi_swapchain_init(struct dxgi_swapchain *swapchain, struct dxgi_device *device,
-        struct wined3d_swapchain_desc *desc) DECLSPEC_HIDDEN;
+        struct wined3d_swapchain_desc *desc, BOOL implicit) DECLSPEC_HIDDEN;
 
 /* IDXGISurface */
 struct dxgi_surface
diff --git a/dlls/dxgi/factory.c b/dlls/dxgi/factory.c
index 5956e62..8e16311 100644
--- a/dlls/dxgi/factory.c
+++ b/dlls/dxgi/factory.c
@@ -246,7 +246,7 @@ static HRESULT STDMETHODCALLTYPE dxgi_factory_CreateSwapChain(IDXGIFactory1 *ifa
     wined3d_desc.swap_interval = WINED3DPRESENT_INTERVAL_DEFAULT;
     wined3d_desc.auto_restore_display_mode = TRUE;
 
-    hr = IWineDXGIDevice_create_swapchain(dxgi_device, &wined3d_desc, &wined3d_swapchain);
+    hr = IWineDXGIDevice_create_swapchain(dxgi_device, &wined3d_desc, FALSE, &wined3d_swapchain);
     IWineDXGIDevice_Release(dxgi_device);
     if (FAILED(hr))
     {
diff --git a/dlls/dxgi/swapchain.c b/dlls/dxgi/swapchain.c
index 10a5786..b729970 100644
--- a/dlls/dxgi/swapchain.c
+++ b/dlls/dxgi/swapchain.c
@@ -70,16 +70,19 @@ static ULONG STDMETHODCALLTYPE dxgi_swapchain_AddRef(IDXGISwapChain *iface)
 
 static ULONG STDMETHODCALLTYPE dxgi_swapchain_Release(IDXGISwapChain *iface)
 {
-    struct dxgi_swapchain *This = impl_from_IDXGISwapChain(iface);
-    ULONG refcount = InterlockedDecrement(&This->refcount);
+    struct dxgi_swapchain *swapchain = impl_from_IDXGISwapChain(iface);
+    ULONG refcount = InterlockedDecrement(&swapchain->refcount);
 
-    TRACE("%p decreasing refcount to %u\n", This, refcount);
+    TRACE("%p decreasing refcount to %u.\n", swapchain, refcount);
 
     if (!refcount)
     {
+        IWineDXGIDevice *device = swapchain->device;
         wined3d_mutex_lock();
-        wined3d_swapchain_decref(This->wined3d_swapchain);
+        wined3d_swapchain_decref(swapchain->wined3d_swapchain);
         wined3d_mutex_unlock();
+        if (device)
+            IWineDXGIDevice_Release(device);
     }
 
     return refcount;
@@ -128,9 +131,18 @@ static HRESULT STDMETHODCALLTYPE dxgi_swapchain_GetParent(IDXGISwapChain *iface,
 
 static HRESULT STDMETHODCALLTYPE dxgi_swapchain_GetDevice(IDXGISwapChain *iface, REFIID riid, void **device)
 {
-    FIXME("iface %p, riid %s, device %p stub!\n", iface, debugstr_guid(riid), device);
+    struct dxgi_swapchain *swapchain = impl_from_IDXGISwapChain(iface);
 
-    return E_NOTIMPL;
+    TRACE("iface %p, riid %s, device %p.\n", iface, debugstr_guid(riid), device);
+
+    if (!swapchain->device)
+    {
+        ERR("Implicit swapchain does not store reference to device.\n");
+        *device = NULL;
+        return E_NOINTERFACE;
+    }
+
+    return IWineDXGIDevice_QueryInterface(swapchain->device, riid, device);
 }
 
 /* IDXGISwapChain methods */
@@ -334,7 +346,7 @@ static const struct wined3d_parent_ops dxgi_swapchain_wined3d_parent_ops =
 };
 
 HRESULT dxgi_swapchain_init(struct dxgi_swapchain *swapchain, struct dxgi_device *device,
-        struct wined3d_swapchain_desc *desc)
+        struct wined3d_swapchain_desc *desc, BOOL implicit)
 {
     HRESULT hr;
 
@@ -353,5 +365,20 @@ HRESULT dxgi_swapchain_init(struct dxgi_swapchain *swapchain, struct dxgi_device
     }
     wined3d_mutex_unlock();
 
+    /**
+     * A reference to the implicit swapchain is held by the wined3d device.
+     * In order to avoid circular references we do not keep a reference
+     * to the device in the implicit swapchain.
+     */
+    if (!implicit)
+    {
+        swapchain->device = &device->IWineDXGIDevice_iface;
+        IWineDXGIDevice_AddRef(swapchain->device);
+    }
+    else
+    {
+        swapchain->device = NULL;
+    }
+
     return S_OK;
 }
diff --git a/dlls/dxgi/tests/device.c b/dlls/dxgi/tests/device.c
index 71385ab..837618a 100644
--- a/dlls/dxgi/tests/device.c
+++ b/dlls/dxgi/tests/device.c
@@ -479,7 +479,7 @@ static void test_create_swapchain(void)
     refcount = get_refcount((IUnknown *)factory);
     todo_wine ok(refcount == 4, "Got unexpected refcount %u.\n", refcount);
     refcount = get_refcount((IUnknown *)device);
-    todo_wine ok(refcount == 3, "Got unexpected refcount %u.\n", refcount);
+    ok(refcount == 3, "Got unexpected refcount %u.\n", refcount);
 
     hr = IDXGISwapChain_GetDesc(swapchain, NULL);
     ok(hr == E_INVALIDARG, "GetDesc unexpectedly returned %#x.\n", hr);
diff --git a/include/wine/winedxgi.idl b/include/wine/winedxgi.idl
index d13a2f1..d9f6677 100644
--- a/include/wine/winedxgi.idl
+++ b/include/wine/winedxgi.idl
@@ -36,6 +36,7 @@ interface IWineDXGIDevice : IDXGIDevice1
     );
     HRESULT create_swapchain(
         [in] struct wined3d_swapchain_desc *desc,
+        [in] BOOL implicit,
         [out] struct wined3d_swapchain **wined3d_swapchain
     );
 }




More information about the wine-cvs mailing list