dxgi: Do not store IDXGIAdapters in IDXGIFactory.

Signed-off-by: Józef Kucia <jkucia@codeweavers.com>
Signed-off-by: Henri Verbeet <hverbeet@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Józef Kucia 2016-04-14 12:20:23 +02:00 committed by Alexandre Julliard
parent 25ad11cef7
commit eb039240e5
5 changed files with 50 additions and 77 deletions

View File

@ -69,6 +69,7 @@ static ULONG STDMETHODCALLTYPE dxgi_adapter_Release(IDXGIAdapter1 *iface)
if (!refcount)
{
wined3d_private_store_cleanup(&adapter->private_store);
IDXGIFactory1_Release(&adapter->factory->IDXGIFactory1_iface);
HeapFree(GetProcessHeap(), 0, adapter);
}
@ -109,9 +110,9 @@ static HRESULT STDMETHODCALLTYPE dxgi_adapter_GetParent(IDXGIAdapter1 *iface, RE
{
struct dxgi_adapter *adapter = impl_from_IDXGIAdapter1(iface);
TRACE("iface %p, iid %s, parent %p\n", iface, debugstr_guid(iid), parent);
TRACE("iface %p, iid %s, parent %p.\n", iface, debugstr_guid(iid), parent);
return IDXGIFactory1_QueryInterface(&adapter->parent->IDXGIFactory1_iface, iid, parent);
return IDXGIFactory1_QueryInterface(&adapter->factory->IDXGIFactory1_iface, iid, parent);
}
static HRESULT STDMETHODCALLTYPE dxgi_adapter_EnumOutputs(IDXGIAdapter1 *iface,
@ -160,7 +161,7 @@ static HRESULT STDMETHODCALLTYPE dxgi_adapter_GetDesc1(IDXGIAdapter1 *iface, DXG
adapter_id.device_name_size = 0;
wined3d_mutex_lock();
hr = wined3d_get_adapter_identifier(adapter->parent->wined3d, adapter->ordinal, 0, &adapter_id);
hr = wined3d_get_adapter_identifier(adapter->factory->wined3d, adapter->ordinal, 0, &adapter_id);
wined3d_mutex_unlock();
if (FAILED(hr))
@ -221,7 +222,7 @@ static HRESULT STDMETHODCALLTYPE dxgi_adapter_CheckInterfaceSupport(IDXGIAdapter
return DXGI_ERROR_UNSUPPORTED;
}
if (!dxgi_check_feature_level_support(adapter->parent, adapter, &feature_level, 1))
if (!dxgi_check_feature_level_support(adapter->factory, adapter, &feature_level, 1))
return DXGI_ERROR_UNSUPPORTED;
if (umd_version)
@ -231,7 +232,7 @@ static HRESULT STDMETHODCALLTYPE dxgi_adapter_CheckInterfaceSupport(IDXGIAdapter
adapter_id.device_name_size = 0;
wined3d_mutex_lock();
hr = wined3d_get_adapter_identifier(adapter->parent->wined3d, adapter->ordinal, 0, &adapter_id);
hr = wined3d_get_adapter_identifier(adapter->factory->wined3d, adapter->ordinal, 0, &adapter_id);
wined3d_mutex_unlock();
if (FAILED(hr))
return hr;
@ -265,11 +266,21 @@ struct dxgi_adapter *unsafe_impl_from_IDXGIAdapter1(IDXGIAdapter1 *iface)
return CONTAINING_RECORD(iface, struct dxgi_adapter, IDXGIAdapter1_iface);
}
void dxgi_adapter_init(struct dxgi_adapter *adapter, struct dxgi_factory *parent, UINT ordinal)
static void dxgi_adapter_init(struct dxgi_adapter *adapter, struct dxgi_factory *factory, UINT ordinal)
{
adapter->IDXGIAdapter1_iface.lpVtbl = &dxgi_adapter_vtbl;
adapter->parent = parent;
adapter->refcount = 1;
wined3d_private_store_init(&adapter->private_store);
adapter->ordinal = ordinal;
adapter->factory = factory;
IDXGIFactory1_AddRef(&adapter->factory->IDXGIFactory1_iface);
}
HRESULT dxgi_adapter_create(struct dxgi_factory *factory, UINT ordinal, struct dxgi_adapter **adapter)
{
if (!(*adapter = HeapAlloc(GetProcessHeap(), 0, sizeof(**adapter))))
return E_OUTOFMEMORY;
dxgi_adapter_init(*adapter, factory, ordinal);
return S_OK;
}

View File

@ -100,8 +100,6 @@ struct dxgi_factory
LONG refcount;
struct wined3d_private_store private_store;
struct wined3d *wined3d;
UINT adapter_count;
IDXGIAdapter1 **adapters;
BOOL extended;
HWND device_window;
};
@ -141,13 +139,14 @@ HRESULT dxgi_output_create(struct dxgi_adapter *adapter, struct dxgi_output **ou
struct dxgi_adapter
{
IDXGIAdapter1 IDXGIAdapter1_iface;
struct dxgi_factory *parent;
LONG refcount;
struct wined3d_private_store private_store;
UINT ordinal;
struct dxgi_factory *factory;
};
void dxgi_adapter_init(struct dxgi_adapter *adapter, struct dxgi_factory *parent, UINT ordinal) DECLSPEC_HIDDEN;
HRESULT dxgi_adapter_create(struct dxgi_factory *factory, UINT ordinal,
struct dxgi_adapter **adapter) DECLSPEC_HIDDEN;
struct dxgi_adapter *unsafe_impl_from_IDXGIAdapter1(IDXGIAdapter1 *iface) DECLSPEC_HIDDEN;
/* IDXGISwapChain */

View File

@ -70,15 +70,8 @@ static ULONG STDMETHODCALLTYPE dxgi_factory_Release(IDXGIFactory1 *iface)
if (!refcount)
{
UINT i;
if (factory->device_window)
DestroyWindow(factory->device_window);
for (i = 0; i < factory->adapter_count; ++i)
{
IDXGIAdapter1_Release(factory->adapters[i]);
}
HeapFree(GetProcessHeap(), 0, factory->adapters);
wined3d_mutex_lock();
wined3d_decref(factory->wined3d);
@ -133,20 +126,32 @@ static HRESULT STDMETHODCALLTYPE dxgi_factory_EnumAdapters1(IDXGIFactory1 *iface
UINT adapter_idx, IDXGIAdapter1 **adapter)
{
struct dxgi_factory *factory = impl_from_IDXGIFactory1(iface);
struct dxgi_adapter *adapter_object;
UINT adapter_count;
HRESULT hr;
TRACE("iface %p, adapter_idx %u, adapter %p.\n", iface, adapter_idx, adapter);
if (!adapter)
return DXGI_ERROR_INVALID_CALL;
if (adapter_idx >= factory->adapter_count)
wined3d_mutex_lock();
adapter_count = wined3d_get_adapter_count(factory->wined3d);
wined3d_mutex_unlock();
if (adapter_idx >= adapter_count)
{
*adapter = NULL;
return DXGI_ERROR_NOT_FOUND;
}
*adapter = (IDXGIAdapter1 *)factory->adapters[adapter_idx];
IDXGIAdapter1_AddRef(*adapter);
if (FAILED(hr = dxgi_adapter_create(factory, adapter_idx, &adapter_object)))
{
*adapter = NULL;
return hr;
}
*adapter = &adapter_object->IDXGIAdapter1_iface;
TRACE("Returning adapter %p.\n", *adapter);
@ -304,64 +309,22 @@ struct dxgi_factory *unsafe_impl_from_IDXGIFactory1(IDXGIFactory1 *iface)
static HRESULT dxgi_factory_init(struct dxgi_factory *factory, BOOL extended)
{
HRESULT hr;
UINT i;
factory->IDXGIFactory1_iface.lpVtbl = &dxgi_factory_vtbl;
factory->refcount = 1;
wined3d_private_store_init(&factory->private_store);
wined3d_mutex_lock();
factory->wined3d = wined3d_create(0);
wined3d_mutex_unlock();
if (!factory->wined3d)
{
wined3d_mutex_unlock();
wined3d_private_store_cleanup(&factory->private_store);
return DXGI_ERROR_UNSUPPORTED;
}
factory->adapter_count = wined3d_get_adapter_count(factory->wined3d);
wined3d_mutex_unlock();
factory->adapters = HeapAlloc(GetProcessHeap(), 0, factory->adapter_count * sizeof(*factory->adapters));
if (!factory->adapters)
{
ERR("Failed to allocate DXGI adapter array memory.\n");
hr = E_OUTOFMEMORY;
goto fail;
}
for (i = 0; i < factory->adapter_count; ++i)
{
struct dxgi_adapter *adapter = HeapAlloc(GetProcessHeap(), 0, sizeof(*adapter));
if (!adapter)
{
UINT j;
ERR("Failed to allocate DXGI adapter memory.\n");
for (j = 0; j < i; ++j)
{
IDXGIAdapter1_Release(factory->adapters[j]);
}
hr = E_OUTOFMEMORY;
goto fail;
}
dxgi_adapter_init(adapter, factory, i);
factory->adapters[i] = &adapter->IDXGIAdapter1_iface;
}
factory->extended = extended;
return S_OK;
fail:
HeapFree(GetProcessHeap(), 0, factory->adapters);
wined3d_mutex_lock();
wined3d_decref(factory->wined3d);
wined3d_mutex_unlock();
wined3d_private_store_cleanup(&factory->private_store);
return hr;
}
HRESULT dxgi_factory_create(REFIID riid, void **factory, BOOL extended)

View File

@ -132,7 +132,7 @@ static HRESULT STDMETHODCALLTYPE dxgi_output_GetDesc(IDXGIOutput *iface, DXGI_OU
return E_INVALIDARG;
wined3d_mutex_lock();
hr = wined3d_get_output_desc(output->adapter->parent->wined3d,
hr = wined3d_get_output_desc(output->adapter->factory->wined3d,
output->adapter->ordinal, &wined3d_desc);
wined3d_mutex_unlock();
@ -172,7 +172,7 @@ static HRESULT STDMETHODCALLTYPE dxgi_output_GetDisplayModeList(IDXGIOutput *ifa
return S_OK;
}
wined3d = This->adapter->parent->wined3d;
wined3d = This->adapter->factory->wined3d;
wined3d_format = wined3dformat_from_dxgi_format(format);
wined3d_mutex_lock();

View File

@ -467,7 +467,7 @@ static void test_create_swapchain(void)
expected_refcount = get_refcount((IUnknown *)adapter);
refcount = get_refcount((IUnknown *)factory);
ok(refcount == 2, "Got unexpected refcount %u.\n", refcount);
todo_wine ok(refcount == 2, "Got unexpected refcount %u.\n", refcount);
refcount = get_refcount((IUnknown *)device);
ok(refcount == 2, "Got unexpected refcount %u.\n", refcount);
@ -499,7 +499,7 @@ static void test_create_swapchain(void)
IDXGISwapChain_Release(swapchain);
refcount = get_refcount((IUnknown *)factory);
ok(refcount == 2, "Got unexpected refcount %u.\n", refcount);
todo_wine ok(refcount == 2, "Got unexpected refcount %u.\n", refcount);
for (i = 0; i < sizeof(refresh_list)/sizeof(refresh_list[0]); i++)
{
@ -554,7 +554,7 @@ static void test_create_swapchain(void)
refcount = IDXGIDevice_Release(device);
ok(!refcount, "Device has %u references left.\n", refcount);
refcount = IDXGIAdapter_Release(adapter);
todo_wine ok(!refcount, "Adapter has %u references left.\n", refcount);
ok(!refcount, "Adapter has %u references left.\n", refcount);
refcount = IDXGIFactory_Release(factory);
ok(!refcount, "Factory has %u references left.\n", refcount);
DestroyWindow(creation_desc.OutputWindow);
@ -668,7 +668,7 @@ done:
refcount = IDXGIDevice_Release(device);
ok(!refcount, "Device has %u references left.\n", refcount);
refcount = IDXGIAdapter_Release(adapter);
todo_wine ok(!refcount, "Adapter has %u references left.\n", refcount);
ok(!refcount, "Adapter has %u references left.\n", refcount);
refcount = IDXGIFactory_Release(factory);
ok(!refcount, "Factory has %u references left.\n", refcount);
DestroyWindow(swapchain_desc.OutputWindow);
@ -1448,15 +1448,15 @@ static void test_output_desc(void)
hr = IDXGIFactory_EnumAdapters(factory, i, &adapter2);
ok(SUCCEEDED(hr), "Failed to enumerate adapter %u, hr %#x.\n", i, hr);
todo_wine ok(adapter != adapter2, "Expected to get new instance of IDXGIAdapter, %p == %p.\n", adapter, adapter2);
ok(adapter != adapter2, "Expected to get new instance of IDXGIAdapter, %p == %p.\n", adapter, adapter2);
refcount = get_refcount((IUnknown *)adapter);
todo_wine ok(refcount == 1, "Get unexpected refcount %u for adapter %u.\n", refcount, i);
ok(refcount == 1, "Get unexpected refcount %u for adapter %u.\n", refcount, i);
IDXGIAdapter_Release(adapter2);
refcount = get_refcount((IUnknown *)factory);
todo_wine ok(refcount == 2, "Get unexpected refcount %u.\n", refcount);
ok(refcount == 2, "Get unexpected refcount %u.\n", refcount);
refcount = get_refcount((IUnknown *)adapter);
todo_wine ok(refcount == 1, "Get unexpected refcount %u for adapter %u.\n", refcount, i);
ok(refcount == 1, "Get unexpected refcount %u for adapter %u.\n", refcount, i);
for (j = 0; ; ++j)
{
@ -1476,9 +1476,9 @@ static void test_output_desc(void)
IDXGIOutput_Release(output2);
refcount = get_refcount((IUnknown *)factory);
todo_wine ok(refcount == 2, "Get unexpected refcount %u.\n", refcount);
ok(refcount == 2, "Get unexpected refcount %u.\n", refcount);
refcount = get_refcount((IUnknown *)adapter);
todo_wine ok(refcount == 2, "Get unexpected refcount %u for adapter %u.\n", refcount, i);
ok(refcount == 2, "Get unexpected refcount %u for adapter %u.\n", refcount, i);
refcount = get_refcount((IUnknown *)output);
ok(refcount == 1, "Get unexpected refcount %u for output %u, adapter %u.\n", refcount, j, i);
@ -1501,7 +1501,7 @@ static void test_output_desc(void)
IDXGIOutput_Release(output);
refcount = get_refcount((IUnknown *)adapter);
todo_wine ok(refcount == 1, "Get unexpected refcount %u for adapter %u.\n", refcount, i);
ok(refcount == 1, "Get unexpected refcount %u for adapter %u.\n", refcount, i);
}
IDXGIAdapter_Release(adapter);