Rémi Bernon : d3d11: Stop advertising the ID3D10Device interface on devices created by d3d11.

Alexandre Julliard julliard at winehq.org
Tue Jun 2 16:34:10 CDT 2020


Module: wine
Branch: master
Commit: 2814e5ce0b9d9b1c058a8937692bce6212ac74b4
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=2814e5ce0b9d9b1c058a8937692bce6212ac74b4

Author: Rémi Bernon <rbernon at codeweavers.com>
Date:   Tue Jun  2 04:05:05 2020 +0430

d3d11: Stop advertising the ID3D10Device interface on devices created by d3d11.

The UPlay overlay tries to detect the device D3D version by querying
this interface first. On d3d11 games, and as we are incorrectly
advertising ID3D10Device, it decides to use d3d10 hooks and crashes the
game after ~10 minutes.

This is happening with "Splinter Cell: Blacklist" for instance.

Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
Signed-off-by: Henri Verbeet <hverbeet at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/d3d11/d3d11_main.c    |  8 ++++++++
 dlls/d3d11/d3d11_private.h |  6 ++++++
 dlls/d3d11/device.c        |  6 ++++--
 dlls/d3d11/tests/d3d11.c   | 16 ++++++++--------
 4 files changed, 26 insertions(+), 10 deletions(-)

diff --git a/dlls/d3d11/d3d11_main.c b/dlls/d3d11/d3d11_main.c
index a5854a93cc..dac59d0999 100644
--- a/dlls/d3d11/d3d11_main.c
+++ b/dlls/d3d11/d3d11_main.c
@@ -107,6 +107,7 @@ HRESULT WINAPI D3D11CoreRegisterLayers(void)
 HRESULT WINAPI D3D11CoreCreateDevice(IDXGIFactory *factory, IDXGIAdapter *adapter, UINT flags,
         const D3D_FEATURE_LEVEL *feature_levels, UINT levels, ID3D11Device **device)
 {
+    struct d3d_device *d3d_device;
     IUnknown *dxgi_device;
     HMODULE d3d11;
     HRESULT hr;
@@ -130,6 +131,13 @@ HRESULT WINAPI D3D11CoreCreateDevice(IDXGIFactory *factory, IDXGIAdapter *adapte
         return E_FAIL;
     }
 
+    if (!(d3d_device = impl_from_ID3D11Device(*device)))
+    {
+        ERR("Failed to retrieve device impl, returning E_FAIL.\n");
+        return E_FAIL;
+    }
+    d3d_device->d3d11_only = TRUE;
+
     return S_OK;
 }
 
diff --git a/dlls/d3d11/d3d11_private.h b/dlls/d3d11/d3d11_private.h
index 48c76959fa..cb2b9c3aed 100644
--- a/dlls/d3d11/d3d11_private.h
+++ b/dlls/d3d11/d3d11_private.h
@@ -537,6 +537,7 @@ struct d3d_device
     LONG refcount;
 
     D3D_FEATURE_LEVEL feature_level;
+    BOOL d3d11_only;
 
     struct d3d11_immediate_context immediate_context;
 
@@ -552,6 +553,11 @@ struct d3d_device
     UINT stencil_ref;
 };
 
+static inline struct d3d_device *impl_from_ID3D11Device(ID3D11Device *iface)
+{
+    return CONTAINING_RECORD((ID3D11Device2 *)iface, struct d3d_device, ID3D11Device2_iface);
+}
+
 static inline struct d3d_device *impl_from_ID3D11Device2(ID3D11Device2 *iface)
 {
     return CONTAINING_RECORD(iface, struct d3d_device, ID3D11Device2_iface);
diff --git a/dlls/d3d11/device.c b/dlls/d3d11/device.c
index aaeb98a205..edbba57a5d 100644
--- a/dlls/d3d11/device.c
+++ b/dlls/d3d11/device.c
@@ -3887,8 +3887,9 @@ static HRESULT STDMETHODCALLTYPE d3d_device_inner_QueryInterface(IUnknown *iface
     {
         *out = &device->ID3D11Device2_iface;
     }
-    else if (IsEqualGUID(riid, &IID_ID3D10Device1)
-            || IsEqualGUID(riid, &IID_ID3D10Device))
+    else if (!device->d3d11_only
+            && (IsEqualGUID(riid, &IID_ID3D10Device1)
+            || IsEqualGUID(riid, &IID_ID3D10Device)))
     {
         *out = &device->ID3D10Device1_iface;
     }
@@ -6241,6 +6242,7 @@ void d3d_device_init(struct d3d_device *device, void *outer_unknown)
     device->refcount = 1;
     /* COM aggregation always takes place */
     device->outer_unk = outer_unknown;
+    device->d3d11_only = FALSE;
 
     d3d11_immediate_context_init(&device->immediate_context, device);
     ID3D11DeviceContext1_Release(&device->immediate_context.ID3D11DeviceContext1_iface);
diff --git a/dlls/d3d11/tests/d3d11.c b/dlls/d3d11/tests/d3d11.c
index 20acc0223e..e107d522b2 100644
--- a/dlls/d3d11/tests/d3d11.c
+++ b/dlls/d3d11/tests/d3d11.c
@@ -2110,8 +2110,8 @@ static void test_device_interfaces(const D3D_FEATURE_LEVEL feature_level)
     check_interface(device, &IID_IDXGIDevice, TRUE, FALSE);
     check_interface(device, &IID_IDXGIDevice1, TRUE, FALSE);
     check_interface(device, &IID_ID3D10Multithread, TRUE, TRUE); /* Not available on all Windows versions. */
-    todo_wine check_interface(device, &IID_ID3D10Device, FALSE, FALSE);
-    todo_wine check_interface(device, &IID_ID3D10Device1, FALSE, FALSE);
+    check_interface(device, &IID_ID3D10Device, FALSE, FALSE);
+    check_interface(device, &IID_ID3D10Device1, FALSE, FALSE);
     check_interface(device, &IID_ID3D11InfoQueue, enable_debug_layer, FALSE);
 
     hr = ID3D11Device_QueryInterface(device, &IID_IDXGIDevice, (void **)&dxgi_device);
@@ -2516,7 +2516,7 @@ static void test_texture1d_interfaces(void)
 
         d3d10_device = (ID3D10Device *)0xdeadbeef;
         ID3D10Texture1D_GetDevice(d3d10_texture, &d3d10_device);
-        todo_wine ok(!d3d10_device, "Test %u: Got unexpected device pointer %p, expected NULL.\n", i, d3d10_device);
+        ok(!d3d10_device, "Test %u: Got unexpected device pointer %p, expected NULL.\n", i, d3d10_device);
         if (d3d10_device) ID3D10Device_Release(d3d10_device);
 
         ID3D10Texture1D_Release(d3d10_texture);
@@ -2913,7 +2913,7 @@ static void test_texture2d_interfaces(void)
 
         d3d10_device = (ID3D10Device *)0xdeadbeef;
         ID3D10Texture2D_GetDevice(d3d10_texture, &d3d10_device);
-        todo_wine ok(!d3d10_device, "Test %u: Got unexpected device pointer %p, expected NULL.\n", i, d3d10_device);
+        ok(!d3d10_device, "Test %u: Got unexpected device pointer %p, expected NULL.\n", i, d3d10_device);
         if (d3d10_device) ID3D10Device_Release(d3d10_device);
 
         ID3D10Texture2D_Release(d3d10_texture);
@@ -3172,7 +3172,7 @@ static void test_texture3d_interfaces(void)
 
         d3d10_device = (ID3D10Device *)0xdeadbeef;
         ID3D10Texture3D_GetDevice(d3d10_texture, &d3d10_device);
-        todo_wine ok(!d3d10_device, "Test %u: Got unexpected device pointer %p, expected NULL.\n", i, d3d10_device);
+        ok(!d3d10_device, "Test %u: Got unexpected device pointer %p, expected NULL.\n", i, d3d10_device);
         if (d3d10_device) ID3D10Device_Release(d3d10_device);
 
         ID3D10Texture3D_Release(d3d10_texture);
@@ -3461,7 +3461,7 @@ static void test_create_buffer(void)
 
         d3d10_device = (ID3D10Device *)0xdeadbeef;
         ID3D10Buffer_GetDevice(d3d10_buffer, &d3d10_device);
-        todo_wine ok(!d3d10_device, "Test %u: Got unexpected device pointer %p, expected NULL.\n", i, d3d10_device);
+        ok(!d3d10_device, "Test %u: Got unexpected device pointer %p, expected NULL.\n", i, d3d10_device);
         if (d3d10_device) ID3D10Device_Release(d3d10_device);
 
         ID3D10Buffer_Release(d3d10_buffer);
@@ -6621,8 +6621,8 @@ static void test_device_context_state(void)
         return;
     }
 
-    todo_wine check_interface(device, &IID_ID3D10Device, FALSE, FALSE);
-    todo_wine check_interface(device, &IID_ID3D10Device1, FALSE, FALSE);
+    check_interface(device, &IID_ID3D10Device, FALSE, FALSE);
+    check_interface(device, &IID_ID3D10Device1, FALSE, FALSE);
 
     feature_level = ID3D11Device1_GetFeatureLevel(device);
     ID3D11Device1_GetImmediateContext1(device, &context);




More information about the wine-cvs mailing list