d3d11: Create an initial device ID3DDeviceContextState.
And use its emulated_interface. This adds a private_refcount to track hidden references, and a reference to the wined3d_device, to keep the d3d_device alive while not publicly referencing it. This uses d3d_device_context_state_AddRef on init so that the initial references are also traced, making it easier to verify that nothing is leaked. Signed-off-by: Rémi Bernon <rbernon@codeweavers.com> Signed-off-by: Henri Verbeet <hverbeet@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
bde070fcf4
commit
943d48896e
|
@ -137,7 +137,6 @@ HRESULT WINAPI D3D11CoreCreateDevice(IDXGIFactory *factory, IDXGIAdapter *adapte
|
||||||
return E_FAIL;
|
return E_FAIL;
|
||||||
}
|
}
|
||||||
d3d_device->d3d11_only = TRUE;
|
d3d_device->d3d11_only = TRUE;
|
||||||
d3d_device->emulated_interface = IID_ID3D11Device2;
|
|
||||||
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
|
@ -520,7 +520,7 @@ struct d3d_query *unsafe_impl_from_ID3D11Asynchronous(ID3D11Asynchronous *iface)
|
||||||
struct d3d_device_context_state
|
struct d3d_device_context_state
|
||||||
{
|
{
|
||||||
ID3DDeviceContextState ID3DDeviceContextState_iface;
|
ID3DDeviceContextState ID3DDeviceContextState_iface;
|
||||||
LONG refcount;
|
LONG refcount, private_refcount;
|
||||||
|
|
||||||
struct wined3d_private_store private_store;
|
struct wined3d_private_store private_store;
|
||||||
struct
|
struct
|
||||||
|
@ -546,6 +546,8 @@ struct d3d_device_context_state
|
||||||
} ps;
|
} ps;
|
||||||
|
|
||||||
GUID emulated_interface;
|
GUID emulated_interface;
|
||||||
|
|
||||||
|
struct wined3d_device *wined3d_device;
|
||||||
ID3D11Device2 *device;
|
ID3D11Device2 *device;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -572,8 +574,8 @@ struct d3d_device
|
||||||
|
|
||||||
D3D_FEATURE_LEVEL feature_level;
|
D3D_FEATURE_LEVEL feature_level;
|
||||||
BOOL d3d11_only;
|
BOOL d3d11_only;
|
||||||
GUID emulated_interface;
|
|
||||||
|
|
||||||
|
struct d3d_device_context_state *state;
|
||||||
struct d3d11_immediate_context immediate_context;
|
struct d3d11_immediate_context immediate_context;
|
||||||
|
|
||||||
struct wined3d_device_parent device_parent;
|
struct wined3d_device_parent device_parent;
|
||||||
|
|
|
@ -31,8 +31,9 @@ static const struct wined3d_parent_ops d3d_null_wined3d_parent_ops =
|
||||||
|
|
||||||
static inline BOOL d3d_device_is_d3d10_active(struct d3d_device *device)
|
static inline BOOL d3d_device_is_d3d10_active(struct d3d_device *device)
|
||||||
{
|
{
|
||||||
return IsEqualGUID(&device->emulated_interface, &IID_ID3D10Device)
|
return !device->state
|
||||||
|| IsEqualGUID(&device->emulated_interface, &IID_ID3D10Device1);
|
|| IsEqualGUID(&device->state->emulated_interface, &IID_ID3D10Device)
|
||||||
|
|| IsEqualGUID(&device->state->emulated_interface, &IID_ID3D10Device1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ID3DDeviceContextState methods */
|
/* ID3DDeviceContextState methods */
|
||||||
|
@ -62,6 +63,15 @@ static HRESULT STDMETHODCALLTYPE d3d_device_context_state_QueryInterface(ID3DDev
|
||||||
return E_NOINTERFACE;
|
return E_NOINTERFACE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static ULONG d3d_device_context_state_private_addref(struct d3d_device_context_state *state)
|
||||||
|
{
|
||||||
|
ULONG refcount = InterlockedIncrement(&state->private_refcount);
|
||||||
|
|
||||||
|
TRACE("%p increasing private refcount to %u.\n", state, refcount);
|
||||||
|
|
||||||
|
return refcount;
|
||||||
|
}
|
||||||
|
|
||||||
static ULONG STDMETHODCALLTYPE d3d_device_context_state_AddRef(ID3DDeviceContextState *iface)
|
static ULONG STDMETHODCALLTYPE d3d_device_context_state_AddRef(ID3DDeviceContextState *iface)
|
||||||
{
|
{
|
||||||
struct d3d_device_context_state *state = impl_from_ID3DDeviceContextState(iface);
|
struct d3d_device_context_state *state = impl_from_ID3DDeviceContextState(iface);
|
||||||
|
@ -69,16 +79,21 @@ static ULONG STDMETHODCALLTYPE d3d_device_context_state_AddRef(ID3DDeviceContext
|
||||||
|
|
||||||
TRACE("%p increasing refcount to %u.\n", state, refcount);
|
TRACE("%p increasing refcount to %u.\n", state, refcount);
|
||||||
|
|
||||||
|
if (refcount == 1)
|
||||||
|
{
|
||||||
|
d3d_device_context_state_private_addref(state);
|
||||||
|
ID3D11Device2_AddRef(state->device);
|
||||||
|
}
|
||||||
|
|
||||||
return refcount;
|
return refcount;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ULONG STDMETHODCALLTYPE d3d_device_context_state_Release(ID3DDeviceContextState *iface)
|
static void d3d_device_context_state_private_release(struct d3d_device_context_state *state)
|
||||||
{
|
{
|
||||||
struct d3d_device_context_state *state = impl_from_ID3DDeviceContextState(iface);
|
ULONG refcount = InterlockedDecrement(&state->private_refcount);
|
||||||
ULONG refcount = InterlockedDecrement(&state->refcount);
|
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
TRACE("%p decreasing refcount to %u.\n", state, refcount);
|
TRACE("%p decreasing private refcount to %u.\n", state, refcount);
|
||||||
|
|
||||||
if (!refcount)
|
if (!refcount)
|
||||||
{
|
{
|
||||||
|
@ -104,9 +119,23 @@ static ULONG STDMETHODCALLTYPE d3d_device_context_state_Release(ID3DDeviceContex
|
||||||
if (state->gs.cbs[i]) ID3D11Buffer_Release(state->gs.cbs[i]);
|
if (state->gs.cbs[i]) ID3D11Buffer_Release(state->gs.cbs[i]);
|
||||||
if (state->ps.cbs[i]) ID3D11Buffer_Release(state->ps.cbs[i]);
|
if (state->ps.cbs[i]) ID3D11Buffer_Release(state->ps.cbs[i]);
|
||||||
}
|
}
|
||||||
ID3D11Device2_Release(state->device);
|
wined3d_device_decref(state->wined3d_device);
|
||||||
heap_free(state);
|
heap_free(state);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static ULONG STDMETHODCALLTYPE d3d_device_context_state_Release(ID3DDeviceContextState *iface)
|
||||||
|
{
|
||||||
|
struct d3d_device_context_state *state = impl_from_ID3DDeviceContextState(iface);
|
||||||
|
ULONG refcount = InterlockedDecrement(&state->refcount);
|
||||||
|
|
||||||
|
TRACE("%p decreasing refcount to %u.\n", state, refcount);
|
||||||
|
|
||||||
|
if (!refcount)
|
||||||
|
{
|
||||||
|
ID3D11Device2_Release(state->device);
|
||||||
|
d3d_device_context_state_private_release(state);
|
||||||
|
}
|
||||||
|
|
||||||
return refcount;
|
return refcount;
|
||||||
}
|
}
|
||||||
|
@ -169,7 +198,7 @@ static void d3d_device_context_state_init(struct d3d_device_context_state *state
|
||||||
REFIID emulated_interface)
|
REFIID emulated_interface)
|
||||||
{
|
{
|
||||||
state->ID3DDeviceContextState_iface.lpVtbl = &d3d_device_context_state_vtbl;
|
state->ID3DDeviceContextState_iface.lpVtbl = &d3d_device_context_state_vtbl;
|
||||||
state->refcount = 1;
|
state->refcount = state->private_refcount = 0;
|
||||||
|
|
||||||
wined3d_private_store_init(&state->private_store);
|
wined3d_private_store_init(&state->private_store);
|
||||||
memset(&state->vs, 0, sizeof(state->vs));
|
memset(&state->vs, 0, sizeof(state->vs));
|
||||||
|
@ -177,8 +206,10 @@ static void d3d_device_context_state_init(struct d3d_device_context_state *state
|
||||||
memset(&state->ps, 0, sizeof(state->ps));
|
memset(&state->ps, 0, sizeof(state->ps));
|
||||||
|
|
||||||
state->emulated_interface = *emulated_interface;
|
state->emulated_interface = *emulated_interface;
|
||||||
|
wined3d_device_incref(state->wined3d_device = device->wined3d_device);
|
||||||
state->device = &device->ID3D11Device2_iface;
|
state->device = &device->ID3D11Device2_iface;
|
||||||
ID3D11Device2_AddRef(state->device);
|
|
||||||
|
d3d_device_context_state_AddRef(&state->ID3DDeviceContextState_iface);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ID3D11DeviceContext - immediate context methods */
|
/* ID3D11DeviceContext - immediate context methods */
|
||||||
|
@ -2770,7 +2801,7 @@ static void STDMETHODCALLTYPE d3d11_immediate_context_SwapDeviceContextState(ID3
|
||||||
*prev_state = NULL;
|
*prev_state = NULL;
|
||||||
if ((state_impl = heap_alloc(sizeof(*state_impl))))
|
if ((state_impl = heap_alloc(sizeof(*state_impl))))
|
||||||
{
|
{
|
||||||
d3d_device_context_state_init(state_impl, device, &device->emulated_interface);
|
d3d_device_context_state_init(state_impl, device, &device->state->emulated_interface);
|
||||||
d3d11_immediate_context_capture_state(iface, state_impl);
|
d3d11_immediate_context_capture_state(iface, state_impl);
|
||||||
*prev_state = &state_impl->ID3DDeviceContextState_iface;
|
*prev_state = &state_impl->ID3DDeviceContextState_iface;
|
||||||
}
|
}
|
||||||
|
@ -2779,7 +2810,7 @@ static void STDMETHODCALLTYPE d3d11_immediate_context_SwapDeviceContextState(ID3
|
||||||
if ((state_impl = impl_from_ID3DDeviceContextState(state)))
|
if ((state_impl = impl_from_ID3DDeviceContextState(state)))
|
||||||
{
|
{
|
||||||
d3d11_immediate_context_restore_state(iface, state_impl);
|
d3d11_immediate_context_restore_state(iface, state_impl);
|
||||||
device->emulated_interface = state_impl->emulated_interface;
|
device->state->emulated_interface = state_impl->emulated_interface;
|
||||||
if (d3d_device_is_d3d10_active(device))
|
if (d3d_device_is_d3d10_active(device))
|
||||||
FIXME("D3D10 interface emulation not fully implemented yet!\n");
|
FIXME("D3D10 interface emulation not fully implemented yet!\n");
|
||||||
}
|
}
|
||||||
|
@ -4175,6 +4206,7 @@ static ULONG STDMETHODCALLTYPE d3d_device_inner_Release(IUnknown *iface)
|
||||||
|
|
||||||
if (!refcount)
|
if (!refcount)
|
||||||
{
|
{
|
||||||
|
if (device->state) d3d_device_context_state_private_release(device->state);
|
||||||
d3d11_immediate_context_destroy(&device->immediate_context);
|
d3d11_immediate_context_destroy(&device->immediate_context);
|
||||||
if (device->wined3d_device)
|
if (device->wined3d_device)
|
||||||
{
|
{
|
||||||
|
@ -6352,6 +6384,8 @@ static void CDECL device_parent_wined3d_device_created(struct wined3d_device_par
|
||||||
struct wined3d_device *wined3d_device)
|
struct wined3d_device *wined3d_device)
|
||||||
{
|
{
|
||||||
struct d3d_device *device = device_from_wined3d_device_parent(device_parent);
|
struct d3d_device *device = device_from_wined3d_device_parent(device_parent);
|
||||||
|
ID3DDeviceContextState *state;
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
TRACE("device_parent %p, wined3d_device %p.\n", device_parent, wined3d_device);
|
TRACE("device_parent %p, wined3d_device %p.\n", device_parent, wined3d_device);
|
||||||
|
|
||||||
|
@ -6359,6 +6393,17 @@ static void CDECL device_parent_wined3d_device_created(struct wined3d_device_par
|
||||||
device->wined3d_device = wined3d_device;
|
device->wined3d_device = wined3d_device;
|
||||||
|
|
||||||
device->feature_level = d3d_feature_level_from_wined3d(wined3d_device_get_feature_level(wined3d_device));
|
device->feature_level = d3d_feature_level_from_wined3d(wined3d_device_get_feature_level(wined3d_device));
|
||||||
|
|
||||||
|
if (FAILED(hr = d3d11_device_CreateDeviceContextState(&device->ID3D11Device2_iface, 0, &device->feature_level,
|
||||||
|
1, D3D11_SDK_VERSION, device->d3d11_only ? &IID_ID3D11Device2 : &IID_ID3D10Device1, NULL,
|
||||||
|
&state)))
|
||||||
|
ERR("Failed to create the initial device context state, hr %#x.\n", hr);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
device->state = impl_from_ID3DDeviceContextState(state);
|
||||||
|
d3d_device_context_state_private_addref(device->state);
|
||||||
|
ID3DDeviceContextState_Release(state);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void CDECL device_parent_mode_changed(struct wined3d_device_parent *device_parent)
|
static void CDECL device_parent_mode_changed(struct wined3d_device_parent *device_parent)
|
||||||
|
@ -6488,7 +6533,7 @@ void d3d_device_init(struct d3d_device *device, void *outer_unknown)
|
||||||
/* COM aggregation always takes place */
|
/* COM aggregation always takes place */
|
||||||
device->outer_unk = outer_unknown;
|
device->outer_unk = outer_unknown;
|
||||||
device->d3d11_only = FALSE;
|
device->d3d11_only = FALSE;
|
||||||
device->emulated_interface = GUID_NULL;
|
device->state = NULL;
|
||||||
|
|
||||||
d3d11_immediate_context_init(&device->immediate_context, device);
|
d3d11_immediate_context_init(&device->immediate_context, device);
|
||||||
ID3D11DeviceContext1_Release(&device->immediate_context.ID3D11DeviceContext1_iface);
|
ID3D11DeviceContext1_Release(&device->immediate_context.ID3D11DeviceContext1_iface);
|
||||||
|
|
Loading…
Reference in New Issue