Commit 15b6bc61 authored by Henri Verbeet's avatar Henri Verbeet Committed by Alexandre Julliard

dxgi: Add a separate function for device initialization.

parent ccbcf8f2
......@@ -312,7 +312,7 @@ static HRESULT STDMETHODCALLTYPE dxgi_device_create_swapchain(IWineDXGIDevice *i
return S_OK;
}
const struct IWineDXGIDeviceVtbl dxgi_device_vtbl =
static const struct IWineDXGIDeviceVtbl dxgi_device_vtbl =
{
/* IUnknown methods */
dxgi_device_QueryInterface,
......@@ -334,3 +334,80 @@ const struct IWineDXGIDeviceVtbl dxgi_device_vtbl =
dxgi_device_create_surface,
dxgi_device_create_swapchain,
};
HRESULT dxgi_device_init(struct dxgi_device *device, struct dxgi_device_layer *layer,
IDXGIFactory *factory, IDXGIAdapter *adapter)
{
IWineD3DDeviceParent *wined3d_device_parent;
IWineDXGIAdapter *wine_adapter;
UINT adapter_ordinal;
IWineD3D *wined3d;
void *layer_base;
HRESULT hr;
device->vtbl = &dxgi_device_vtbl;
device->refcount = 1;
layer_base = device + 1;
hr = layer->create(layer->id, &layer_base, 0,
device, &IID_IUnknown, (void **)&device->child_layer);
if (FAILED(hr))
{
WARN("Failed to create device, returning %#x.\n", hr);
goto fail;
}
hr = IDXGIFactory_QueryInterface(factory, &IID_IWineDXGIFactory, (void **)&device->factory);
if (FAILED(hr))
{
WARN("This is not the factory we're looking for, returning %#x.\n", hr);
goto fail;
}
wined3d = IWineDXGIFactory_get_wined3d(device->factory);
hr = IDXGIAdapter_QueryInterface(adapter, &IID_IWineDXGIAdapter, (void **)&wine_adapter);
if (FAILED(hr))
{
WARN("This is not the adapter we're looking for, returning %#x.\n", hr);
EnterCriticalSection(&dxgi_cs);
IWineD3D_Release(wined3d);
LeaveCriticalSection(&dxgi_cs);
goto fail;
}
adapter_ordinal = IWineDXGIAdapter_get_ordinal(wine_adapter);
IWineDXGIAdapter_Release(wine_adapter);
hr = IUnknown_QueryInterface((IUnknown *)device, &IID_IWineD3DDeviceParent, (void **)&wined3d_device_parent);
if (FAILED(hr))
{
ERR("DXGI device should implement IWineD3DDeviceParent.\n");
goto fail;
}
FIXME("Ignoring adapter type.\n");
EnterCriticalSection(&dxgi_cs);
hr = IWineD3D_CreateDevice(wined3d, adapter_ordinal, WINED3DDEVTYPE_HAL, NULL, 0,
(IUnknown *)device, wined3d_device_parent, &device->wined3d_device);
IWineD3DDeviceParent_Release(wined3d_device_parent);
IWineD3D_Release(wined3d);
LeaveCriticalSection(&dxgi_cs);
if (FAILED(hr))
{
WARN("Failed to create a wined3d device, returning %#x.\n", hr);
goto fail;
}
return S_OK;
fail:
if (device->wined3d_device)
{
EnterCriticalSection(&dxgi_cs);
IWineD3DDevice_Release(device->wined3d_device);
LeaveCriticalSection(&dxgi_cs);
}
if (device->factory) IWineDXGIFactory_Release(device->factory);
if (device->child_layer) IUnknown_Release(device->child_layer);
return hr;
}
......@@ -226,14 +226,9 @@ static HRESULT register_d3d10core_layers(HMODULE d3d10core)
HRESULT WINAPI DXGID3D10CreateDevice(HMODULE d3d10core, IDXGIFactory *factory, IDXGIAdapter *adapter,
UINT flags, DWORD unknown0, void **device)
{
IWineD3DDeviceParent *wined3d_device_parent;
struct layer_get_size_args get_size_args;
struct dxgi_device *dxgi_device;
struct dxgi_device_layer d3d10_layer;
IWineDXGIAdapter *wine_adapter;
UINT adapter_ordinal;
IWineD3D *wined3d;
void *layer_base;
UINT device_size;
DWORD count;
HRESULT hr;
......@@ -282,75 +277,19 @@ HRESULT WINAPI DXGID3D10CreateDevice(HMODULE d3d10core, IDXGIFactory *factory, I
return E_OUTOFMEMORY;
}
dxgi_device->vtbl = &dxgi_device_vtbl;
dxgi_device->refcount = 1;
layer_base = dxgi_device + 1;
hr = d3d10_layer.create(d3d10_layer.id, &layer_base, 0,
dxgi_device, &IID_IUnknown, (void **)&dxgi_device->child_layer);
if (FAILED(hr))
{
WARN("Failed to create device, returning %#x\n", hr);
goto fail;
}
hr = IDXGIFactory_QueryInterface(factory, &IID_IWineDXGIFactory, (void **)&dxgi_device->factory);
if (FAILED(hr))
{
WARN("This is not the factory we're looking for, returning %#x\n", hr);
goto fail;
}
wined3d = IWineDXGIFactory_get_wined3d(dxgi_device->factory);
hr = IDXGIAdapter_QueryInterface(adapter, &IID_IWineDXGIAdapter, (void **)&wine_adapter);
if (FAILED(hr))
{
WARN("This is not the adapter we're looking for, returning %#x\n", hr);
EnterCriticalSection(&dxgi_cs);
IWineD3D_Release(wined3d);
LeaveCriticalSection(&dxgi_cs);
goto fail;
}
adapter_ordinal = IWineDXGIAdapter_get_ordinal(wine_adapter);
IWineDXGIAdapter_Release(wine_adapter);
hr = IUnknown_QueryInterface((IUnknown *)dxgi_device, &IID_IWineD3DDeviceParent, (void **)&wined3d_device_parent);
hr = dxgi_device_init(dxgi_device, &d3d10_layer, factory, adapter);
if (FAILED(hr))
{
ERR("DXGI device should implement IWineD3DDeviceParent\n");
goto fail;
}
FIXME("Ignoring adapter type\n");
EnterCriticalSection(&dxgi_cs);
hr = IWineD3D_CreateDevice(wined3d, adapter_ordinal, WINED3DDEVTYPE_HAL, NULL, 0,
(IUnknown *)dxgi_device, wined3d_device_parent, &dxgi_device->wined3d_device);
IWineD3DDeviceParent_Release(wined3d_device_parent);
IWineD3D_Release(wined3d);
LeaveCriticalSection(&dxgi_cs);
if (FAILED(hr))
{
WARN("Failed to create a WineD3D device, returning %#x\n", hr);
goto fail;
WARN("Failed to initialize device, hr %#x.\n", hr);
HeapFree(GetProcessHeap(), 0, dxgi_device);
*device = NULL;
return hr;
}
TRACE("Created device %p.\n", dxgi_device);
*device = dxgi_device;
return hr;
fail:
if (dxgi_device->wined3d_device)
{
EnterCriticalSection(&dxgi_cs);
IWineD3DDevice_Release(dxgi_device->wined3d_device);
LeaveCriticalSection(&dxgi_cs);
}
if (dxgi_device->factory) IWineDXGIFactory_Release(dxgi_device->factory);
if (dxgi_device->child_layer) IUnknown_Release(dxgi_device->child_layer);
HeapFree(GetProcessHeap(), 0, dxgi_device);
*device = NULL;
return hr;
return S_OK;
}
HRESULT WINAPI DXGID3D10RegisterLayers(const struct dxgi_device_layer *layers, UINT layer_count)
......
......@@ -36,6 +36,38 @@
extern CRITICAL_SECTION dxgi_cs DECLSPEC_HIDDEN;
/* Layered device */
enum dxgi_device_layer_id
{
DXGI_DEVICE_LAYER_DEBUG1 = 0x8,
DXGI_DEVICE_LAYER_THREAD_SAFE = 0x10,
DXGI_DEVICE_LAYER_DEBUG2 = 0x20,
DXGI_DEVICE_LAYER_SWITCH_TO_REF = 0x30,
DXGI_DEVICE_LAYER_D3D10_DEVICE = 0xffffffff,
};
struct layer_get_size_args
{
DWORD unknown0;
DWORD unknown1;
DWORD *unknown2;
DWORD *unknown3;
IDXGIAdapter *adapter;
WORD interface_major;
WORD interface_minor;
WORD version_build;
WORD version_revision;
};
struct dxgi_device_layer
{
enum dxgi_device_layer_id id;
HRESULT (WINAPI *init)(enum dxgi_device_layer_id id, DWORD *count, DWORD *values);
UINT (WINAPI *get_size)(enum dxgi_device_layer_id id, struct layer_get_size_args *args, DWORD unknown0);
HRESULT (WINAPI *create)(enum dxgi_device_layer_id id, void **layer_base, DWORD unknown0,
void *device_object, REFIID riid, void **device_layer);
};
/* TRACE helper functions */
const char *debug_dxgi_format(DXGI_FORMAT format) DECLSPEC_HIDDEN;
......@@ -53,7 +85,6 @@ struct dxgi_factory
};
/* IDXGIDevice */
extern const struct IWineDXGIDeviceVtbl dxgi_device_vtbl DECLSPEC_HIDDEN;
struct dxgi_device
{
const struct IWineDXGIDeviceVtbl *vtbl;
......@@ -63,6 +94,9 @@ struct dxgi_device
IWineDXGIFactory *factory;
};
HRESULT dxgi_device_init(struct dxgi_device *device, struct dxgi_device_layer *layer,
IDXGIFactory *factory, IDXGIAdapter *adapter) DECLSPEC_HIDDEN;
/* IDXGIOutput */
struct dxgi_output
{
......@@ -104,36 +138,4 @@ struct dxgi_surface
LONG refcount;
};
/* Layered device */
enum dxgi_device_layer_id
{
DXGI_DEVICE_LAYER_DEBUG1 = 0x8,
DXGI_DEVICE_LAYER_THREAD_SAFE = 0x10,
DXGI_DEVICE_LAYER_DEBUG2 = 0x20,
DXGI_DEVICE_LAYER_SWITCH_TO_REF = 0x30,
DXGI_DEVICE_LAYER_D3D10_DEVICE = 0xffffffff,
};
struct layer_get_size_args
{
DWORD unknown0;
DWORD unknown1;
DWORD *unknown2;
DWORD *unknown3;
IDXGIAdapter *adapter;
WORD interface_major;
WORD interface_minor;
WORD version_build;
WORD version_revision;
};
struct dxgi_device_layer
{
enum dxgi_device_layer_id id;
HRESULT (WINAPI *init)(enum dxgi_device_layer_id id, DWORD *count, DWORD *values);
UINT (WINAPI *get_size)(enum dxgi_device_layer_id id, struct layer_get_size_args *args, DWORD unknown0);
HRESULT (WINAPI *create)(enum dxgi_device_layer_id id, void **layer_base, DWORD unknown0,
void *device_object, REFIID riid, void **device_layer);
};
#endif /* __WINE_DXGI_PRIVATE_H */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment