Commit eda929d0 authored by Henri Verbeet's avatar Henri Verbeet Committed by Alexandre Julliard

dxgi: Create a wined3d swapchain.

parent 91e4ec57
......@@ -1331,11 +1331,28 @@ static HRESULT STDMETHODCALLTYPE device_parent_CreateVolume(IWineD3DDeviceParent
static HRESULT STDMETHODCALLTYPE device_parent_CreateSwapChain(IWineD3DDeviceParent *iface,
WINED3DPRESENT_PARAMETERS *present_parameters, IWineD3DSwapChain **swapchain)
{
FIXME("iface %p, present_parameters %p, swapchain %p stub!\n", iface, present_parameters, swapchain);
IWineDXGIDevice *wine_device;
HRESULT hr;
return E_NOTIMPL;
}
TRACE("iface %p, present_parameters %p, swapchain %p\n", iface, present_parameters, swapchain);
hr = IWineD3DDeviceParent_QueryInterface(iface, &IID_IWineDXGIDevice, (void **)&wine_device);
if (FAILED(hr))
{
ERR("Device should implement IWineDXGIDevice\n");
return E_FAIL;
}
hr = IWineDXGIDevice_create_swapchain(wine_device, present_parameters, swapchain);
IWineDXGIDevice_Release(wine_device);
if (FAILED(hr))
{
ERR("Failed to create DXGI swapchain, returning %#x\n", hr);
return hr;
}
return S_OK;
}
const struct IWineD3DDeviceParentVtbl d3d10_wined3d_device_parent_vtbl =
{
......
......@@ -280,6 +280,38 @@ static HRESULT STDMETHODCALLTYPE dxgi_device_create_surface(IWineDXGIDevice *ifa
return S_OK;
}
static HRESULT STDMETHODCALLTYPE dxgi_device_create_swapchain(IWineDXGIDevice *iface,
WINED3DPRESENT_PARAMETERS *present_parameters, IWineD3DSwapChain **wined3d_swapchain)
{
struct dxgi_device *This = (struct dxgi_device *)iface;
struct dxgi_swapchain *object;
HRESULT hr;
object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
if (!object)
{
ERR("Failed to allocate DXGI swapchain object memory\n");
return E_OUTOFMEMORY;
}
object->vtbl = &dxgi_swapchain_vtbl;
object->refcount = 1;
hr = IWineD3DDevice_CreateSwapChain(This->wined3d_device, present_parameters,
&object->wined3d_swapchain, (IUnknown *)object, SURFACE_OPENGL);
if (FAILED(hr))
{
WARN("Failed to create a swapchain, returning %#x\n", hr);
HeapFree(GetProcessHeap(), 0, object);
return hr;
}
*wined3d_swapchain = object->wined3d_swapchain;
TRACE("Created IDXGISwapChain %p\n", object);
return S_OK;
}
const struct IWineDXGIDeviceVtbl dxgi_device_vtbl =
{
/* IUnknown methods */
......@@ -300,4 +332,5 @@ const struct IWineDXGIDeviceVtbl dxgi_device_vtbl =
/* IWineDXGIAdapter methods */
dxgi_device_get_wined3d_device,
dxgi_device_create_surface,
dxgi_device_create_swapchain,
};
......@@ -79,6 +79,7 @@ struct dxgi_swapchain
{
const struct IDXGISwapChainVtbl *vtbl;
LONG refcount;
IWineD3DSwapChain *wined3d_swapchain;
};
/* IDXGISurface */
......
......@@ -153,25 +153,98 @@ static HRESULT STDMETHODCALLTYPE dxgi_factory_GetWindowAssociation(IWineDXGIFact
return E_NOTIMPL;
}
/* TODO: The DXGI swapchain desc is a bit nicer than WINED3DPRESENT_PARAMETERS,
* change wined3d to use a structure more similar to DXGI. */
static HRESULT STDMETHODCALLTYPE dxgi_factory_CreateSwapChain(IWineDXGIFactory *iface,
IUnknown *device, DXGI_SWAP_CHAIN_DESC *desc, IDXGISwapChain **swapchain)
{
struct dxgi_swapchain *object;
WINED3DPRESENT_PARAMETERS present_parameters;
IWineD3DSwapChain *wined3d_swapchain;
IWineD3DDevice *wined3d_device;
IWineDXGIDevice *dxgi_device;
UINT count;
HRESULT hr;
FIXME("iface %p, device %p, desc %p, swapchain %p partial stub!\n", iface, device, desc, swapchain);
object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
if (!object)
hr = IUnknown_QueryInterface(device, &IID_IWineDXGIDevice, (void **)&dxgi_device);
if (FAILED(hr))
{
ERR("Failed to allocate DXGI swapchain object memory\n");
return E_OUTOFMEMORY;
ERR("This is not the device we're looking for\n");
return hr;
}
object->vtbl = &dxgi_swapchain_vtbl;
object->refcount = 1;
*swapchain = (IDXGISwapChain *)object;
wined3d_device = IWineDXGIDevice_get_wined3d_device(dxgi_device);
IWineDXGIDevice_Release(dxgi_device);
TRACE("Created IDXGISwapChain %p\n", object);
count = IWineD3DDevice_GetNumberOfSwapChains(wined3d_device);
if (count)
{
FIXME("Only a single swapchain supported.\n");
IWineD3DDevice_Release(wined3d_device);
return E_FAIL;
}
if (!desc->OutputWindow)
{
FIXME("No output window, should use factory output window\n");
}
FIXME("Ignoring SwapEffect and Flags\n");
present_parameters.BackBufferWidth = desc->BufferDesc.Width;
present_parameters.BackBufferHeight = desc->BufferDesc.Height;
present_parameters.BackBufferFormat = wined3dformat_from_dxgi_format(desc->BufferDesc.Format);
present_parameters.BackBufferCount = desc->BufferCount;
if (desc->SampleDesc.Count > 1)
{
present_parameters.MultiSampleType = desc->SampleDesc.Count;
present_parameters.MultiSampleQuality = desc->SampleDesc.Quality;
}
else
{
present_parameters.MultiSampleType = WINED3DMULTISAMPLE_NONE;
present_parameters.MultiSampleQuality = 0;
}
present_parameters.SwapEffect = WINED3DSWAPEFFECT_DISCARD;
present_parameters.hDeviceWindow = desc->OutputWindow;
present_parameters.Windowed = desc->Windowed;
present_parameters.EnableAutoDepthStencil = FALSE;
present_parameters.AutoDepthStencilFormat = 0;
present_parameters.Flags = 0; /* WINED3DPRESENTFLAG_DISCARD_DEPTHSTENCIL? */
present_parameters.FullScreen_RefreshRateInHz =
desc->BufferDesc.RefreshRate.Numerator / desc->BufferDesc.RefreshRate.Denominator;
present_parameters.PresentationInterval = WINED3DPRESENT_INTERVAL_DEFAULT;
hr = IWineD3DDevice_Init3D(wined3d_device, &present_parameters);
if (FAILED(hr))
{
WARN("Failed to initialize 3D, returning %#x\n", hr);
IWineD3DDevice_Release(wined3d_device);
return hr;
}
hr = IWineD3DDevice_GetSwapChain(wined3d_device, 0, &wined3d_swapchain);
IWineD3DDevice_Release(wined3d_device);
if (FAILED(hr))
{
WARN("Failed to get swapchain, returning %#x\n", hr);
return hr;
}
hr = IWineD3DSwapChain_GetParent(wined3d_swapchain, (IUnknown **)swapchain);
IUnknown_Release(wined3d_swapchain);
if (FAILED(hr))
{
WARN("Failed to get swapchain, returning %#x\n", hr);
return hr;
}
/* FIXME? The swapchain is created with refcount 1 by the wined3d device,
* but the wined3d device can't hold a real reference. */
IUnknown_Release(*swapchain);
TRACE("Created IDXGISwapChain %p\n", *swapchain);
return S_OK;
}
......
......@@ -56,6 +56,25 @@ static ULONG STDMETHODCALLTYPE dxgi_swapchain_AddRef(IDXGISwapChain *iface)
return refcount;
}
static ULONG STDMETHODCALLTYPE destroy_surface(IWineD3DSurface *surface)
{
IDXGISurface *dxgi_surface;
TRACE("surface %p\n", surface);
IWineD3DSurface_GetParent(surface, (IUnknown **)&dxgi_surface);
IDXGISurface_Release(dxgi_surface);
return IDXGISurface_Release(dxgi_surface);
}
static ULONG STDMETHODCALLTYPE destroy_swapchain(IWineD3DSwapChain *swapchain)
{
TRACE("swapchain %p\n", swapchain);
return IWineD3DSwapChain_Release(swapchain);
}
static ULONG STDMETHODCALLTYPE dxgi_swapchain_Release(IDXGISwapChain *iface)
{
struct dxgi_swapchain *This = (struct dxgi_swapchain *)iface;
......@@ -65,6 +84,26 @@ static ULONG STDMETHODCALLTYPE dxgi_swapchain_Release(IDXGISwapChain *iface)
if (!refcount)
{
IWineD3DDevice *wined3d_device;
HRESULT hr;
FIXME("Only a single swapchain is supported\n");
hr = IWineD3DSwapChain_GetDevice(This->wined3d_swapchain, &wined3d_device);
if (FAILED(hr))
{
ERR("Failed to get the wined3d device, hr %#x\n", hr);
}
else
{
hr = IWineD3DDevice_Uninit3D(wined3d_device, destroy_surface, destroy_swapchain);
IWineD3DDevice_Release(wined3d_device);
if (FAILED(hr))
{
ERR("Uninit3D failed, hr %#x\n", hr);
}
}
HeapFree(GetProcessHeap(), 0, This);
}
......
......@@ -53,4 +53,8 @@ interface IWineDXGIDevice : IDXGIDevice
[in] IUnknown *outer,
[out] void **surface
);
HRESULT create_swapchain(
[in] struct _WINED3DPRESENT_PARAMETERS *present_parameters,
[out] struct IWineD3DSwapChain **wined3d_swapchain
);
}
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