Signed-off-by: Rémi Bernon rbernon@codeweavers.com ---
As suggested, this is the beginning of a series implementating D3D11 state capture and restore, to fix the D2D1 regression [1] by using D3D11 interfaces in D2D1 instead of D3D10.
[1] https://bugs.winehq.org/show_bug.cgi?id=49395
dlls/d3d11/d3d11_private.h | 12 +++ dlls/d3d11/device.c | 155 ++++++++++++++++++++++++++++++++++++- dlls/d3d11/tests/d3d11.c | 74 +++++++++++++----- 3 files changed, 219 insertions(+), 22 deletions(-)
diff --git a/dlls/d3d11/d3d11_private.h b/dlls/d3d11/d3d11_private.h index 3248285fcda..94a0fd8ce74 100644 --- a/dlls/d3d11/d3d11_private.h +++ b/dlls/d3d11/d3d11_private.h @@ -516,6 +516,18 @@ struct d3d_query *unsafe_impl_from_ID3D11Query(ID3D11Query *iface) DECLSPEC_HIDD struct d3d_query *unsafe_impl_from_ID3D10Query(ID3D10Query *iface) DECLSPEC_HIDDEN; struct d3d_query *unsafe_impl_from_ID3D11Asynchronous(ID3D11Asynchronous *iface) DECLSPEC_HIDDEN;
+/* ID3DDeviceContextState */ +struct d3d_device_context_state +{ + ID3DDeviceContextState ID3DDeviceContextState_iface; + LONG refcount; + + struct wined3d_private_store private_store; + + ID3D11Device2 *device; + GUID emulated_interface; +}; + /* ID3D11DeviceContext - immediate context */ struct d3d11_immediate_context { diff --git a/dlls/d3d11/device.c b/dlls/d3d11/device.c index 50e8cd58fe2..2435c34dbff 100644 --- a/dlls/d3d11/device.c +++ b/dlls/d3d11/device.c @@ -29,6 +29,140 @@ static const struct wined3d_parent_ops d3d_null_wined3d_parent_ops = d3d_null_wined3d_object_destroyed, };
+/* ID3DDeviceContextState methods */ + +static inline struct d3d_device_context_state *impl_from_ID3DDeviceContextState(ID3DDeviceContextState *iface) +{ + return CONTAINING_RECORD(iface, struct d3d_device_context_state, ID3DDeviceContextState_iface); +} + +static inline struct d3d_device *device_from_ID3DDeviceContextState(ID3DDeviceContextState *iface) +{ + struct d3d_device_context_state *state = impl_from_ID3DDeviceContextState(iface); + return impl_from_ID3D11Device2(state->device); +} + +static HRESULT STDMETHODCALLTYPE d3d_device_context_state_QueryInterface(ID3DDeviceContextState *iface, + REFIID iid, void **out) +{ + struct d3d_device_context_state *state = impl_from_ID3DDeviceContextState(iface); + + TRACE("iface %p, iid %s, out %p.\n", iface, debugstr_guid(iid), out); + + if (IsEqualGUID(iid, &IID_ID3DDeviceContextState) + || IsEqualGUID(iid, &IID_ID3D11DeviceChild) + || IsEqualGUID(iid, &IID_IUnknown)) + { + *out = &state->ID3DDeviceContextState_iface; + } + else + { + WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid)); + *out = NULL; + return E_NOINTERFACE; + } + + ID3DDeviceContextState_AddRef(iface); + return S_OK; +} + +static ULONG STDMETHODCALLTYPE d3d_device_context_state_AddRef(ID3DDeviceContextState *iface) +{ + struct d3d_device_context_state *state = impl_from_ID3DDeviceContextState(iface); + struct d3d_device *device = device_from_ID3DDeviceContextState(iface); + ULONG refcount = InterlockedIncrement(&state->refcount); + + TRACE("%p increasing refcount to %u.\n", state, refcount); + + if (refcount == 1) + { + ID3D11Device2_AddRef(&device->ID3D11Device2_iface); + } + + return refcount; +} + +static ULONG STDMETHODCALLTYPE d3d_device_context_state_Release(ID3DDeviceContextState *iface) +{ + struct d3d_device_context_state *state = impl_from_ID3DDeviceContextState(iface); + struct d3d_device *device = device_from_ID3DDeviceContextState(iface); + ULONG refcount = InterlockedDecrement(&state->refcount); + + TRACE("%p decreasing refcount to %u.\n", state, refcount); + + if (!refcount) + { + wined3d_private_store_cleanup(&state->private_store); + ID3D11Device2_Release(&device->ID3D11Device2_iface); + } + + return refcount; +} + +static void STDMETHODCALLTYPE d3d_device_context_state_GetDevice(ID3DDeviceContextState *iface, ID3D11Device **device) +{ + struct d3d_device *device_object = device_from_ID3DDeviceContextState(iface); + + TRACE("iface %p, device %p.\n", iface, device); + + *device = (ID3D11Device *)&device_object->ID3D11Device2_iface; + ID3D11Device_AddRef(*device); +} + +static HRESULT STDMETHODCALLTYPE d3d_device_context_state_GetPrivateData(ID3DDeviceContextState *iface, REFGUID guid, + UINT *data_size, void *data) +{ + struct d3d_device_context_state *state = impl_from_ID3DDeviceContextState(iface); + + TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface, debugstr_guid(guid), data_size, data); + + return d3d_get_private_data(&state->private_store, guid, data_size, data); +} + +static HRESULT STDMETHODCALLTYPE d3d_device_context_state_SetPrivateData(ID3DDeviceContextState *iface, REFGUID guid, + UINT data_size, const void *data) +{ + struct d3d_device_context_state *state = impl_from_ID3DDeviceContextState(iface); + + TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface, debugstr_guid(guid), data_size, data); + + return d3d_set_private_data(&state->private_store, guid, data_size, data); +} + +static HRESULT STDMETHODCALLTYPE d3d_device_context_state_SetPrivateDataInterface(ID3DDeviceContextState *iface, + REFGUID guid, const IUnknown *data) +{ + struct d3d_device_context_state *state = impl_from_ID3DDeviceContextState(iface); + + TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data); + + return d3d_set_private_data_interface(&state->private_store, guid, data); +} + +static const struct ID3DDeviceContextStateVtbl d3d_device_context_state_vtbl = +{ + /* IUnknown methods */ + d3d_device_context_state_QueryInterface, + d3d_device_context_state_AddRef, + d3d_device_context_state_Release, + /* ID3D11DeviceChild methods */ + d3d_device_context_state_GetDevice, + d3d_device_context_state_GetPrivateData, + d3d_device_context_state_SetPrivateData, + d3d_device_context_state_SetPrivateDataInterface, +}; + +static void d3d_device_context_state_init(struct d3d_device_context_state *state, struct d3d_device *device, + REFIID emulated_interface) +{ + state->ID3DDeviceContextState_iface.lpVtbl = &d3d_device_context_state_vtbl; + state->refcount = 1; + state->emulated_interface = *emulated_interface; + ID3D11Device2_AddRef(state->device = &device->ID3D11Device2_iface); + + wined3d_private_store_init(&state->private_store); +} + /* ID3D11DeviceContext - immediate context methods */
static inline struct d3d11_immediate_context *impl_from_ID3D11DeviceContext1(ID3D11DeviceContext1 *iface) @@ -3738,11 +3872,28 @@ static HRESULT STDMETHODCALLTYPE d3d11_device_CreateDeviceContextState(ID3D11Dev const D3D_FEATURE_LEVEL *feature_levels, UINT feature_levels_count, UINT sdk_version, REFIID emulated_interface, D3D_FEATURE_LEVEL *chosen_feature_level, ID3DDeviceContextState **state) { + struct d3d_device *device = impl_from_ID3D11Device2(iface); + struct d3d_device_context_state *state_impl; + FIXME("iface %p, flags %#x, feature_levels %p, feature_level_count %u, sdk_version %u, " - "emulated_interface %s, chosen_feature_level %p, state %p stub!\n", iface, flags, feature_levels, + "emulated_interface %s, chosen_feature_level %p, state %p semi-stub!\n", iface, flags, feature_levels, feature_levels_count, sdk_version, debugstr_guid(emulated_interface), chosen_feature_level, state);
- return E_NOTIMPL; + if (chosen_feature_level) + FIXME("Device context state feature level not implemented yet.\n"); + + if (state) + { + *state = NULL; + if (!(state_impl = heap_alloc(sizeof(*state_impl)))) + return E_OUTOFMEMORY; + d3d_device_context_state_init(state_impl, device, emulated_interface); + *state = &state_impl->ID3DDeviceContextState_iface; + } + + device->d3d11_only = FALSE; + if (chosen_feature_level) *chosen_feature_level = ID3D11Device2_GetFeatureLevel(iface); + return state ? S_OK : S_FALSE; }
static HRESULT STDMETHODCALLTYPE d3d11_device_OpenSharedResource1(ID3D11Device2 *iface, HANDLE handle, diff --git a/dlls/d3d11/tests/d3d11.c b/dlls/d3d11/tests/d3d11.c index 9fc09a5ec83..fde7a11766d 100644 --- a/dlls/d3d11/tests/d3d11.c +++ b/dlls/d3d11/tests/d3d11.c @@ -6683,10 +6683,9 @@ static void test_device_context_state(void) ok(tmp_sampler == sampler, "Got sampler %p, expected %p.\n", tmp_sampler, sampler); ID3D11SamplerState_Release(tmp_sampler);
- feature_level = min(feature_level, D3D_FEATURE_LEVEL_10_1); + feature_level = min(feature_level, D3D_FEATURE_LEVEL_11_1); hr = ID3D11Device1_CreateDeviceContextState(device, 0, &feature_level, 1, D3D11_SDK_VERSION, - &IID_ID3D10Device, NULL, &context_state); -todo_wine + &IID_ID3D11Device1, NULL, &context_state); ok(SUCCEEDED(hr), "Failed to create device context state, hr %#x.\n", hr); if (FAILED(hr)) { @@ -6700,6 +6699,24 @@ todo_wine context_type = ID3D11DeviceContext1_GetType(context); ok(context_type == D3D11_DEVICE_CONTEXT_IMMEDIATE, "Unexpected context type %u.\n", context_type);
+ check_interface(device, &IID_ID3D10Device, TRUE, FALSE); + check_interface(device, &IID_ID3D10Device1, TRUE, FALSE); + 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); @@ -6743,73 +6760,90 @@ todo_wine 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"); + + context_type = ID3D11DeviceContext1_GetType(context); + ok(context_type == D3D11_DEVICE_CONTEXT_IMMEDIATE, "Unexpected context type %u.\n", context_type);
ID3D11DeviceContext1_PSSetSamplers(context, 0, 1, &sampler); tmp_sampler = (ID3D11SamplerState *)0xdeadbeef; ID3D11DeviceContext1_PSGetSamplers(context, 0, 1, &tmp_sampler); - ok(tmp_sampler == (ID3D11SamplerState *)0xdeadbeef, "Got unexpected sampler %p.\n", tmp_sampler); + todo_wine ok(tmp_sampler == (ID3D11SamplerState *)0xdeadbeef, "Got unexpected sampler %p.\n", tmp_sampler); + if (tmp_sampler && tmp_sampler != (ID3D11SamplerState *)0xdeadbeef) + ID3D11SamplerState_Release(tmp_sampler); if (!enable_debug_layer) ID3D11DeviceContext1_PSSetSamplers(context, 0, 1, &tmp_sampler);
ID3D11DeviceContext1_CSSetSamplers(context, 0, 1, &sampler); tmp_sampler = (ID3D11SamplerState *)0xdeadbeef; ID3D11DeviceContext1_CSGetSamplers(context, 0, 1, &tmp_sampler); - ok(!tmp_sampler, "Got unexpected sampler %p.\n", tmp_sampler); + todo_wine ok(!tmp_sampler, "Got unexpected sampler %p.\n", tmp_sampler); + if (tmp_sampler) ID3D11SamplerState_Release(tmp_sampler);
ID3D11DeviceContext1_DSSetSamplers(context, 0, 1, &sampler); tmp_sampler = (ID3D11SamplerState *)0xdeadbeef; ID3D11DeviceContext1_DSGetSamplers(context, 0, 1, &tmp_sampler); - ok(!tmp_sampler, "Got unexpected sampler %p.\n", tmp_sampler); + todo_wine ok(!tmp_sampler, "Got unexpected sampler %p.\n", tmp_sampler); + if (tmp_sampler) ID3D11SamplerState_Release(tmp_sampler);
ID3D11DeviceContext1_GSSetSamplers(context, 0, 1, &sampler); tmp_sampler = (ID3D11SamplerState *)0xdeadbeef; ID3D11DeviceContext1_GSGetSamplers(context, 0, 1, &tmp_sampler); - ok(!tmp_sampler, "Got unexpected sampler %p.\n", tmp_sampler); + todo_wine ok(!tmp_sampler, "Got unexpected sampler %p.\n", tmp_sampler); + if (tmp_sampler) ID3D11SamplerState_Release(tmp_sampler);
ID3D11DeviceContext1_HSSetSamplers(context, 0, 1, &sampler); tmp_sampler = (ID3D11SamplerState *)0xdeadbeef; ID3D11DeviceContext1_HSGetSamplers(context, 0, 1, &tmp_sampler); - ok(!tmp_sampler, "Got unexpected sampler %p.\n", tmp_sampler); + todo_wine ok(!tmp_sampler, "Got unexpected sampler %p.\n", tmp_sampler); + if (tmp_sampler) ID3D11SamplerState_Release(tmp_sampler);
ID3D11DeviceContext1_VSSetSamplers(context, 0, 1, &sampler); tmp_sampler = (ID3D11SamplerState *)0xdeadbeef; ID3D11DeviceContext1_VSGetSamplers(context, 0, 1, &tmp_sampler); - ok(!tmp_sampler, "Got unexpected sampler %p.\n", tmp_sampler); - - context_type = ID3D11DeviceContext1_GetType(context); - ok(context_type == D3D11_DEVICE_CONTEXT_IMMEDIATE, "Unexpected context type %u.\n", context_type); + todo_wine ok(!tmp_sampler, "Got unexpected sampler %p.\n", tmp_sampler); + if (tmp_sampler) ID3D11SamplerState_Release(tmp_sampler);
tmp_cb = (ID3D11Buffer *)0xdeadbeef; ID3D11DeviceContext1_CSGetConstantBuffers(context, 0, 1, &tmp_cb); - ok(!tmp_cb, "Got unexpected buffer %p.\n", tmp_cb); + todo_wine ok(!tmp_cb, "Got unexpected buffer %p.\n", tmp_cb); + if (tmp_cb) ID3D11Buffer_Release(tmp_cb);
tmp_cb = (ID3D11Buffer *)0xdeadbeef; ID3D11DeviceContext1_PSGetConstantBuffers(context, 0, 1, &tmp_cb); - ok(!tmp_cb, "Got unexpected buffer %p.\n", tmp_cb); + todo_wine ok(!tmp_cb, "Got unexpected buffer %p.\n", tmp_cb); + if (tmp_cb) ID3D11Buffer_Release(tmp_cb);
tmp_cb = (ID3D11Buffer *)0xdeadbeef; ID3D11DeviceContext1_VSGetConstantBuffers(context, 0, 1, &tmp_cb); - ok(!tmp_cb, "Got unexpected buffer %p.\n", tmp_cb); + todo_wine ok(!tmp_cb, "Got unexpected buffer %p.\n", tmp_cb); + if (tmp_cb) ID3D11Buffer_Release(tmp_cb);
tmp_cb = (ID3D11Buffer *)0xdeadbeef; ID3D11DeviceContext1_DSGetConstantBuffers(context, 0, 1, &tmp_cb); - ok(!tmp_cb, "Got unexpected buffer %p.\n", tmp_cb); + todo_wine ok(!tmp_cb, "Got unexpected buffer %p.\n", tmp_cb); + if (tmp_cb) ID3D11Buffer_Release(tmp_cb);
tmp_cb = (ID3D11Buffer *)0xdeadbeef; ID3D11DeviceContext1_GSGetConstantBuffers(context, 0, 1, &tmp_cb); - ok(!tmp_cb, "Got unexpected buffer %p.\n", tmp_cb); + todo_wine ok(!tmp_cb, "Got unexpected buffer %p.\n", tmp_cb); + if (tmp_cb) ID3D11Buffer_Release(tmp_cb);
tmp_cb = (ID3D11Buffer *)0xdeadbeef; ID3D11DeviceContext1_HSGetConstantBuffers(context, 0, 1, &tmp_cb); - ok(!tmp_cb, "Got unexpected buffer %p.\n", tmp_cb); + todo_wine ok(!tmp_cb, "Got unexpected buffer %p.\n", tmp_cb); + if (tmp_cb) ID3D11Buffer_Release(tmp_cb);
check_interface(device, &IID_ID3D10Device, TRUE, FALSE); check_interface(device, &IID_ID3D10Device1, TRUE, FALSE);
+ context_state = NULL; ID3D11DeviceContext1_SwapDeviceContextState(context, previous_context_state, &context_state); - refcount = ID3DDeviceContextState_Release(context_state); + if (!context_state) refcount = 0; + else refcount = ID3DDeviceContextState_Release(context_state); ok(!refcount, "Got refcount %u, expected 0.\n", refcount); - refcount = ID3DDeviceContextState_Release(previous_context_state); + if (!previous_context_state) refcount = 0; + else refcount = ID3DDeviceContextState_Release(previous_context_state); ok(!refcount, "Got refcount %u, expected 0.\n", refcount);
/* ID3DDeviceContextState retains the previous state. */
Signed-off-by: Rémi Bernon rbernon@codeweavers.com ---
Activating D3D10 interface should actually disable most of the D3D11 interface methods, and the other way respectively. This is currently left unimplemented, 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 94a0fd8ce74..2effe3a8242 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 2435c34dbff..60bacd5c1eb 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) @@ -2685,7 +2691,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, @@ -6386,6 +6414,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. */
Signed-off-by: Rémi Bernon rbernon@codeweavers.com ---
Some test checks are removed but actually moved to keep VS state checks together.
dlls/d3d11/d3d11_private.h | 7 +++ dlls/d3d11/device.c | 48 ++++++++++++++++ dlls/d3d11/tests/d3d11.c | 114 ++++++++++++++++++++++++++++++------- 3 files changed, 150 insertions(+), 19 deletions(-)
diff --git a/dlls/d3d11/d3d11_private.h b/dlls/d3d11/d3d11_private.h index 2effe3a8242..a5a9f227eeb 100644 --- a/dlls/d3d11/d3d11_private.h +++ b/dlls/d3d11/d3d11_private.h @@ -523,6 +523,13 @@ struct d3d_device_context_state LONG refcount;
struct wined3d_private_store private_store; + struct + { + ID3D11VertexShader *shader; + ID3D11SamplerState *samplers[D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT]; + ID3D11ShaderResourceView *srvs[D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT]; + ID3D11Buffer *cbs[D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT]; + } vs;
ID3D11Device2 *device; GUID emulated_interface; diff --git a/dlls/d3d11/device.c b/dlls/d3d11/device.c index 60bacd5c1eb..1461a41a06b 100644 --- a/dlls/d3d11/device.c +++ b/dlls/d3d11/device.c @@ -93,11 +93,26 @@ static ULONG STDMETHODCALLTYPE d3d_device_context_state_Release(ID3DDeviceContex struct d3d_device_context_state *state = impl_from_ID3DDeviceContextState(iface); struct d3d_device *device = device_from_ID3DDeviceContextState(iface); ULONG refcount = InterlockedDecrement(&state->refcount); + unsigned int i;
TRACE("%p decreasing refcount to %u.\n", state, refcount);
if (!refcount) { + if (state->vs.shader) ID3D11VertexShader_Release(state->vs.shader); + for (i = 0; i < D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT; ++i) + { + if (state->vs.samplers[i]) ID3D11SamplerState_Release(state->vs.samplers[i]); + } + for (i = 0; i < D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT; ++i) + { + if (state->vs.srvs[i]) ID3D11ShaderResourceView_Release(state->vs.srvs[i]); + } + for (i = 0; i < D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT; ++i) + { + if (state->vs.cbs[i]) ID3D11Buffer_Release(state->vs.cbs[i]); + } + wined3d_private_store_cleanup(&state->private_store); ID3D11Device2_Release(&device->ID3D11Device2_iface); } @@ -167,6 +182,7 @@ static void d3d_device_context_state_init(struct d3d_device_context_state *state ID3D11Device2_AddRef(state->device = &device->ID3D11Device2_iface);
wined3d_private_store_init(&state->private_store); + memset(&state->vs, 0, sizeof(state->vs)); }
/* ID3D11DeviceContext - immediate context methods */ @@ -2688,6 +2704,36 @@ static void STDMETHODCALLTYPE d3d11_immediate_context_CSGetConstantBuffers1(ID3D iface, start_slot, buffer_count, buffers, first_constant, num_constants); }
+static void d3d11_immediate_context_capture_state(ID3D11DeviceContext1 *iface, struct d3d_device_context_state *state) +{ + wined3d_mutex_lock(); + + d3d11_immediate_context_VSGetShader(iface, &state->vs.shader, NULL, 0); + d3d11_immediate_context_VSGetSamplers(iface, 0, + D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT, state->vs.samplers); + d3d11_immediate_context_VSGetShaderResources(iface, 0, + D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT, state->vs.srvs); + d3d11_immediate_context_VSGetConstantBuffers(iface, 0, + D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT, state->vs.cbs); + + wined3d_mutex_unlock(); +} + +static void d3d11_immediate_context_restore_state(ID3D11DeviceContext1 *iface, struct d3d_device_context_state *state) +{ + wined3d_mutex_lock(); + + d3d11_immediate_context_VSSetShader(iface, state->vs.shader, NULL, 0); + d3d11_immediate_context_VSSetSamplers(iface, 0, + D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT, state->vs.samplers); + d3d11_immediate_context_VSSetShaderResources(iface, 0, + D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT, state->vs.srvs); + d3d11_immediate_context_VSSetConstantBuffers(iface, 0, + D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT, state->vs.cbs); + + wined3d_mutex_unlock(); +} + static void STDMETHODCALLTYPE d3d11_immediate_context_SwapDeviceContextState(ID3D11DeviceContext1 *iface, ID3DDeviceContextState *state, ID3DDeviceContextState **prev_state) { @@ -2703,12 +2749,14 @@ static void STDMETHODCALLTYPE d3d11_immediate_context_SwapDeviceContextState(ID3 if ((state_impl = heap_alloc(sizeof(*state_impl)))) { d3d_device_context_state_init(state_impl, device, &device->emulated_interface); + d3d11_immediate_context_capture_state(iface, state_impl); *prev_state = &state_impl->ID3DDeviceContextState_iface; } }
if ((state_impl = impl_from_ID3DDeviceContextState(state))) { + d3d11_immediate_context_restore_state(iface, state_impl); device->emulated_interface = state_impl->emulated_interface; if (d3d_device_is_d3d10_active(device)) FIXME("D3D10 interface emulation not fully implemented yet!\n"); diff --git a/dlls/d3d11/tests/d3d11.c b/dlls/d3d11/tests/d3d11.c index 1f6e7f3795c..389954f18ab 100644 --- a/dlls/d3d11/tests/d3d11.c +++ b/dlls/d3d11/tests/d3d11.c @@ -6597,16 +6597,36 @@ static void test_state_refcounting(const D3D_FEATURE_LEVEL feature_level)
static void test_device_context_state(void) { +#if 0 + float4 main(float4 pos : POSITION) : POSITION + { + return pos; + } +#endif + static const DWORD simple_vs[] = + { + 0x43425844, 0x66689e7c, 0x643f0971, 0xb7f67ff4, 0xabc48688, 0x00000001, 0x000000d4, 0x00000003, + 0x0000002c, 0x00000060, 0x00000094, 0x4e475349, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, + 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000f0f, 0x49534f50, 0x4e4f4954, 0xababab00, + 0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003, + 0x00000000, 0x0000000f, 0x49534f50, 0x4e4f4954, 0xababab00, 0x52444853, 0x00000038, 0x00010040, + 0x0000000e, 0x0300005f, 0x001010f2, 0x00000000, 0x03000065, 0x001020f2, 0x00000000, 0x05000036, + 0x001020f2, 0x00000000, 0x00101e46, 0x00000000, 0x0100003e, + }; + ID3DDeviceContextState *context_state, *previous_context_state; ID3D11SamplerState *sampler, *tmp_sampler; + D3D11_SHADER_RESOURCE_VIEW_DESC srv_desc; + ID3D11ShaderResourceView *tmp_srv, *srv; D3D11_DEVICE_CONTEXT_TYPE context_type; ID3D11DeviceContext1 *context = NULL; D3D11_SAMPLER_DESC sampler_desc; D3D_FEATURE_LEVEL feature_level; + ID3D11VertexShader *tmp_vs, *vs; ID3D11Device *d3d11_device; ID3D11Device1 *device; struct vec4 constant; - ID3D11Buffer *cb, *tmp_cb; + ID3D11Buffer *cb, *srvb, *tmp_cb; ULONG refcount; HRESULT hr;
@@ -6677,12 +6697,6 @@ static void test_device_context_state(void) ok(tmp_sampler == sampler, "Got sampler %p, expected %p.\n", tmp_sampler, sampler); ID3D11SamplerState_Release(tmp_sampler);
- ID3D11DeviceContext1_VSSetSamplers(context, 0, 1, &sampler); - tmp_sampler = NULL; - ID3D11DeviceContext1_VSGetSamplers(context, 0, 1, &tmp_sampler); - ok(tmp_sampler == sampler, "Got sampler %p, expected %p.\n", tmp_sampler, sampler); - ID3D11SamplerState_Release(tmp_sampler); - feature_level = min(feature_level, D3D_FEATURE_LEVEL_11_1); hr = ID3D11Device1_CreateDeviceContextState(device, 0, &feature_level, 1, D3D11_SDK_VERSION, &IID_ID3D11Device1, NULL, &context_state); @@ -6705,6 +6719,7 @@ static void test_device_context_state(void) check_interface(device, &IID_ID3D11Device1, TRUE, FALSE);
cb = create_buffer((ID3D11Device *)device, D3D11_BIND_CONSTANT_BUFFER, sizeof(constant), NULL); + srvb = create_buffer((ID3D11Device *)device, D3D11_BIND_SHADER_RESOURCE, 1024, NULL);
ID3D11DeviceContext1_CSSetConstantBuffers(context, 0, 1, &cb); tmp_cb = NULL; @@ -6718,12 +6733,6 @@ static void test_device_context_state(void) ok(tmp_cb == cb, "Got buffer %p, expected %p.\n", tmp_cb, cb); ID3D11Buffer_Release(tmp_cb);
- ID3D11DeviceContext1_VSSetConstantBuffers(context, 0, 1, &cb); - tmp_cb = NULL; - ID3D11DeviceContext1_VSGetConstantBuffers(context, 0, 1, &tmp_cb); - ok(tmp_cb == cb, "Got buffer %p, expected %p.\n", tmp_cb, cb); - ID3D11Buffer_Release(tmp_cb); - ID3D11DeviceContext1_DSSetConstantBuffers(context, 0, 1, &cb); tmp_cb = NULL; ID3D11DeviceContext1_DSGetConstantBuffers(context, 0, 1, &tmp_cb); @@ -6742,6 +6751,22 @@ static void test_device_context_state(void) ok(tmp_cb == cb, "Got buffer %p, expected %p.\n", tmp_cb, cb); ID3D11Buffer_Release(tmp_cb);
+ hr = ID3D11Device1_CreateVertexShader(device, simple_vs, sizeof(simple_vs), NULL, &vs); + ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr); + + srv_desc.Format = DXGI_FORMAT_R32G32B32A32_FLOAT; + srv_desc.ViewDimension = D3D11_SRV_DIMENSION_BUFFER; + U(srv_desc).Buffer.ElementOffset = 0; + U(srv_desc).Buffer.ElementWidth = 64; + hr = ID3D11Device1_CreateShaderResourceView(device, (ID3D11Resource *)srvb, &srv_desc, &srv); + ok(SUCCEEDED(hr), "Failed to create shader resource view, hr %#x.\n", hr); + ID3D11Buffer_Release(srvb); + + ID3D11DeviceContext1_VSSetConstantBuffers(context, 0, 1, &cb); + ID3D11DeviceContext1_VSSetSamplers(context, 0, 1, &sampler); + ID3D11DeviceContext1_VSSetShader(context, vs, NULL, 0); + ID3D11DeviceContext1_VSSetShaderResources(context, 0, 1, &srv); + previous_context_state = NULL; ID3D11DeviceContext1_SwapDeviceContextState(context, context_state, &previous_context_state); refcount = ID3DDeviceContextState_Release(context_state); @@ -6751,6 +6776,19 @@ static void test_device_context_state(void) context_type = ID3D11DeviceContext1_GetType(context); ok(context_type == D3D11_DEVICE_CONTEXT_IMMEDIATE, "Unexpected context type %u.\n", context_type);
+ tmp_cb = (ID3D11Buffer *)0xdeadbeef; + ID3D11DeviceContext1_VSGetConstantBuffers(context, 0, 1, &tmp_cb); + ok(!tmp_cb, "Got unexpected buffer %p.\n", tmp_cb); + tmp_sampler = (ID3D11SamplerState *)0xdeadbeef; + ID3D11DeviceContext1_VSGetSamplers(context, 0, 1, &tmp_sampler); + ok(!tmp_sampler, "Got unexpected sampler %p.\n", tmp_sampler); + tmp_vs = (ID3D11VertexShader *)0xdeadbeef; + ID3D11DeviceContext1_VSGetShader(context, &tmp_vs, NULL, NULL); + ok(!tmp_vs, "Got unexpected shader %p.\n", tmp_vs); + tmp_srv = (ID3D11ShaderResourceView *)0xdeadbeef; + ID3D11DeviceContext1_VSGetShaderResources(context, 0, 1, &tmp_srv); + ok(!tmp_srv, "Got unexpected srv %p.\n", tmp_srv); + ID3D11DeviceContext1_SwapDeviceContextState(context, previous_context_state, &context_state); refcount = ID3DDeviceContextState_Release(context_state); ok(!refcount, "Got refcount %u, expected 0.\n", refcount); @@ -6812,6 +6850,14 @@ static void test_device_context_state(void) ID3D11DeviceContext1_CSGetConstantBuffers(context, 0, 1, &tmp_cb); ok(tmp_cb == cb, "Got buffer %p, expected %p.\n", tmp_cb, cb); ID3D11Buffer_Release(tmp_cb); + tmp_vs = (ID3D11VertexShader *)0xdeadbeef; + ID3D11DeviceContext1_VSGetShader(context, &tmp_vs, NULL, NULL); + ok(tmp_vs == vs, "Got shader %p, expected %p.\n", tmp_vs, vs); + ID3D11VertexShader_Release(tmp_vs); + tmp_srv = (ID3D11ShaderResourceView *)0xdeadbeef; + ID3D11DeviceContext1_VSGetShaderResources(context, 0, 1, &tmp_srv); + ok(tmp_srv == srv, "Got srv %p, expected %p.\n", tmp_srv, srv); + ID3D11ShaderResourceView_Release(tmp_srv);
feature_level = min(feature_level, D3D_FEATURE_LEVEL_10_1); hr = ID3D11Device1_CreateDeviceContextState(device, 0, &feature_level, 1, D3D11_SDK_VERSION, @@ -6866,11 +6912,27 @@ static void test_device_context_state(void) todo_wine ok(!tmp_sampler, "Got unexpected sampler %p.\n", tmp_sampler); if (tmp_sampler) ID3D11SamplerState_Release(tmp_sampler);
+ ID3D11DeviceContext1_VSSetConstantBuffers(context, 0, 1, &cb); ID3D11DeviceContext1_VSSetSamplers(context, 0, 1, &sampler); + ID3D11DeviceContext1_VSSetShader(context, vs, NULL, 0); + ID3D11DeviceContext1_VSSetShaderResources(context, 0, 1, &srv); + + tmp_cb = (ID3D11Buffer *)0xdeadbeef; + ID3D11DeviceContext1_VSGetConstantBuffers(context, 0, 1, &tmp_cb); + todo_wine ok(!tmp_cb, "Got unexpected buffer %p.\n", tmp_cb); + if (tmp_cb && tmp_cb != (ID3D11Buffer *)0xdeadbeef) ID3D11Buffer_Release(tmp_cb); tmp_sampler = (ID3D11SamplerState *)0xdeadbeef; ID3D11DeviceContext1_VSGetSamplers(context, 0, 1, &tmp_sampler); todo_wine ok(!tmp_sampler, "Got unexpected sampler %p.\n", tmp_sampler); - if (tmp_sampler) ID3D11SamplerState_Release(tmp_sampler); + if (tmp_sampler && tmp_sampler != (ID3D11SamplerState *)0xdeadbeef) ID3D11SamplerState_Release(tmp_sampler); + tmp_vs = (ID3D11VertexShader *)0xdeadbeef; + ID3D11DeviceContext1_VSGetShader(context, &tmp_vs, NULL, NULL); + todo_wine ok(!tmp_vs, "Got unexpected shader %p.\n", tmp_vs); + if (tmp_vs && tmp_vs != (ID3D11VertexShader *)0xdeadbeef) ID3D11VertexShader_Release(tmp_vs); + tmp_srv = (ID3D11ShaderResourceView *)0xdeadbeef; + ID3D11DeviceContext1_VSGetShaderResources(context, 0, 1, &tmp_srv); + todo_wine ok(!tmp_srv, "Got unexpected srv %p.\n", tmp_srv); + if (tmp_srv && tmp_srv != (ID3D11ShaderResourceView *)0xdeadbeef) ID3D11ShaderResourceView_Release(tmp_srv);
tmp_cb = (ID3D11Buffer *)0xdeadbeef; ID3D11DeviceContext1_CSGetConstantBuffers(context, 0, 1, &tmp_cb); @@ -6882,11 +6944,6 @@ static void test_device_context_state(void) todo_wine ok(!tmp_cb, "Got unexpected buffer %p.\n", tmp_cb); if (tmp_cb) ID3D11Buffer_Release(tmp_cb);
- tmp_cb = (ID3D11Buffer *)0xdeadbeef; - ID3D11DeviceContext1_VSGetConstantBuffers(context, 0, 1, &tmp_cb); - todo_wine ok(!tmp_cb, "Got unexpected buffer %p.\n", tmp_cb); - if (tmp_cb) ID3D11Buffer_Release(tmp_cb); - tmp_cb = (ID3D11Buffer *)0xdeadbeef; ID3D11DeviceContext1_DSGetConstantBuffers(context, 0, 1, &tmp_cb); todo_wine ok(!tmp_cb, "Got unexpected buffer %p.\n", tmp_cb); @@ -6929,10 +6986,29 @@ static void test_device_context_state(void) ok(tmp_sampler == sampler, "Got sampler %p, expected %p.\n", tmp_sampler, sampler); ID3D11SamplerState_Release(tmp_sampler);
+ 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_vs = (ID3D11VertexShader *)0xdeadbeef; + ID3D11DeviceContext1_VSGetShader(context, &tmp_vs, NULL, NULL); + ok(tmp_vs == vs, "Got shader %p, expected %p.\n", tmp_vs, vs); + ID3D11VertexShader_Release(tmp_vs); + tmp_srv = (ID3D11ShaderResourceView *)0xdeadbeef; + ID3D11DeviceContext1_VSGetShaderResources(context, 0, 1, &tmp_srv); + ok(tmp_srv == srv, "Got srv %p, expected %p.\n", tmp_srv, srv); + ID3D11ShaderResourceView_Release(tmp_srv); + check_interface(device, &IID_ID3D10Device, TRUE, FALSE); check_interface(device, &IID_ID3D10Device1, TRUE, FALSE);
+ ID3D11VertexShader_Release(vs); ID3D11Buffer_Release(cb); + ID3D11ShaderResourceView_Release(srv); ID3D11SamplerState_Release(sampler); ID3D11DeviceContext1_Release(context); refcount = ID3D11Device1_Release(device);
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=84371
Your paranoid android.
=== w1064_2qxl (64 bit report) ===
d3d11: d3d11.c:6137: Test failed: Got unexpected PrimitivesStorageNeeded: 4277992701.
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/d3d11/d3d11_private.h | 7 ++ dlls/d3d11/device.c | 21 ++++++ dlls/d3d11/tests/d3d11.c | 136 ++++++++++++++++++++++++++++++------- 3 files changed, 141 insertions(+), 23 deletions(-)
diff --git a/dlls/d3d11/d3d11_private.h b/dlls/d3d11/d3d11_private.h index a5a9f227eeb..164993d40f4 100644 --- a/dlls/d3d11/d3d11_private.h +++ b/dlls/d3d11/d3d11_private.h @@ -530,6 +530,13 @@ struct d3d_device_context_state ID3D11ShaderResourceView *srvs[D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT]; ID3D11Buffer *cbs[D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT]; } vs; + struct + { + ID3D11GeometryShader *shader; + ID3D11SamplerState *samplers[D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT]; + ID3D11ShaderResourceView *srvs[D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT]; + ID3D11Buffer *cbs[D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT]; + } gs;
ID3D11Device2 *device; GUID emulated_interface; diff --git a/dlls/d3d11/device.c b/dlls/d3d11/device.c index 1461a41a06b..cb1043032d2 100644 --- a/dlls/d3d11/device.c +++ b/dlls/d3d11/device.c @@ -100,17 +100,21 @@ static ULONG STDMETHODCALLTYPE d3d_device_context_state_Release(ID3DDeviceContex if (!refcount) { if (state->vs.shader) ID3D11VertexShader_Release(state->vs.shader); + if (state->gs.shader) ID3D11GeometryShader_Release(state->gs.shader); for (i = 0; i < D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT; ++i) { if (state->vs.samplers[i]) ID3D11SamplerState_Release(state->vs.samplers[i]); + if (state->gs.samplers[i]) ID3D11SamplerState_Release(state->gs.samplers[i]); } for (i = 0; i < D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT; ++i) { if (state->vs.srvs[i]) ID3D11ShaderResourceView_Release(state->vs.srvs[i]); + if (state->gs.srvs[i]) ID3D11ShaderResourceView_Release(state->gs.srvs[i]); } for (i = 0; i < D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT; ++i) { if (state->vs.cbs[i]) ID3D11Buffer_Release(state->vs.cbs[i]); + if (state->gs.cbs[i]) ID3D11Buffer_Release(state->gs.cbs[i]); }
wined3d_private_store_cleanup(&state->private_store); @@ -183,6 +187,7 @@ static void d3d_device_context_state_init(struct d3d_device_context_state *state
wined3d_private_store_init(&state->private_store); memset(&state->vs, 0, sizeof(state->vs)); + memset(&state->gs, 0, sizeof(state->gs)); }
/* ID3D11DeviceContext - immediate context methods */ @@ -2716,6 +2721,14 @@ static void d3d11_immediate_context_capture_state(ID3D11DeviceContext1 *iface, s d3d11_immediate_context_VSGetConstantBuffers(iface, 0, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT, state->vs.cbs);
+ d3d11_immediate_context_GSGetShader(iface, &state->gs.shader, NULL, 0); + d3d11_immediate_context_GSGetSamplers(iface, 0, + D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT, state->gs.samplers); + d3d11_immediate_context_GSGetShaderResources(iface, 0, + D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT, state->gs.srvs); + d3d11_immediate_context_GSGetConstantBuffers(iface, 0, + D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT, state->gs.cbs); + wined3d_mutex_unlock(); }
@@ -2731,6 +2744,14 @@ static void d3d11_immediate_context_restore_state(ID3D11DeviceContext1 *iface, s d3d11_immediate_context_VSSetConstantBuffers(iface, 0, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT, state->vs.cbs);
+ d3d11_immediate_context_GSSetShader(iface, state->gs.shader, NULL, 0); + d3d11_immediate_context_GSSetSamplers(iface, 0, + D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT, state->gs.samplers); + d3d11_immediate_context_GSSetShaderResources(iface, 0, + D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT, state->gs.srvs); + d3d11_immediate_context_GSSetConstantBuffers(iface, 0, + D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT, state->gs.cbs); + wined3d_mutex_unlock(); }
diff --git a/dlls/d3d11/tests/d3d11.c b/dlls/d3d11/tests/d3d11.c index 389954f18ab..aa4b54ba9d5 100644 --- a/dlls/d3d11/tests/d3d11.c +++ b/dlls/d3d11/tests/d3d11.c @@ -6613,6 +6613,49 @@ static void test_device_context_state(void) 0x0000000e, 0x0300005f, 0x001010f2, 0x00000000, 0x03000065, 0x001020f2, 0x00000000, 0x05000036, 0x001020f2, 0x00000000, 0x00101e46, 0x00000000, 0x0100003e, }; +#if 0 + struct gs_out + { + float4 pos : SV_POSITION; + }; + + [maxvertexcount(4)] + void main(point float4 vin[1] : POSITION, inout TriangleStream<gs_out> vout) + { + float offset = 0.1 * vin[0].w; + gs_out v; + + v.pos = float4(vin[0].x - offset, vin[0].y - offset, vin[0].z, vin[0].w); + vout.Append(v); + v.pos = float4(vin[0].x - offset, vin[0].y + offset, vin[0].z, vin[0].w); + vout.Append(v); + v.pos = float4(vin[0].x + offset, vin[0].y - offset, vin[0].z, vin[0].w); + vout.Append(v); + v.pos = float4(vin[0].x + offset, vin[0].y + offset, vin[0].z, vin[0].w); + vout.Append(v); + } +#endif + static const DWORD simple_gs[] = + { + 0x43425844, 0x000ee786, 0xc624c269, 0x885a5cbe, 0x444b3b1f, 0x00000001, 0x0000023c, 0x00000003, + 0x0000002c, 0x00000060, 0x00000094, 0x4e475349, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, + 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000f0f, 0x49534f50, 0x4e4f4954, 0xababab00, + 0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000001, 0x00000003, + 0x00000000, 0x0000000f, 0x505f5653, 0x5449534f, 0x004e4f49, 0x52444853, 0x000001a0, 0x00020040, + 0x00000068, 0x0400005f, 0x002010f2, 0x00000001, 0x00000000, 0x02000068, 0x00000001, 0x0100085d, + 0x0100285c, 0x04000067, 0x001020f2, 0x00000000, 0x00000001, 0x0200005e, 0x00000004, 0x0f000032, + 0x00100032, 0x00000000, 0x80201ff6, 0x00000041, 0x00000000, 0x00000000, 0x00004002, 0x3dcccccd, + 0x3dcccccd, 0x00000000, 0x00000000, 0x00201046, 0x00000000, 0x00000000, 0x05000036, 0x00102032, + 0x00000000, 0x00100046, 0x00000000, 0x06000036, 0x001020c2, 0x00000000, 0x00201ea6, 0x00000000, + 0x00000000, 0x01000013, 0x05000036, 0x00102012, 0x00000000, 0x0010000a, 0x00000000, 0x0e000032, + 0x00100052, 0x00000000, 0x00201ff6, 0x00000000, 0x00000000, 0x00004002, 0x3dcccccd, 0x00000000, + 0x3dcccccd, 0x00000000, 0x00201106, 0x00000000, 0x00000000, 0x05000036, 0x00102022, 0x00000000, + 0x0010002a, 0x00000000, 0x06000036, 0x001020c2, 0x00000000, 0x00201ea6, 0x00000000, 0x00000000, + 0x01000013, 0x05000036, 0x00102012, 0x00000000, 0x0010000a, 0x00000000, 0x05000036, 0x00102022, + 0x00000000, 0x0010001a, 0x00000000, 0x06000036, 0x001020c2, 0x00000000, 0x00201ea6, 0x00000000, + 0x00000000, 0x01000013, 0x05000036, 0x00102032, 0x00000000, 0x00100086, 0x00000000, 0x06000036, + 0x001020c2, 0x00000000, 0x00201ea6, 0x00000000, 0x00000000, 0x01000013, 0x0100003e, + };
ID3DDeviceContextState *context_state, *previous_context_state; ID3D11SamplerState *sampler, *tmp_sampler; @@ -6622,6 +6665,7 @@ static void test_device_context_state(void) ID3D11DeviceContext1 *context = NULL; D3D11_SAMPLER_DESC sampler_desc; D3D_FEATURE_LEVEL feature_level; + ID3D11GeometryShader *tmp_gs, *gs; ID3D11VertexShader *tmp_vs, *vs; ID3D11Device *d3d11_device; ID3D11Device1 *device; @@ -6685,12 +6729,6 @@ static void test_device_context_state(void) ok(tmp_sampler == sampler, "Got sampler %p, expected %p.\n", tmp_sampler, sampler); ID3D11SamplerState_Release(tmp_sampler);
- ID3D11DeviceContext1_GSSetSamplers(context, 0, 1, &sampler); - tmp_sampler = NULL; - ID3D11DeviceContext1_GSGetSamplers(context, 0, 1, &tmp_sampler); - ok(tmp_sampler == sampler, "Got sampler %p, expected %p.\n", tmp_sampler, sampler); - ID3D11SamplerState_Release(tmp_sampler); - ID3D11DeviceContext1_HSSetSamplers(context, 0, 1, &sampler); tmp_sampler = NULL; ID3D11DeviceContext1_HSGetSamplers(context, 0, 1, &tmp_sampler); @@ -6739,12 +6777,6 @@ static void test_device_context_state(void) ok(tmp_cb == cb, "Got buffer %p, expected %p.\n", tmp_cb, cb); ID3D11Buffer_Release(tmp_cb);
- ID3D11DeviceContext1_GSSetConstantBuffers(context, 0, 1, &cb); - tmp_cb = NULL; - ID3D11DeviceContext1_GSGetConstantBuffers(context, 0, 1, &tmp_cb); - ok(tmp_cb == cb, "Got buffer %p, expected %p.\n", tmp_cb, cb); - ID3D11Buffer_Release(tmp_cb); - ID3D11DeviceContext1_HSSetConstantBuffers(context, 0, 1, &cb); tmp_cb = NULL; ID3D11DeviceContext1_HSGetConstantBuffers(context, 0, 1, &tmp_cb); @@ -6754,6 +6786,9 @@ static void test_device_context_state(void) hr = ID3D11Device1_CreateVertexShader(device, simple_vs, sizeof(simple_vs), NULL, &vs); ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr);
+ hr = ID3D11Device1_CreateGeometryShader(device, simple_gs, sizeof(simple_gs), NULL, &gs); + ok(SUCCEEDED(hr), "Failed to create geometry shader, hr %#x.\n", hr); + srv_desc.Format = DXGI_FORMAT_R32G32B32A32_FLOAT; srv_desc.ViewDimension = D3D11_SRV_DIMENSION_BUFFER; U(srv_desc).Buffer.ElementOffset = 0; @@ -6767,6 +6802,11 @@ static void test_device_context_state(void) ID3D11DeviceContext1_VSSetShader(context, vs, NULL, 0); ID3D11DeviceContext1_VSSetShaderResources(context, 0, 1, &srv);
+ ID3D11DeviceContext1_GSSetConstantBuffers(context, 0, 1, &cb); + ID3D11DeviceContext1_GSSetSamplers(context, 0, 1, &sampler); + ID3D11DeviceContext1_GSSetShader(context, gs, NULL, 0); + ID3D11DeviceContext1_GSSetShaderResources(context, 0, 1, &srv); + previous_context_state = NULL; ID3D11DeviceContext1_SwapDeviceContextState(context, context_state, &previous_context_state); refcount = ID3DDeviceContextState_Release(context_state); @@ -6789,6 +6829,19 @@ static void test_device_context_state(void) ID3D11DeviceContext1_VSGetShaderResources(context, 0, 1, &tmp_srv); ok(!tmp_srv, "Got unexpected srv %p.\n", tmp_srv);
+ tmp_cb = (ID3D11Buffer *)0xdeadbeef; + ID3D11DeviceContext1_GSGetConstantBuffers(context, 0, 1, &tmp_cb); + ok(!tmp_cb, "Got unexpected buffer %p.\n", tmp_cb); + tmp_sampler = (ID3D11SamplerState *)0xdeadbeef; + ID3D11DeviceContext1_GSGetSamplers(context, 0, 1, &tmp_sampler); + ok(!tmp_sampler, "Got unexpected sampler %p.\n", tmp_sampler); + tmp_gs = (ID3D11GeometryShader *)0xdeadbeef; + ID3D11DeviceContext1_GSGetShader(context, &tmp_gs, NULL, NULL); + ok(!tmp_gs, "Got unexpected shader %p.\n", tmp_gs); + tmp_srv = (ID3D11ShaderResourceView *)0xdeadbeef; + ID3D11DeviceContext1_GSGetShaderResources(context, 0, 1, &tmp_srv); + ok(!tmp_srv, "Got unexpected srv %p.\n", tmp_srv); + ID3D11DeviceContext1_SwapDeviceContextState(context, previous_context_state, &context_state); refcount = ID3DDeviceContextState_Release(context_state); ok(!refcount, "Got refcount %u, expected 0.\n", refcount); @@ -6832,6 +6885,14 @@ static void test_device_context_state(void) 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_gs = (ID3D11GeometryShader *)0xdeadbeef; + ID3D11DeviceContext1_GSGetShader(context, &tmp_gs, NULL, NULL); + ok(tmp_gs == gs, "Got shader %p, expected %p.\n", tmp_gs, gs); + ID3D11GeometryShader_Release(tmp_gs); + tmp_srv = (ID3D11ShaderResourceView *)0xdeadbeef; + ID3D11DeviceContext1_GSGetShaderResources(context, 0, 1, &tmp_srv); + ok(tmp_srv == srv, "Got srv %p, expected %p.\n", tmp_srv, srv); + ID3D11ShaderResourceView_Release(tmp_srv);
tmp_sampler = (ID3D11SamplerState *)0xdeadbeef; ID3D11DeviceContext1_DSGetSamplers(context, 0, 1, &tmp_sampler); @@ -6900,12 +6961,6 @@ static void test_device_context_state(void) todo_wine ok(!tmp_sampler, "Got unexpected sampler %p.\n", tmp_sampler); if (tmp_sampler) ID3D11SamplerState_Release(tmp_sampler);
- ID3D11DeviceContext1_GSSetSamplers(context, 0, 1, &sampler); - tmp_sampler = (ID3D11SamplerState *)0xdeadbeef; - ID3D11DeviceContext1_GSGetSamplers(context, 0, 1, &tmp_sampler); - todo_wine ok(!tmp_sampler, "Got unexpected sampler %p.\n", tmp_sampler); - if (tmp_sampler) ID3D11SamplerState_Release(tmp_sampler); - ID3D11DeviceContext1_HSSetSamplers(context, 0, 1, &sampler); tmp_sampler = (ID3D11SamplerState *)0xdeadbeef; ID3D11DeviceContext1_HSGetSamplers(context, 0, 1, &tmp_sampler); @@ -6934,23 +6989,40 @@ static void test_device_context_state(void) todo_wine ok(!tmp_srv, "Got unexpected srv %p.\n", tmp_srv); if (tmp_srv && tmp_srv != (ID3D11ShaderResourceView *)0xdeadbeef) ID3D11ShaderResourceView_Release(tmp_srv);
+ ID3D11DeviceContext1_GSSetConstantBuffers(context, 0, 1, &cb); + ID3D11DeviceContext1_GSSetSamplers(context, 0, 1, &sampler); + ID3D11DeviceContext1_GSSetShader(context, gs, NULL, 0); + ID3D11DeviceContext1_GSSetShaderResources(context, 0, 1, &srv); + tmp_cb = (ID3D11Buffer *)0xdeadbeef; - ID3D11DeviceContext1_CSGetConstantBuffers(context, 0, 1, &tmp_cb); + ID3D11DeviceContext1_GSGetConstantBuffers(context, 0, 1, &tmp_cb); todo_wine ok(!tmp_cb, "Got unexpected buffer %p.\n", tmp_cb); - if (tmp_cb) ID3D11Buffer_Release(tmp_cb); + if (tmp_cb && tmp_cb != (ID3D11Buffer *)0xdeadbeef) ID3D11Buffer_Release(tmp_cb); + tmp_sampler = (ID3D11SamplerState *)0xdeadbeef; + ID3D11DeviceContext1_GSGetSamplers(context, 0, 1, &tmp_sampler); + todo_wine ok(!tmp_sampler, "Got unexpected sampler %p.\n", tmp_sampler); + if (tmp_sampler && tmp_sampler != (ID3D11SamplerState *)0xdeadbeef) ID3D11SamplerState_Release(tmp_sampler); + tmp_gs = (ID3D11GeometryShader *)0xdeadbeef; + ID3D11DeviceContext1_GSGetShader(context, &tmp_gs, NULL, NULL); + todo_wine ok(!tmp_gs, "Got unexpected shader %p.\n", tmp_gs); + if (tmp_gs && tmp_gs != (ID3D11GeometryShader *)0xdeadbeef) ID3D11GeometryShader_Release(tmp_gs); + tmp_srv = (ID3D11ShaderResourceView *)0xdeadbeef; + ID3D11DeviceContext1_GSGetShaderResources(context, 0, 1, &tmp_srv); + todo_wine ok(!tmp_srv, "Got unexpected srv %p.\n", tmp_srv); + if (tmp_srv && tmp_srv != (ID3D11ShaderResourceView *)0xdeadbeef) ID3D11ShaderResourceView_Release(tmp_srv);
tmp_cb = (ID3D11Buffer *)0xdeadbeef; - ID3D11DeviceContext1_PSGetConstantBuffers(context, 0, 1, &tmp_cb); + ID3D11DeviceContext1_CSGetConstantBuffers(context, 0, 1, &tmp_cb); todo_wine ok(!tmp_cb, "Got unexpected buffer %p.\n", tmp_cb); if (tmp_cb) ID3D11Buffer_Release(tmp_cb);
tmp_cb = (ID3D11Buffer *)0xdeadbeef; - ID3D11DeviceContext1_DSGetConstantBuffers(context, 0, 1, &tmp_cb); + ID3D11DeviceContext1_PSGetConstantBuffers(context, 0, 1, &tmp_cb); todo_wine ok(!tmp_cb, "Got unexpected buffer %p.\n", tmp_cb); if (tmp_cb) ID3D11Buffer_Release(tmp_cb);
tmp_cb = (ID3D11Buffer *)0xdeadbeef; - ID3D11DeviceContext1_GSGetConstantBuffers(context, 0, 1, &tmp_cb); + ID3D11DeviceContext1_DSGetConstantBuffers(context, 0, 1, &tmp_cb); todo_wine ok(!tmp_cb, "Got unexpected buffer %p.\n", tmp_cb); if (tmp_cb) ID3D11Buffer_Release(tmp_cb);
@@ -7003,9 +7075,27 @@ static void test_device_context_state(void) ok(tmp_srv == srv, "Got srv %p, expected %p.\n", tmp_srv, srv); ID3D11ShaderResourceView_Release(tmp_srv);
+ 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_gs = (ID3D11GeometryShader *)0xdeadbeef; + ID3D11DeviceContext1_GSGetShader(context, &tmp_gs, NULL, NULL); + ok(tmp_gs == gs, "Got shader %p, expected %p.\n", tmp_gs, gs); + ID3D11GeometryShader_Release(tmp_gs); + tmp_srv = (ID3D11ShaderResourceView *)0xdeadbeef; + ID3D11DeviceContext1_GSGetShaderResources(context, 0, 1, &tmp_srv); + ok(tmp_srv == srv, "Got srv %p, expected %p.\n", tmp_srv, srv); + ID3D11ShaderResourceView_Release(tmp_srv); + check_interface(device, &IID_ID3D10Device, TRUE, FALSE); check_interface(device, &IID_ID3D10Device1, TRUE, FALSE);
+ ID3D11GeometryShader_Release(gs); ID3D11VertexShader_Release(vs); ID3D11Buffer_Release(cb); ID3D11ShaderResourceView_Release(srv);
Signed-off-by: Rémi Bernon rbernon@codeweavers.com ---
Same here, although I wasn't sure what the !enable_debug_layer case is doing there. The D3D11 interface is supposed to be disabled anyway, so setting the PS sampler is a no-op, right?
dlls/d3d11/d3d11_private.h | 7 +++ dlls/d3d11/device.c | 21 +++++++ dlls/d3d11/tests/d3d11.c | 123 +++++++++++++++++++++++++------------ 3 files changed, 112 insertions(+), 39 deletions(-)
diff --git a/dlls/d3d11/d3d11_private.h b/dlls/d3d11/d3d11_private.h index 164993d40f4..5f5234d3d32 100644 --- a/dlls/d3d11/d3d11_private.h +++ b/dlls/d3d11/d3d11_private.h @@ -537,6 +537,13 @@ struct d3d_device_context_state ID3D11ShaderResourceView *srvs[D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT]; ID3D11Buffer *cbs[D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT]; } gs; + struct + { + ID3D11PixelShader *shader; + ID3D11SamplerState *samplers[D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT]; + ID3D11ShaderResourceView *srvs[D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT]; + ID3D11Buffer *cbs[D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT]; + } ps;
ID3D11Device2 *device; GUID emulated_interface; diff --git a/dlls/d3d11/device.c b/dlls/d3d11/device.c index cb1043032d2..2fb164480b6 100644 --- a/dlls/d3d11/device.c +++ b/dlls/d3d11/device.c @@ -101,20 +101,24 @@ static ULONG STDMETHODCALLTYPE d3d_device_context_state_Release(ID3DDeviceContex { if (state->vs.shader) ID3D11VertexShader_Release(state->vs.shader); if (state->gs.shader) ID3D11GeometryShader_Release(state->gs.shader); + if (state->ps.shader) ID3D11PixelShader_Release(state->ps.shader); for (i = 0; i < D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT; ++i) { if (state->vs.samplers[i]) ID3D11SamplerState_Release(state->vs.samplers[i]); if (state->gs.samplers[i]) ID3D11SamplerState_Release(state->gs.samplers[i]); + if (state->ps.samplers[i]) ID3D11SamplerState_Release(state->ps.samplers[i]); } for (i = 0; i < D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT; ++i) { if (state->vs.srvs[i]) ID3D11ShaderResourceView_Release(state->vs.srvs[i]); if (state->gs.srvs[i]) ID3D11ShaderResourceView_Release(state->gs.srvs[i]); + if (state->ps.srvs[i]) ID3D11ShaderResourceView_Release(state->ps.srvs[i]); } for (i = 0; i < D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT; ++i) { if (state->vs.cbs[i]) ID3D11Buffer_Release(state->vs.cbs[i]); if (state->gs.cbs[i]) ID3D11Buffer_Release(state->gs.cbs[i]); + if (state->ps.cbs[i]) ID3D11Buffer_Release(state->ps.cbs[i]); }
wined3d_private_store_cleanup(&state->private_store); @@ -188,6 +192,7 @@ static void d3d_device_context_state_init(struct d3d_device_context_state *state wined3d_private_store_init(&state->private_store); memset(&state->vs, 0, sizeof(state->vs)); memset(&state->gs, 0, sizeof(state->gs)); + memset(&state->ps, 0, sizeof(state->ps)); }
/* ID3D11DeviceContext - immediate context methods */ @@ -2729,6 +2734,14 @@ static void d3d11_immediate_context_capture_state(ID3D11DeviceContext1 *iface, s d3d11_immediate_context_GSGetConstantBuffers(iface, 0, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT, state->gs.cbs);
+ d3d11_immediate_context_PSGetShader(iface, &state->ps.shader, NULL, 0); + d3d11_immediate_context_PSGetSamplers(iface, 0, + D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT, state->ps.samplers); + d3d11_immediate_context_PSGetShaderResources(iface, 0, + D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT, state->ps.srvs); + d3d11_immediate_context_PSGetConstantBuffers(iface, 0, + D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT, state->ps.cbs); + wined3d_mutex_unlock(); }
@@ -2752,6 +2765,14 @@ static void d3d11_immediate_context_restore_state(ID3D11DeviceContext1 *iface, s d3d11_immediate_context_GSSetConstantBuffers(iface, 0, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT, state->gs.cbs);
+ d3d11_immediate_context_PSSetShader(iface, state->ps.shader, NULL, 0); + d3d11_immediate_context_PSSetSamplers(iface, 0, + D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT, state->ps.samplers); + d3d11_immediate_context_PSSetShaderResources(iface, 0, + D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT, state->ps.srvs); + d3d11_immediate_context_PSSetConstantBuffers(iface, 0, + D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT, state->ps.cbs); + wined3d_mutex_unlock(); }
diff --git a/dlls/d3d11/tests/d3d11.c b/dlls/d3d11/tests/d3d11.c index aa4b54ba9d5..7220be73ac7 100644 --- a/dlls/d3d11/tests/d3d11.c +++ b/dlls/d3d11/tests/d3d11.c @@ -6656,6 +6656,22 @@ static void test_device_context_state(void) 0x00000000, 0x01000013, 0x05000036, 0x00102032, 0x00000000, 0x00100086, 0x00000000, 0x06000036, 0x001020c2, 0x00000000, 0x00201ea6, 0x00000000, 0x00000000, 0x01000013, 0x0100003e, }; +#if 0 + float4 main(float4 color : COLOR) : SV_TARGET + { + return color; + } +#endif + static const DWORD simple_ps[] = + { + 0x43425844, 0x08c2b568, 0x17d33120, 0xb7d82948, 0x13a570fb, 0x00000001, 0x000000d0, 0x00000003, + 0x0000002c, 0x0000005c, 0x00000090, 0x4e475349, 0x00000028, 0x00000001, 0x00000008, 0x00000020, + 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000f0f, 0x4f4c4f43, 0xabab0052, 0x4e47534f, + 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003, 0x00000000, + 0x0000000f, 0x545f5653, 0x45475241, 0xabab0054, 0x52444853, 0x00000038, 0x00000040, 0x0000000e, + 0x03001062, 0x001010f2, 0x00000000, 0x03000065, 0x001020f2, 0x00000000, 0x05000036, 0x001020f2, + 0x00000000, 0x00101e46, 0x00000000, 0x0100003e, + };
ID3DDeviceContextState *context_state, *previous_context_state; ID3D11SamplerState *sampler, *tmp_sampler; @@ -6667,6 +6683,7 @@ static void test_device_context_state(void) D3D_FEATURE_LEVEL feature_level; ID3D11GeometryShader *tmp_gs, *gs; ID3D11VertexShader *tmp_vs, *vs; + ID3D11PixelShader *tmp_ps, *ps; ID3D11Device *d3d11_device; ID3D11Device1 *device; struct vec4 constant; @@ -6711,12 +6728,6 @@ static void test_device_context_state(void) hr = ID3D11Device1_CreateSamplerState(device, &sampler_desc, &sampler); ok(SUCCEEDED(hr), "Failed to create sampler state, hr %#x.\n", hr);
- ID3D11DeviceContext1_PSSetSamplers(context, 0, 1, &sampler); - tmp_sampler = NULL; - ID3D11DeviceContext1_PSGetSamplers(context, 0, 1, &tmp_sampler); - ok(tmp_sampler == sampler, "Got sampler %p, expected %p.\n", tmp_sampler, sampler); - ID3D11SamplerState_Release(tmp_sampler); - ID3D11DeviceContext1_CSSetSamplers(context, 0, 1, &sampler); tmp_sampler = NULL; ID3D11DeviceContext1_CSGetSamplers(context, 0, 1, &tmp_sampler); @@ -6765,12 +6776,6 @@ static void test_device_context_state(void) ok(tmp_cb == cb, "Got buffer %p, expected %p.\n", tmp_cb, cb); ID3D11Buffer_Release(tmp_cb);
- ID3D11DeviceContext1_PSSetConstantBuffers(context, 0, 1, &cb); - tmp_cb = NULL; - ID3D11DeviceContext1_PSGetConstantBuffers(context, 0, 1, &tmp_cb); - ok(tmp_cb == cb, "Got buffer %p, expected %p.\n", tmp_cb, cb); - ID3D11Buffer_Release(tmp_cb); - ID3D11DeviceContext1_DSSetConstantBuffers(context, 0, 1, &cb); tmp_cb = NULL; ID3D11DeviceContext1_DSGetConstantBuffers(context, 0, 1, &tmp_cb); @@ -6789,6 +6794,9 @@ static void test_device_context_state(void) hr = ID3D11Device1_CreateGeometryShader(device, simple_gs, sizeof(simple_gs), NULL, &gs); ok(SUCCEEDED(hr), "Failed to create geometry shader, hr %#x.\n", hr);
+ hr = ID3D11Device1_CreatePixelShader(device, simple_ps, sizeof(simple_ps), NULL, &ps); + ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr); + srv_desc.Format = DXGI_FORMAT_R32G32B32A32_FLOAT; srv_desc.ViewDimension = D3D11_SRV_DIMENSION_BUFFER; U(srv_desc).Buffer.ElementOffset = 0; @@ -6807,6 +6815,11 @@ static void test_device_context_state(void) ID3D11DeviceContext1_GSSetShader(context, gs, NULL, 0); ID3D11DeviceContext1_GSSetShaderResources(context, 0, 1, &srv);
+ ID3D11DeviceContext1_PSSetConstantBuffers(context, 0, 1, &cb); + ID3D11DeviceContext1_PSSetSamplers(context, 0, 1, &sampler); + ID3D11DeviceContext1_PSSetShader(context, ps, NULL, 0); + ID3D11DeviceContext1_PSSetShaderResources(context, 0, 1, &srv); + previous_context_state = NULL; ID3D11DeviceContext1_SwapDeviceContextState(context, context_state, &previous_context_state); refcount = ID3DDeviceContextState_Release(context_state); @@ -6842,6 +6855,19 @@ static void test_device_context_state(void) ID3D11DeviceContext1_GSGetShaderResources(context, 0, 1, &tmp_srv); ok(!tmp_srv, "Got unexpected srv %p.\n", tmp_srv);
+ tmp_cb = (ID3D11Buffer *)0xdeadbeef; + ID3D11DeviceContext1_PSGetConstantBuffers(context, 0, 1, &tmp_cb); + ok(!tmp_cb, "Got unexpected buffer %p.\n", tmp_cb); + tmp_sampler = (ID3D11SamplerState *)0xdeadbeef; + ID3D11DeviceContext1_PSGetSamplers(context, 0, 1, &tmp_sampler); + ok(!tmp_sampler, "Got unexpected sampler %p.\n", tmp_sampler); + tmp_ps = (ID3D11PixelShader *)0xdeadbeef; + ID3D11DeviceContext1_PSGetShader(context, &tmp_ps, NULL, NULL); + ok(!tmp_ps, "Got unexpected shader %p.\n", tmp_ps); + tmp_srv = (ID3D11ShaderResourceView *)0xdeadbeef; + ID3D11DeviceContext1_PSGetShaderResources(context, 0, 1, &tmp_srv); + ok(!tmp_srv, "Got unexpected srv %p.\n", tmp_srv); + ID3D11DeviceContext1_SwapDeviceContextState(context, previous_context_state, &context_state); refcount = ID3DDeviceContextState_Release(context_state); ok(!refcount, "Got refcount %u, expected 0.\n", refcount); @@ -6858,6 +6884,14 @@ static void test_device_context_state(void) 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_ps = (ID3D11PixelShader *)0xdeadbeef; + ID3D11DeviceContext1_PSGetShader(context, &tmp_ps, NULL, NULL); + ok(tmp_ps == ps, "Got shader %p, expected %p.\n", tmp_ps, ps); + ID3D11PixelShader_Release(tmp_ps); + tmp_srv = (ID3D11ShaderResourceView *)0xdeadbeef; + ID3D11DeviceContext1_PSGetShaderResources(context, 0, 1, &tmp_srv); + ok(tmp_srv == srv, "Got srv %p, expected %p.\n", tmp_srv, srv); + ID3D11ShaderResourceView_Release(tmp_srv);
tmp_sampler = (ID3D11SamplerState *)0xdeadbeef; ID3D11DeviceContext1_GSGetSamplers(context, 0, 1, &tmp_sampler); @@ -6940,15 +6974,6 @@ static void test_device_context_state(void) context_type = ID3D11DeviceContext1_GetType(context); ok(context_type == D3D11_DEVICE_CONTEXT_IMMEDIATE, "Unexpected context type %u.\n", context_type);
- ID3D11DeviceContext1_PSSetSamplers(context, 0, 1, &sampler); - tmp_sampler = (ID3D11SamplerState *)0xdeadbeef; - ID3D11DeviceContext1_PSGetSamplers(context, 0, 1, &tmp_sampler); - todo_wine ok(tmp_sampler == (ID3D11SamplerState *)0xdeadbeef, "Got unexpected sampler %p.\n", tmp_sampler); - if (tmp_sampler && tmp_sampler != (ID3D11SamplerState *)0xdeadbeef) - ID3D11SamplerState_Release(tmp_sampler); - if (!enable_debug_layer) - ID3D11DeviceContext1_PSSetSamplers(context, 0, 1, &tmp_sampler); - ID3D11DeviceContext1_CSSetSamplers(context, 0, 1, &sampler); tmp_sampler = (ID3D11SamplerState *)0xdeadbeef; ID3D11DeviceContext1_CSGetSamplers(context, 0, 1, &tmp_sampler); @@ -7011,13 +7036,30 @@ static void test_device_context_state(void) todo_wine ok(!tmp_srv, "Got unexpected srv %p.\n", tmp_srv); if (tmp_srv && tmp_srv != (ID3D11ShaderResourceView *)0xdeadbeef) ID3D11ShaderResourceView_Release(tmp_srv);
+ ID3D11DeviceContext1_PSSetConstantBuffers(context, 0, 1, &cb); + ID3D11DeviceContext1_PSSetSamplers(context, 0, 1, &sampler); + ID3D11DeviceContext1_PSSetShader(context, ps, NULL, 0); + ID3D11DeviceContext1_PSSetShaderResources(context, 0, 1, &srv); + tmp_cb = (ID3D11Buffer *)0xdeadbeef; - ID3D11DeviceContext1_CSGetConstantBuffers(context, 0, 1, &tmp_cb); + ID3D11DeviceContext1_PSGetConstantBuffers(context, 0, 1, &tmp_cb); todo_wine ok(!tmp_cb, "Got unexpected buffer %p.\n", tmp_cb); - if (tmp_cb) ID3D11Buffer_Release(tmp_cb); + if (tmp_cb && tmp_cb != (ID3D11Buffer *)0xdeadbeef) ID3D11Buffer_Release(tmp_cb); + tmp_sampler = (ID3D11SamplerState *)0xdeadbeef; + ID3D11DeviceContext1_PSGetSamplers(context, 0, 1, &tmp_sampler); + todo_wine ok(tmp_sampler == (ID3D11SamplerState *)0xdeadbeef, "Got unexpected sampler %p.\n", tmp_sampler); + if (tmp_sampler && tmp_sampler != (ID3D11SamplerState *)0xdeadbeef) ID3D11SamplerState_Release(tmp_sampler); + tmp_ps = (ID3D11PixelShader *)0xdeadbeef; + ID3D11DeviceContext1_PSGetShader(context, &tmp_ps, NULL, NULL); + todo_wine ok(!tmp_ps, "Got unexpected shader %p.\n", tmp_ps); + if (tmp_ps && tmp_ps != (ID3D11PixelShader *)0xdeadbeef) ID3D11PixelShader_Release(tmp_ps); + tmp_srv = (ID3D11ShaderResourceView *)0xdeadbeef; + ID3D11DeviceContext1_PSGetShaderResources(context, 0, 1, &tmp_srv); + todo_wine ok(!tmp_srv, "Got unexpected srv %p.\n", tmp_srv); + if (tmp_srv && tmp_srv != (ID3D11ShaderResourceView *)0xdeadbeef) ID3D11ShaderResourceView_Release(tmp_srv);
tmp_cb = (ID3D11Buffer *)0xdeadbeef; - ID3D11DeviceContext1_PSGetConstantBuffers(context, 0, 1, &tmp_cb); + ID3D11DeviceContext1_CSGetConstantBuffers(context, 0, 1, &tmp_cb); todo_wine ok(!tmp_cb, "Got unexpected buffer %p.\n", tmp_cb); if (tmp_cb) ID3D11Buffer_Release(tmp_cb);
@@ -7042,21 +7084,6 @@ static void test_device_context_state(void) ok(!refcount, "Got refcount %u, expected 0.\n", refcount);
/* ID3DDeviceContextState retains the previous state. */ - tmp_sampler = NULL; - 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_sampler = NULL; - ID3D11DeviceContext1_PSSetSamplers(context, 0, 1, &tmp_sampler); - tmp_sampler = (ID3D11SamplerState *)0xdeadbeef; - ID3D11DeviceContext1_PSGetSamplers(context, 0, 1, &tmp_sampler); - ok(!tmp_sampler, "Got unexpected sampler %p.\n", tmp_sampler); - ID3D11DeviceContext1_PSSetSamplers(context, 0, 1, &sampler); - tmp_sampler = NULL; - 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_sampler = (ID3D11SamplerState *)0xdeadbeef; ID3D11DeviceContext1_VSGetSamplers(context, 0, 1, &tmp_sampler); @@ -7092,9 +7119,27 @@ static void test_device_context_state(void) ok(tmp_srv == srv, "Got srv %p, expected %p.\n", tmp_srv, srv); ID3D11ShaderResourceView_Release(tmp_srv);
+ 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_ps = (ID3D11PixelShader *)0xdeadbeef; + ID3D11DeviceContext1_PSGetShader(context, &tmp_ps, NULL, NULL); + ok(tmp_ps == ps, "Got shader %p, expected %p.\n", tmp_ps, ps); + ID3D11PixelShader_Release(tmp_ps); + tmp_srv = (ID3D11ShaderResourceView *)0xdeadbeef; + ID3D11DeviceContext1_PSGetShaderResources(context, 0, 1, &tmp_srv); + ok(tmp_srv == srv, "Got srv %p, expected %p.\n", tmp_srv, srv); + ID3D11ShaderResourceView_Release(tmp_srv); + check_interface(device, &IID_ID3D10Device, TRUE, FALSE); check_interface(device, &IID_ID3D10Device1, TRUE, FALSE);
+ ID3D11PixelShader_Release(ps); ID3D11GeometryShader_Release(gs); ID3D11VertexShader_Release(vs); ID3D11Buffer_Release(cb);
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=84373
Your paranoid android.
=== w1064v1809 (32 bit report) ===
d3d11: d3d11.c:5804: Test failed: Got unexpected IAVertices count: 0. d3d11.c:5805: Test failed: Got unexpected IAPrimitives count: 0. d3d11.c:5806: Test failed: Got unexpected VSInvocations count: 0. d3d11.c:5809: Test failed: Got unexpected CInvocations count: 0. d3d11.c:5810: Test failed: Got unexpected CPrimitives count: 0.
On Thu, 21 Jan 2021 at 20:14, Rémi Bernon rbernon@codeweavers.com wrote:
Same here, although I wasn't sure what the !enable_debug_layer case is doing there. The D3D11 interface is supposed to be disabled anyway, so setting the PS sampler is a no-op, right?
"enable_debug_layer" checks are generally for calls that introduces failures or crashes when the debug layer is enabled.
On Thu, 21 Jan 2021 at 20:13, Rémi Bernon rbernon@codeweavers.com wrote:
+static inline struct d3d_device *device_from_ID3DDeviceContextState(ID3DDeviceContextState *iface) +{
- struct d3d_device_context_state *state = impl_from_ID3DDeviceContextState(iface);
- return impl_from_ID3D11Device2(state->device);
+}
You don't need this. For example, in d3d_device_context_state_AddRef(), you could simply do:
ID3D11Device2_AddRef(state->device);
+static HRESULT STDMETHODCALLTYPE d3d_device_context_state_QueryInterface(ID3DDeviceContextState *iface,
REFIID iid, void **out)
+{
- struct d3d_device_context_state *state = impl_from_ID3DDeviceContextState(iface);
- TRACE("iface %p, iid %s, out %p.\n", iface, debugstr_guid(iid), out);
- if (IsEqualGUID(iid, &IID_ID3DDeviceContextState)
|| IsEqualGUID(iid, &IID_ID3D11DeviceChild)
|| IsEqualGUID(iid, &IID_IUnknown))
- {
*out = &state->ID3DDeviceContextState_iface;
- }
- else
- {
WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid));
*out = NULL;
return E_NOINTERFACE;
- }
- ID3DDeviceContextState_AddRef(iface);
- return S_OK;
+}
This can be simplified; you don't need the "state" variable.
+static ULONG STDMETHODCALLTYPE d3d_device_context_state_AddRef(ID3DDeviceContextState *iface) +{
- struct d3d_device_context_state *state = impl_from_ID3DDeviceContextState(iface);
- struct d3d_device *device = device_from_ID3DDeviceContextState(iface);
- ULONG refcount = InterlockedIncrement(&state->refcount);
- TRACE("%p increasing refcount to %u.\n", state, refcount);
- if (refcount == 1)
- {
ID3D11Device2_AddRef(&device->ID3D11Device2_iface);
- }
Can this happen?
+static ULONG STDMETHODCALLTYPE d3d_device_context_state_Release(ID3DDeviceContextState *iface) +{
- struct d3d_device_context_state *state = impl_from_ID3DDeviceContextState(iface);
- struct d3d_device *device = device_from_ID3DDeviceContextState(iface);
- ULONG refcount = InterlockedDecrement(&state->refcount);
- TRACE("%p decreasing refcount to %u.\n", state, refcount);
- if (!refcount)
- {
wined3d_private_store_cleanup(&state->private_store);
ID3D11Device2_Release(&device->ID3D11Device2_iface);
- }
- return refcount;
+}
You leak the "state" object here.
+static void STDMETHODCALLTYPE d3d_device_context_state_GetDevice(ID3DDeviceContextState *iface, ID3D11Device **device) +{
- struct d3d_device *device_object = device_from_ID3DDeviceContextState(iface);
- TRACE("iface %p, device %p.\n", iface, device);
- *device = (ID3D11Device *)&device_object->ID3D11Device2_iface;
- ID3D11Device_AddRef(*device);
+}
"*device = (ID3D11Device *)state->device;"
On 1/25/21 3:08 PM, Henri Verbeet wrote:
On Thu, 21 Jan 2021 at 20:13, Rémi Bernon rbernon@codeweavers.com wrote:
+static inline struct d3d_device *device_from_ID3DDeviceContextState(ID3DDeviceContextState *iface) +{
- struct d3d_device_context_state *state = impl_from_ID3DDeviceContextState(iface);
- return impl_from_ID3D11Device2(state->device);
+}
You don't need this. For example, in d3d_device_context_state_AddRef(), you could simply do:
ID3D11Device2_AddRef(state->device);
+static HRESULT STDMETHODCALLTYPE d3d_device_context_state_QueryInterface(ID3DDeviceContextState *iface,
REFIID iid, void **out)
+{
- struct d3d_device_context_state *state = impl_from_ID3DDeviceContextState(iface);
- TRACE("iface %p, iid %s, out %p.\n", iface, debugstr_guid(iid), out);
- if (IsEqualGUID(iid, &IID_ID3DDeviceContextState)
|| IsEqualGUID(iid, &IID_ID3D11DeviceChild)
|| IsEqualGUID(iid, &IID_IUnknown))
- {
*out = &state->ID3DDeviceContextState_iface;
- }
- else
- {
WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid));
*out = NULL;
return E_NOINTERFACE;
- }
- ID3DDeviceContextState_AddRef(iface);
- return S_OK;
+}
This can be simplified; you don't need the "state" variable.
+static ULONG STDMETHODCALLTYPE d3d_device_context_state_AddRef(ID3DDeviceContextState *iface) +{
- struct d3d_device_context_state *state = impl_from_ID3DDeviceContextState(iface);
- struct d3d_device *device = device_from_ID3DDeviceContextState(iface);
- ULONG refcount = InterlockedIncrement(&state->refcount);
- TRACE("%p increasing refcount to %u.\n", state, refcount);
- if (refcount == 1)
- {
ID3D11Device2_AddRef(&device->ID3D11Device2_iface);
- }
Can this happen?
+static ULONG STDMETHODCALLTYPE d3d_device_context_state_Release(ID3DDeviceContextState *iface) +{
- struct d3d_device_context_state *state = impl_from_ID3DDeviceContextState(iface);
- struct d3d_device *device = device_from_ID3DDeviceContextState(iface);
- ULONG refcount = InterlockedDecrement(&state->refcount);
- TRACE("%p decreasing refcount to %u.\n", state, refcount);
- if (!refcount)
- {
wined3d_private_store_cleanup(&state->private_store);
ID3D11Device2_Release(&device->ID3D11Device2_iface);
- }
- return refcount;
+}
You leak the "state" object here.
+static void STDMETHODCALLTYPE d3d_device_context_state_GetDevice(ID3DDeviceContextState *iface, ID3D11Device **device) +{
- struct d3d_device *device_object = device_from_ID3DDeviceContextState(iface);
- TRACE("iface %p, device %p.\n", iface, device);
- *device = (ID3D11Device *)&device_object->ID3D11Device2_iface;
- ID3D11Device_AddRef(*device);
+}
"*device = (ID3D11Device *)state->device;"
Ah yes sorry, I'm stupid. All this was with a different implementation in mind where the state was a member of device / device context and not a free object... I've refactored it later and then forgot to update these base methods.