On 1/25/21 3:08 PM, Henri Verbeet wrote:
On Thu, 21 Jan 2021 at 20:13, Rémi Bernon <rbernon(a)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. -- Rémi Bernon <rbernon(a)codeweavers.com>