Henri Verbeet : dxgi: Create a wined3d swapchain.
Alexandre Julliard
julliard at winehq.org
Tue Feb 24 10:21:32 CST 2009
Module: wine
Branch: master
Commit: eda929d0104a5a42f54c4be5fc840fe5f477f740
URL: http://source.winehq.org/git/wine.git/?a=commit;h=eda929d0104a5a42f54c4be5fc840fe5f477f740
Author: Henri Verbeet <hverbeet at codeweavers.com>
Date: Tue Feb 24 07:43:02 2009 +0100
dxgi: Create a wined3d swapchain.
---
dlls/d3d10core/device.c | 23 ++++++++++-
dlls/dxgi/device.c | 33 ++++++++++++++++
dlls/dxgi/dxgi_private.h | 1 +
dlls/dxgi/factory.c | 91 ++++++++++++++++++++++++++++++++++++++++----
dlls/dxgi/swapchain.c | 39 +++++++++++++++++++
include/wine/winedxgi.idl | 4 ++
6 files changed, 179 insertions(+), 12 deletions(-)
diff --git a/dlls/d3d10core/device.c b/dlls/d3d10core/device.c
index 0eeb5d9..0d79808 100644
--- a/dlls/d3d10core/device.c
+++ b/dlls/d3d10core/device.c
@@ -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 =
{
diff --git a/dlls/dxgi/device.c b/dlls/dxgi/device.c
index 5c3fdfc..bf079d5 100644
--- a/dlls/dxgi/device.c
+++ b/dlls/dxgi/device.c
@@ -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,
};
diff --git a/dlls/dxgi/dxgi_private.h b/dlls/dxgi/dxgi_private.h
index 90ed4dc..54446ef 100644
--- a/dlls/dxgi/dxgi_private.h
+++ b/dlls/dxgi/dxgi_private.h
@@ -79,6 +79,7 @@ struct dxgi_swapchain
{
const struct IDXGISwapChainVtbl *vtbl;
LONG refcount;
+ IWineD3DSwapChain *wined3d_swapchain;
};
/* IDXGISurface */
diff --git a/dlls/dxgi/factory.c b/dlls/dxgi/factory.c
index 19bc4cf..667b2f7 100644
--- a/dlls/dxgi/factory.c
+++ b/dlls/dxgi/factory.c
@@ -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;
}
diff --git a/dlls/dxgi/swapchain.c b/dlls/dxgi/swapchain.c
index 3287c4c..3e9e444 100644
--- a/dlls/dxgi/swapchain.c
+++ b/dlls/dxgi/swapchain.c
@@ -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);
}
diff --git a/include/wine/winedxgi.idl b/include/wine/winedxgi.idl
index 3fc7883..e54ce73 100644
--- a/include/wine/winedxgi.idl
+++ b/include/wine/winedxgi.idl
@@ -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
+ );
}
More information about the wine-cvs
mailing list