From b85af44374eac736ad91331ee50a3697f8c1b20a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Bernon?= Date: Tue, 26 Jan 2021 12:14:26 +0100 Subject: [PATCH] d3d11: Add initial implementation of SwapDeviceContextState. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: RĂ©mi Bernon Signed-off-by: Henri Verbeet Signed-off-by: Alexandre Julliard --- 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. */