[PATCH v2 2/5] d3d11: Add initial implementation of SwapDeviceContextState.

Rémi Bernon rbernon at codeweavers.com
Tue Jan 26 05:14:26 CST 2021


Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
---

Notes:
    Activating D3D10 interface should actually disable most of the D3D11
    interface methods, and the other way respectively. This is currently
    left implemented, as it's not really required for the purpose of the
    series.

 dlls/d3d11/d3d11_main.c    |   1 +
 dlls/d3d11/d3d11_private.h |   1 +
 dlls/d3d11/device.c        |  31 ++++++++++-
 dlls/d3d11/tests/d3d11.c   | 102 ++++++++++++++++++++++++++++++-------
 4 files changed, 116 insertions(+), 19 deletions(-)

diff --git a/dlls/d3d11/d3d11_main.c b/dlls/d3d11/d3d11_main.c
index dac59d09999..6666876049d 100644
--- a/dlls/d3d11/d3d11_main.c
+++ b/dlls/d3d11/d3d11_main.c
@@ -137,6 +137,7 @@ HRESULT WINAPI D3D11CoreCreateDevice(IDXGIFactory *factory, IDXGIAdapter *adapte
         return E_FAIL;
     }
     d3d_device->d3d11_only = TRUE;
+    d3d_device->emulated_interface = IID_ID3D11Device2;
 
     return S_OK;
 }
diff --git a/dlls/d3d11/d3d11_private.h b/dlls/d3d11/d3d11_private.h
index 77078a07545..fd97269a384 100644
--- a/dlls/d3d11/d3d11_private.h
+++ b/dlls/d3d11/d3d11_private.h
@@ -551,6 +551,7 @@ struct d3d_device
 
     D3D_FEATURE_LEVEL feature_level;
     BOOL d3d11_only;
+    GUID emulated_interface;
 
     struct d3d11_immediate_context immediate_context;
 
diff --git a/dlls/d3d11/device.c b/dlls/d3d11/device.c
index e870399a83e..bec087308e4 100644
--- a/dlls/d3d11/device.c
+++ b/dlls/d3d11/device.c
@@ -29,6 +29,12 @@ static const struct wined3d_parent_ops d3d_null_wined3d_parent_ops =
     d3d_null_wined3d_object_destroyed,
 };
 
+static inline BOOL d3d_device_is_d3d10_active(struct d3d_device *device)
+{
+    return IsEqualGUID(&device->emulated_interface, &IID_ID3D10Device)
+                || IsEqualGUID(&device->emulated_interface, &IID_ID3D10Device1);
+}
+
 /* ID3DDeviceContextState methods */
 
 static inline struct d3d_device_context_state *impl_from_ID3DDeviceContextState(ID3DDeviceContextState *iface)
@@ -2672,7 +2678,29 @@ static void STDMETHODCALLTYPE d3d11_immediate_context_CSGetConstantBuffers1(ID3D
 static void STDMETHODCALLTYPE d3d11_immediate_context_SwapDeviceContextState(ID3D11DeviceContext1 *iface,
         ID3DDeviceContextState *state, ID3DDeviceContextState **prev_state)
 {
-    FIXME("iface %p, state %p, prev_state %p stub!\n", iface, state, prev_state);
+    struct d3d_device_context_state *state_impl;
+    struct d3d_device *device = device_from_immediate_ID3D11DeviceContext1(iface);
+
+    FIXME("iface %p, state %p, prev_state %p semi-stub!\n", iface, state, prev_state);
+
+    wined3d_mutex_lock();
+    if (prev_state)
+    {
+        *prev_state = NULL;
+        if ((state_impl = heap_alloc(sizeof(*state_impl))))
+        {
+            d3d_device_context_state_init(state_impl, device, &device->emulated_interface);
+            *prev_state = &state_impl->ID3DDeviceContextState_iface;
+        }
+    }
+
+    if ((state_impl = impl_from_ID3DDeviceContextState(state)))
+    {
+        device->emulated_interface = state_impl->emulated_interface;
+        if (d3d_device_is_d3d10_active(device))
+            FIXME("D3D10 interface emulation not fully implemented yet!\n");
+    }
+    wined3d_mutex_unlock();
 }
 
 static void STDMETHODCALLTYPE d3d11_immediate_context_ClearView(ID3D11DeviceContext1 *iface, ID3D11View *view,
@@ -6373,6 +6401,7 @@ void d3d_device_init(struct d3d_device *device, void *outer_unknown)
     /* COM aggregation always takes place */
     device->outer_unk = outer_unknown;
     device->d3d11_only = FALSE;
+    device->emulated_interface = GUID_NULL;
 
     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 fde7a11766d..1f6e7f3795c 100644
--- a/dlls/d3d11/tests/d3d11.c
+++ b/dlls/d3d11/tests/d3d11.c
@@ -6704,19 +6704,6 @@ static void test_device_context_state(void)
     check_interface(device, &IID_ID3D11Device, TRUE, FALSE);
     check_interface(device, &IID_ID3D11Device1, TRUE, FALSE);
 
-    refcount = ID3DDeviceContextState_Release(context_state);
-    ok(!refcount, "Got refcount %u, expected 0.\n", refcount);
-
-    feature_level = min(feature_level, D3D_FEATURE_LEVEL_10_1);
-    hr = ID3D11Device1_CreateDeviceContextState(device, 0, &feature_level, 1, D3D11_SDK_VERSION,
-            &IID_ID3D10Device, NULL, &context_state);
-    ok(SUCCEEDED(hr), "Failed to create device context state, hr %#x.\n", hr);
-    refcount = get_refcount(context_state);
-    ok(refcount == 1, "Got refcount %u, expected 1.\n", refcount);
-
-    context_type = ID3D11DeviceContext1_GetType(context);
-    ok(context_type == D3D11_DEVICE_CONTEXT_IMMEDIATE, "Unexpected context type %u.\n", context_type);
-
     cb = create_buffer((ID3D11Device *)device, D3D11_BIND_CONSTANT_BUFFER, sizeof(constant), NULL);
 
     ID3D11DeviceContext1_CSSetConstantBuffers(context, 0, 1, &cb);
@@ -6755,12 +6742,93 @@ static void test_device_context_state(void)
     ok(tmp_cb == cb, "Got buffer %p, expected %p.\n", tmp_cb, cb);
     ID3D11Buffer_Release(tmp_cb);
 
+    previous_context_state = NULL;
+    ID3D11DeviceContext1_SwapDeviceContextState(context, context_state, &previous_context_state);
+    refcount = ID3DDeviceContextState_Release(context_state);
+    ok(!refcount, "Got refcount %u, expected 0.\n", refcount);
+    ok(previous_context_state != NULL, "Failed to get previous context state\n");
+
+    context_type = ID3D11DeviceContext1_GetType(context);
+    ok(context_type == D3D11_DEVICE_CONTEXT_IMMEDIATE, "Unexpected context type %u.\n", context_type);
+
+    ID3D11DeviceContext1_SwapDeviceContextState(context, previous_context_state, &context_state);
+    refcount = ID3DDeviceContextState_Release(context_state);
+    ok(!refcount, "Got refcount %u, expected 0.\n", refcount);
+    refcount = ID3DDeviceContextState_Release(previous_context_state);
+    ok(!refcount, "Got refcount %u, expected 0.\n", refcount);
+
+    /* ID3DDeviceContextState retains the previous state. */
+
+    tmp_sampler = (ID3D11SamplerState *)0xdeadbeef;
+    ID3D11DeviceContext1_VSGetSamplers(context, 0, 1, &tmp_sampler);
+    ok(tmp_sampler == sampler, "Got sampler %p, expected %p.\n", tmp_sampler, sampler);
+    ID3D11SamplerState_Release(tmp_sampler);
+    tmp_cb = (ID3D11Buffer *)0xdeadbeef;
+    ID3D11DeviceContext1_VSGetConstantBuffers(context, 0, 1, &tmp_cb);
+    ok(tmp_cb == cb, "Got buffer %p, expected %p.\n", tmp_cb, cb);
+    ID3D11Buffer_Release(tmp_cb);
+
+    tmp_sampler = (ID3D11SamplerState *)0xdeadbeef;
+    ID3D11DeviceContext1_GSGetSamplers(context, 0, 1, &tmp_sampler);
+    ok(tmp_sampler == sampler, "Got sampler %p, expected %p.\n", tmp_sampler, sampler);
+    ID3D11SamplerState_Release(tmp_sampler);
+    tmp_cb = (ID3D11Buffer *)0xdeadbeef;
+    ID3D11DeviceContext1_GSGetConstantBuffers(context, 0, 1, &tmp_cb);
+    ok(tmp_cb == cb, "Got buffer %p, expected %p.\n", tmp_cb, cb);
+    ID3D11Buffer_Release(tmp_cb);
+
+    tmp_sampler = (ID3D11SamplerState *)0xdeadbeef;
+    ID3D11DeviceContext1_PSGetSamplers(context, 0, 1, &tmp_sampler);
+    ok(tmp_sampler == sampler, "Got sampler %p, expected %p.\n", tmp_sampler, sampler);
+    ID3D11SamplerState_Release(tmp_sampler);
+    tmp_cb = (ID3D11Buffer *)0xdeadbeef;
+    ID3D11DeviceContext1_PSGetConstantBuffers(context, 0, 1, &tmp_cb);
+    ok(tmp_cb == cb, "Got buffer %p, expected %p.\n", tmp_cb, cb);
+    ID3D11Buffer_Release(tmp_cb);
+
+    tmp_sampler = (ID3D11SamplerState *)0xdeadbeef;
+    ID3D11DeviceContext1_HSGetSamplers(context, 0, 1, &tmp_sampler);
+    ok(tmp_sampler == sampler, "Got sampler %p, expected %p.\n", tmp_sampler, sampler);
+    ID3D11SamplerState_Release(tmp_sampler);
+    tmp_cb = (ID3D11Buffer *)0xdeadbeef;
+    ID3D11DeviceContext1_HSGetConstantBuffers(context, 0, 1, &tmp_cb);
+    ok(tmp_cb == cb, "Got buffer %p, expected %p.\n", tmp_cb, cb);
+    ID3D11Buffer_Release(tmp_cb);
+
+    tmp_sampler = (ID3D11SamplerState *)0xdeadbeef;
+    ID3D11DeviceContext1_DSGetSamplers(context, 0, 1, &tmp_sampler);
+    ok(tmp_sampler == sampler, "Got sampler %p, expected %p.\n", tmp_sampler, sampler);
+    ID3D11SamplerState_Release(tmp_sampler);
+    tmp_cb = (ID3D11Buffer *)0xdeadbeef;
+    ID3D11DeviceContext1_DSGetConstantBuffers(context, 0, 1, &tmp_cb);
+    ok(tmp_cb == cb, "Got buffer %p, expected %p.\n", tmp_cb, cb);
+    ID3D11Buffer_Release(tmp_cb);
+
+    tmp_sampler = (ID3D11SamplerState *)0xdeadbeef;
+    ID3D11DeviceContext1_CSGetSamplers(context, 0, 1, &tmp_sampler);
+    ok(tmp_sampler == sampler, "Got sampler %p, expected %p.\n", tmp_sampler, sampler);
+    ID3D11SamplerState_Release(tmp_sampler);
+    tmp_cb = (ID3D11Buffer *)0xdeadbeef;
+    ID3D11DeviceContext1_CSGetConstantBuffers(context, 0, 1, &tmp_cb);
+    ok(tmp_cb == cb, "Got buffer %p, expected %p.\n", tmp_cb, cb);
+    ID3D11Buffer_Release(tmp_cb);
+
+    feature_level = min(feature_level, D3D_FEATURE_LEVEL_10_1);
+    hr = ID3D11Device1_CreateDeviceContextState(device, 0, &feature_level, 1, D3D11_SDK_VERSION,
+            &IID_ID3D10Device, NULL, &context_state);
+    ok(SUCCEEDED(hr), "Failed to create device context state, hr %#x.\n", hr);
+    refcount = get_refcount(context_state);
+    ok(refcount == 1, "Got refcount %u, expected 1.\n", refcount);
+
+    context_type = ID3D11DeviceContext1_GetType(context);
+    ok(context_type == D3D11_DEVICE_CONTEXT_IMMEDIATE, "Unexpected context type %u.\n", context_type);
+
     /* Enable ID3D10Device behavior. */
     previous_context_state = NULL;
     ID3D11DeviceContext1_SwapDeviceContextState(context, context_state, &previous_context_state);
     refcount = ID3DDeviceContextState_Release(context_state);
     ok(!refcount, "Got refcount %u, expected 0.\n", refcount);
-    todo_wine ok(previous_context_state != NULL, "Failed to get previous context state\n");
+    ok(previous_context_state != NULL, "Failed to get previous context state\n");
 
     context_type = ID3D11DeviceContext1_GetType(context);
     ok(context_type == D3D11_DEVICE_CONTEXT_IMMEDIATE, "Unexpected context type %u.\n", context_type);
@@ -6839,11 +6907,9 @@ static void test_device_context_state(void)
 
     context_state = NULL;
     ID3D11DeviceContext1_SwapDeviceContextState(context, previous_context_state, &context_state);
-    if (!context_state) refcount = 0;
-    else refcount = ID3DDeviceContextState_Release(context_state);
+    refcount = ID3DDeviceContextState_Release(context_state);
     ok(!refcount, "Got refcount %u, expected 0.\n", refcount);
-    if (!previous_context_state) refcount = 0;
-    else refcount = ID3DDeviceContextState_Release(previous_context_state);
+    refcount = ID3DDeviceContextState_Release(previous_context_state);
     ok(!refcount, "Got refcount %u, expected 0.\n", refcount);
 
     /* ID3DDeviceContextState retains the previous state. */
-- 
2.30.0




More information about the wine-devel mailing list