dxgi: Create a wined3d swapchain.
This commit is contained in:
parent
91e4ec57cc
commit
eda929d010
|
@ -1331,12 +1331,29 @@ 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 =
|
||||
{
|
||||
/* IUnknown methods */
|
||||
|
|
|
@ -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
|
||||
);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue