Implement swapchains.
diff --git a/dlls/d3d8/d3d8_private.h b/dlls/d3d8/d3d8_private.h
index fa65f21..c1ec0bb 100644
--- a/dlls/d3d8/d3d8_private.h
+++ b/dlls/d3d8/d3d8_private.h
@@ -655,6 +655,9 @@
/* OpenGL/GLX related */
GLXContext swap_ctx;
Drawable swap_drawable;
+
+ /* ready for when we move over to wined3d */
+ IWineD3DSwapChain *wineD3DSwapChain;
};
/* IUnknown: */
diff --git a/dlls/d3d8/directx.c b/dlls/d3d8/directx.c
index ae3996a..ecf2ca4 100644
--- a/dlls/d3d8/directx.c
+++ b/dlls/d3d8/directx.c
@@ -579,6 +579,61 @@
return res;
}
+/* Callback for creating the inplicite swapchain when the device is created */
+HRESULT WINAPI D3D8CB_CreateAdditionalSwapChain(IUnknown *device,
+ WINED3DPRESENT_PARAMETERS* pPresentationParameters,
+ IWineD3DSwapChain ** ppSwapChain){
+ HRESULT res = D3D_OK;
+ IDirect3DSwapChain8Impl *d3dSwapChain = NULL;
+ /* We have to pass the presentation parameters back and forth */
+ D3DPRESENT_PARAMETERS localParameters;
+ localParameters.BackBufferWidth = *(pPresentationParameters->BackBufferWidth);
+ localParameters.BackBufferHeight = *(pPresentationParameters->BackBufferHeight);
+ localParameters.BackBufferFormat = *(pPresentationParameters->BackBufferFormat);
+ localParameters.BackBufferCount = *(pPresentationParameters->BackBufferCount);
+ localParameters.MultiSampleType = *(pPresentationParameters->MultiSampleType);
+ /* d3d9 only */
+ /* localParameters.MultiSampleQuality = *(pPresentationParameters->MultiSampleQuality); */
+ localParameters.SwapEffect = *(pPresentationParameters->SwapEffect);
+ localParameters.hDeviceWindow = *(pPresentationParameters->hDeviceWindow);
+ localParameters.Windowed = *(pPresentationParameters->Windowed);
+ localParameters.EnableAutoDepthStencil = *(pPresentationParameters->EnableAutoDepthStencil);
+ localParameters.AutoDepthStencilFormat = *(pPresentationParameters->AutoDepthStencilFormat);
+ localParameters.Flags = *(pPresentationParameters->Flags);
+ localParameters.FullScreen_RefreshRateInHz = *(pPresentationParameters->FullScreen_RefreshRateInHz);
+/* not in d3d8 */
+/* localParameters.PresentationInterval = *(pPresentationParameters->PresentationInterval); */
+
+ TRACE("(%p) rellaying\n", device);
+ /*copy the presentation parameters*/
+ res = IDirect3DDevice8_CreateAdditionalSwapChain((IDirect3DDevice8 *)device, &localParameters, (IDirect3DSwapChain8 **)&d3dSwapChain);
+
+ if (res == D3D_OK){
+ *ppSwapChain = d3dSwapChain->wineD3DSwapChain;
+ } else {
+ FIXME("failed to create additional swap chain\n");
+ *ppSwapChain = NULL;
+ }
+ /* Copy back the presentation parameters */
+ TRACE("(%p) setting up return parameters\n", device);
+ *pPresentationParameters->BackBufferWidth = localParameters.BackBufferWidth;
+ *pPresentationParameters->BackBufferHeight = localParameters.BackBufferHeight;
+ *pPresentationParameters->BackBufferFormat = localParameters.BackBufferFormat;
+ *pPresentationParameters->BackBufferCount = localParameters.BackBufferCount;
+ *pPresentationParameters->MultiSampleType = localParameters.MultiSampleType;
+/* *pPresentationParameters->MultiSampleQuality leave alone incase wineD3D set something internally */
+ *pPresentationParameters->SwapEffect = localParameters.SwapEffect;
+ *pPresentationParameters->hDeviceWindow = localParameters.hDeviceWindow;
+ *pPresentationParameters->Windowed = localParameters.Windowed;
+ *pPresentationParameters->EnableAutoDepthStencil = localParameters.EnableAutoDepthStencil;
+ *pPresentationParameters->AutoDepthStencilFormat = localParameters.AutoDepthStencilFormat;
+ *pPresentationParameters->Flags = localParameters.Flags;
+ *pPresentationParameters->FullScreen_RefreshRateInHz = localParameters.FullScreen_RefreshRateInHz;
+/* *pPresentationParameters->PresentationInterval leave alone incase wineD3D set something internally */
+
+ return res;
+}
+
HRESULT WINAPI IDirect3D8Impl_CreateDevice (LPDIRECT3D8 iface,
UINT Adapter, D3DDEVTYPE DeviceType, HWND hFocusWindow,
DWORD BehaviourFlags, D3DPRESENT_PARAMETERS* pPresentationParameters,
@@ -624,7 +679,7 @@
localParameters.Flags = &pPresentationParameters->Flags;
localParameters.FullScreen_RefreshRateInHz = &pPresentationParameters->FullScreen_RefreshRateInHz;
localParameters.PresentationInterval = &pPresentationParameters->FullScreen_PresentationInterval; /* Renamed in dx9 */
- IWineD3D_CreateDevice(This->WineD3D, Adapter, DeviceType, hFocusWindow, BehaviourFlags, &localParameters, &object->WineD3DDevice, (IUnknown *)object, D3D8CB_CreateRenderTarget);
+ IWineD3D_CreateDevice(This->WineD3D, Adapter, DeviceType, hFocusWindow, BehaviourFlags, &localParameters, &object->WineD3DDevice, (IUnknown *)object, D3D8CB_CreateAdditionalSwapChain);
/** use StateBlock Factory here, for creating the startup stateBlock */
object->StateBlock = NULL;
diff --git a/dlls/d3d9/d3d9_private.h b/dlls/d3d9/d3d9_private.h
index b0aedf5..4c96a63 100644
--- a/dlls/d3d9/d3d9_private.h
+++ b/dlls/d3d9/d3d9_private.h
@@ -184,7 +184,6 @@
typedef struct IDirect3DVertexBuffer9Impl IDirect3DVertexBuffer9Impl;
typedef struct IDirect3DIndexBuffer9Impl IDirect3DIndexBuffer9Impl;
typedef struct IDirect3DSurface9Impl IDirect3DSurface9Impl;
-typedef struct IDirect3DSwapChain9Impl IDirect3DSwapChain9Impl;
typedef struct IDirect3DResource9Impl IDirect3DResource9Impl;
typedef struct IDirect3DVolume9Impl IDirect3DVolume9Impl;
typedef struct IDirect3DStateBlock9Impl IDirect3DStateBlock9Impl;
@@ -560,34 +559,15 @@
/*****************************************************************************
* IDirect3DSwapChain9 implementation structure
*/
-struct IDirect3DSwapChain9Impl
+typedef struct IDirect3DSwapChain9Impl
{
/* IUnknown fields */
const IDirect3DSwapChain9Vtbl *lpVtbl;
DWORD ref;
/* IDirect3DSwapChain9 fields */
- IDirect3DDevice9Impl *Device;
- IDirect3DSurface9Impl *frontBuffer;
- IDirect3DSurface9Impl *backBuffer;
- IDirect3DSurface9Impl *depthStencilBuffer;
- D3DPRESENT_PARAMETERS PresentParms;
-};
-
-/* IUnknown: */
-extern HRESULT WINAPI IDirect3DSwapChain9Impl_QueryInterface(LPDIRECT3DSWAPCHAIN9 iface, REFIID refiid, LPVOID* obj);
-extern ULONG WINAPI IDirect3DSwapChain9Impl_AddRef(LPDIRECT3DSWAPCHAIN9 iface);
-extern ULONG WINAPI IDirect3DSwapChain9Impl_Release(LPDIRECT3DSWAPCHAIN9 iface);
-
-/* IDirect3DSwapChain9: */
-extern HRESULT WINAPI IDirect3DSwapChain9Impl_Present(LPDIRECT3DSWAPCHAIN9 iface, CONST RECT* pSourceRect, CONST RECT* pDestRect, HWND hDestWindowOverride, CONST RGNDATA* pDirtyRegion, DWORD dwFlags);
-extern HRESULT WINAPI IDirect3DSwapChain9Impl_GetFrontBufferData(LPDIRECT3DSWAPCHAIN9 iface, IDirect3DSurface9* pDestSurface);
-extern HRESULT WINAPI IDirect3DSwapChain9Impl_GetBackBuffer(LPDIRECT3DSWAPCHAIN9 iface, UINT iBackBuffer, D3DBACKBUFFER_TYPE Type, IDirect3DSurface9** ppBackBuffer);
-extern HRESULT WINAPI IDirect3DSwapChain9Impl_GetRasterStatus(LPDIRECT3DSWAPCHAIN9 iface, D3DRASTER_STATUS* pRasterStatus);
-extern HRESULT WINAPI IDirect3DSwapChain9Impl_GetDisplayMode(LPDIRECT3DSWAPCHAIN9 iface, D3DDISPLAYMODE* pMode);
-extern HRESULT WINAPI IDirect3DSwapChain9Impl_GetDevice(LPDIRECT3DSWAPCHAIN9 iface, IDirect3DDevice9** ppDevice);
-extern HRESULT WINAPI IDirect3DSwapChain9Impl_GetPresentParameters(LPDIRECT3DSWAPCHAIN9 iface, D3DPRESENT_PARAMETERS* pPresentationParameters);
-
+ IWineD3DSwapChain *wineD3DSwapChain;
+} IDirect3DSwapChain9Impl;
/* ------------------ */
/* IDirect3DResource9 */
@@ -1210,4 +1190,14 @@
IWineD3DVolume **ppVolume,
HANDLE * pSharedHandle);
+extern HRESULT WINAPI D3D9CB_CreateDepthStencilSurface(IUnknown *device, UINT Width, UINT Height,
+ WINED3DFORMAT Format, D3DMULTISAMPLE_TYPE MultiSample,
+ DWORD MultisampleQuality, BOOL Discard,
+ IWineD3DSurface** ppSurface, HANDLE* pSharedHandle);
+
+extern HRESULT WINAPI D3D9CB_CreateRenderTarget(IUnknown *device, UINT Width, UINT Height,
+ WINED3DFORMAT Format, D3DMULTISAMPLE_TYPE MultiSample,
+ DWORD MultisampleQuality, BOOL Lockable,
+ IWineD3DSurface** ppSurface, HANDLE* pSharedHandle);
+
#endif /* __WINE_D3D9_PRIVATE_H */
diff --git a/dlls/d3d9/device.c b/dlls/d3d9/device.c
index 2d99208..8a08a5d 100644
--- a/dlls/d3d9/device.c
+++ b/dlls/d3d9/device.c
@@ -57,7 +57,6 @@
TRACE("(%p) : ReleaseRef to %ld\n", This, ref);
if (ref == 0) {
- IDirect3D9_Release((LPDIRECT3D9) This->direct3d);
IWineD3DDevice_Release(This->WineD3DDevice);
HeapFree(GetProcessHeap(), 0, This);
}
diff --git a/dlls/d3d9/directx.c b/dlls/d3d9/directx.c
index 5ce74f6..4c7aa85 100644
--- a/dlls/d3d9/directx.c
+++ b/dlls/d3d9/directx.c
@@ -175,38 +175,103 @@
}
/* Internal function called back during the CreateDevice to create a render target */
-HRESULT WINAPI D3D9CB_CreateRenderTarget(IUnknown *device, UINT Width, UINT Height,
- WINED3DFORMAT Format, D3DMULTISAMPLE_TYPE MultiSample,
- DWORD MultisampleQuality, BOOL Lockable,
+HRESULT WINAPI D3D9CB_CreateRenderTarget(IUnknown *device, UINT Width, UINT Height,
+ WINED3DFORMAT Format, D3DMULTISAMPLE_TYPE MultiSample,
+ DWORD MultisampleQuality, BOOL Lockable,
IWineD3DSurface** ppSurface, HANDLE* pSharedHandle) {
HRESULT res = D3D_OK;
IDirect3DSurface9Impl *d3dSurface = NULL;
- IDirect3DDevice9Impl* pDeviceImpl = (IDirect3DDevice9Impl*) device;
-
+ TRACE("(%p) call back\n", device);
res = IDirect3DDevice9_CreateRenderTarget((IDirect3DDevice9 *)device, Width, Height,
- (D3DFORMAT) Format, MultiSample, MultisampleQuality, Lockable,
+ (D3DFORMAT)Format, MultiSample, MultisampleQuality, Lockable,
(IDirect3DSurface9 **)&d3dSurface, pSharedHandle);
if (SUCCEEDED(res)) {
*ppSurface = d3dSurface->wineD3DSurface;
- if (NULL == pDeviceImpl->backBuffer) {
- pDeviceImpl->backBuffer = d3dSurface;
- pDeviceImpl->renderTarget = d3dSurface;
- IDirect3DSurface9Impl_AddRef((LPDIRECT3DSURFACE9) pDeviceImpl->renderTarget);
- }
} else {
*ppSurface = NULL;
}
return res;
}
+HRESULT WINAPI D3D9CB_CreateAdditionalSwapChain(IUnknown *device,
+ WINED3DPRESENT_PARAMETERS* pPresentationParameters,
+ IWineD3DSwapChain ** ppSwapChain) {
+ HRESULT res = D3D_OK;
+ IDirect3DSwapChain9Impl *d3dSwapChain = NULL;
+ D3DPRESENT_PARAMETERS localParameters;
+ TRACE("(%p) call back\n", device);
+
+ localParameters.BackBufferWidth = *(pPresentationParameters->BackBufferWidth);
+ localParameters.BackBufferHeight = *(pPresentationParameters->BackBufferHeight);
+ localParameters.BackBufferFormat = *(pPresentationParameters->BackBufferFormat);
+ localParameters.BackBufferCount = *(pPresentationParameters->BackBufferCount);
+ localParameters.MultiSampleType = *(pPresentationParameters->MultiSampleType);
+ localParameters.MultiSampleQuality = *(pPresentationParameters->MultiSampleQuality);
+ localParameters.SwapEffect = *(pPresentationParameters->SwapEffect);
+ localParameters.hDeviceWindow = *(pPresentationParameters->hDeviceWindow);
+ localParameters.Windowed = *(pPresentationParameters->Windowed);
+ localParameters.EnableAutoDepthStencil = *(pPresentationParameters->EnableAutoDepthStencil);
+ localParameters.AutoDepthStencilFormat = *(pPresentationParameters->AutoDepthStencilFormat);
+ localParameters.Flags = *(pPresentationParameters->Flags);
+ localParameters.FullScreen_RefreshRateInHz = *(pPresentationParameters->FullScreen_RefreshRateInHz);
+ localParameters.PresentationInterval = *(pPresentationParameters->PresentationInterval);
+
+ /*copy the presentation parameters*/
+ res = IDirect3DDevice9_CreateAdditionalSwapChain((IDirect3DDevice9 *)device, &localParameters, (IDirect3DSwapChain9 **)&d3dSwapChain);
+
+ if (res == D3D_OK && d3dSwapChain != NULL) {
+ *ppSwapChain = d3dSwapChain->wineD3DSwapChain;
+ } else {
+ *ppSwapChain = NULL;
+ }
+ /*Copy back the presentation parameters*/
+ *pPresentationParameters->BackBufferWidth = localParameters.BackBufferWidth;
+ *pPresentationParameters->BackBufferHeight = localParameters.BackBufferHeight;
+ *pPresentationParameters->BackBufferFormat = localParameters.BackBufferFormat;
+ *pPresentationParameters->BackBufferCount = localParameters.BackBufferCount;
+ *pPresentationParameters->MultiSampleType = localParameters.MultiSampleType;
+ *pPresentationParameters->MultiSampleQuality = localParameters.MultiSampleQuality;
+ *pPresentationParameters->SwapEffect = localParameters.SwapEffect;
+ *pPresentationParameters->hDeviceWindow = localParameters.hDeviceWindow;
+ *pPresentationParameters->Windowed = localParameters.Windowed;
+ *pPresentationParameters->EnableAutoDepthStencil = localParameters.EnableAutoDepthStencil;
+ *pPresentationParameters->AutoDepthStencilFormat = localParameters.AutoDepthStencilFormat;
+ *pPresentationParameters->Flags = localParameters.Flags;
+ *pPresentationParameters->FullScreen_RefreshRateInHz = localParameters.FullScreen_RefreshRateInHz;
+ *pPresentationParameters->PresentationInterval = localParameters.PresentationInterval;
+
+ return res;
+}
+
+/* Internal function called back during the CreateDevice to create a render target */
+HRESULT WINAPI D3D9CB_CreateDepthStencilSurface(IUnknown *device, UINT Width, UINT Height,
+ WINED3DFORMAT Format, D3DMULTISAMPLE_TYPE MultiSample,
+ DWORD MultisampleQuality, BOOL Discard,
+ IWineD3DSurface** ppSurface, HANDLE* pSharedHandle) {
+ HRESULT res = D3D_OK;
+ IDirect3DSurface9Impl *d3dSurface = NULL;
+ TRACE("(%p) call back\n", device);
+
+ res = IDirect3DDevice9_CreateDepthStencilSurface((IDirect3DDevice9 *)device, Width, Height,
+ (D3DFORMAT)Format, MultiSample, MultisampleQuality, Discard,
+ (IDirect3DSurface9 **)&d3dSurface, pSharedHandle);
+ if (res == D3D_OK) {
+ *ppSurface = d3dSurface->wineD3DSurface;
+ }
+ return res;
+}
+
+
HRESULT WINAPI IDirect3D9Impl_CreateDevice(LPDIRECT3D9 iface, UINT Adapter, D3DDEVTYPE DeviceType, HWND hFocusWindow,
- DWORD BehaviourFlags, D3DPRESENT_PARAMETERS* pPresentationParameters,
- IDirect3DDevice9** ppReturnedDeviceInterface) {
+ DWORD BehaviourFlags, D3DPRESENT_PARAMETERS* pPresentationParameters,
+ IDirect3DDevice9** ppReturnedDeviceInterface) {
IDirect3D9Impl *This = (IDirect3D9Impl *)iface;
IDirect3DDevice9Impl *object = NULL;
WINED3DPRESENT_PARAMETERS localParameters;
+ HRESULT hr;
+ TRACE("(%p) Relay \n", This);
/* Check the validity range of the adapter parameter */
if (Adapter >= IDirect3D9Impl_GetAdapterCount(iface)) {
@@ -224,28 +289,38 @@
object->lpVtbl = &Direct3DDevice9_Vtbl;
object->ref = 1;
- object->direct3d = This;
- IDirect3D9_AddRef((LPDIRECT3D9) object->direct3d);
*ppReturnedDeviceInterface = (IDirect3DDevice9 *)object;
-
+
/* Allocate an associated WineD3DDevice object */
localParameters.BackBufferWidth = &pPresentationParameters->BackBufferWidth;
- localParameters.BackBufferHeight = &pPresentationParameters->BackBufferHeight;
- localParameters.BackBufferFormat = &pPresentationParameters->BackBufferFormat;
- localParameters.BackBufferCount = &pPresentationParameters->BackBufferCount;
- localParameters.MultiSampleType = &pPresentationParameters->MultiSampleType;
- localParameters.MultiSampleQuality = &pPresentationParameters->MultiSampleQuality;
- localParameters.SwapEffect = &pPresentationParameters->SwapEffect;
- localParameters.hDeviceWindow = &pPresentationParameters->hDeviceWindow;
- localParameters.Windowed = &pPresentationParameters->Windowed;
- localParameters.EnableAutoDepthStencil = &pPresentationParameters->EnableAutoDepthStencil;
- localParameters.AutoDepthStencilFormat = &pPresentationParameters->AutoDepthStencilFormat;
- localParameters.Flags = &pPresentationParameters->Flags;
+ localParameters.BackBufferHeight = &pPresentationParameters->BackBufferHeight;
+ localParameters.BackBufferFormat = &pPresentationParameters->BackBufferFormat;
+ localParameters.BackBufferCount = &pPresentationParameters->BackBufferCount;
+ localParameters.MultiSampleType = &pPresentationParameters->MultiSampleType;
+ localParameters.MultiSampleQuality = &pPresentationParameters->MultiSampleQuality;
+ localParameters.SwapEffect = &pPresentationParameters->SwapEffect;
+ localParameters.hDeviceWindow = &pPresentationParameters->hDeviceWindow;
+ localParameters.Windowed = &pPresentationParameters->Windowed;
+ localParameters.EnableAutoDepthStencil = &pPresentationParameters->EnableAutoDepthStencil;
+ localParameters.AutoDepthStencilFormat = &pPresentationParameters->AutoDepthStencilFormat;
+ localParameters.Flags = &pPresentationParameters->Flags;
localParameters.FullScreen_RefreshRateInHz = &pPresentationParameters->FullScreen_RefreshRateInHz;
- localParameters.PresentationInterval = &pPresentationParameters->PresentationInterval;
- return IWineD3D_CreateDevice(This->WineD3D, Adapter, DeviceType, hFocusWindow, BehaviourFlags, &localParameters, &object->WineD3DDevice, (IUnknown *)object, D3D9CB_CreateRenderTarget);
+ localParameters.PresentationInterval = &pPresentationParameters->PresentationInterval;
+
+ hr =IWineD3D_CreateDevice(This->WineD3D, Adapter, DeviceType, hFocusWindow, BehaviourFlags, &localParameters, &object->WineD3DDevice, (IUnknown *)object, D3D9CB_CreateAdditionalSwapChain);
+
+ if (hr == D3D_OK) {
+
+ TRACE("(%p) : Created Device %p\n", This, object);
+ } else {
+ HeapFree(GetProcessHeap(), 0, object);
+ *ppReturnedDeviceInterface = NULL;
+ }
+ return hr;
}
+
+
const IDirect3D9Vtbl Direct3D9_Vtbl =
{
IDirect3D9Impl_QueryInterface,
diff --git a/dlls/d3d9/swapchain.c b/dlls/d3d9/swapchain.c
index 93ce291..dbe23d1 100644
--- a/dlls/d3d9/swapchain.c
+++ b/dlls/d3d9/swapchain.c
@@ -3,6 +3,7 @@
*
* Copyright 2002-2003 Jason Edmeades
* Raphael Junqueira
+ * Copyright 2005 Oliver Stieber
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -22,7 +23,7 @@
#include "config.h"
#include "d3d9_private.h"
-WINE_DEFAULT_DEBUG_CHANNEL(d3d);
+WINE_DEFAULT_DEBUG_CHANNEL(d3d9);
/* IDirect3DSwapChain IUnknown parts follow: */
HRESULT WINAPI IDirect3DSwapChain9Impl_QueryInterface(LPDIRECT3DSWAPCHAIN9 iface, REFIID riid, LPVOID* ppobj)
@@ -31,8 +32,8 @@
if (IsEqualGUID(riid, &IID_IUnknown)
|| IsEqualGUID(riid, &IID_IDirect3DSwapChain9)) {
- IDirect3DSwapChain9Impl_AddRef(iface);
- *ppobj = This;
+ IUnknown_AddRef(iface);
+ *ppobj = This;
return D3D_OK;
}
@@ -64,50 +65,62 @@
/* IDirect3DSwapChain9 parts follow: */
HRESULT WINAPI IDirect3DSwapChain9Impl_Present(LPDIRECT3DSWAPCHAIN9 iface, CONST RECT* pSourceRect, CONST RECT* pDestRect, HWND hDestWindowOverride, CONST RGNDATA* pDirtyRegion, DWORD dwFlags) {
IDirect3DSwapChain9Impl *This = (IDirect3DSwapChain9Impl *)iface;
- FIXME("(%p) : stub\n", This);
- return D3D_OK;
+ TRACE("(%p) Relay\n", This);
+ return IWineD3DSwapChain_Present(This->wineD3DSwapChain, pSourceRect, pDestRect, hDestWindowOverride, pDirtyRegion, dwFlags);
}
HRESULT WINAPI IDirect3DSwapChain9Impl_GetFrontBufferData(LPDIRECT3DSWAPCHAIN9 iface, IDirect3DSurface9* pDestSurface) {
IDirect3DSwapChain9Impl *This = (IDirect3DSwapChain9Impl *)iface;
- FIXME("(%p) : stub\n", This);
- return D3D_OK;
+ TRACE("(%p) Relay\n", This);
+ return IWineD3DSwapChain_GetFrontBufferData(This->wineD3DSwapChain, ((IDirect3DSurface9Impl *)pDestSurface)->wineD3DSurface);
}
HRESULT WINAPI IDirect3DSwapChain9Impl_GetBackBuffer(LPDIRECT3DSWAPCHAIN9 iface, UINT iBackBuffer, D3DBACKBUFFER_TYPE Type, IDirect3DSurface9** ppBackBuffer) {
IDirect3DSwapChain9Impl *This = (IDirect3DSwapChain9Impl *)iface;
- FIXME("(%p) : stub\n", This);
- return D3D_OK;
+ HRESULT hrc = D3D_OK;
+ IWineD3DSurface *mySurface = NULL;
+
+ TRACE("(%p) Relay\n", This);
+
+ hrc = IWineD3DSwapChain_GetBackBuffer(This->wineD3DSwapChain, iBackBuffer, Type, &mySurface);
+ if (hrc == D3D_OK && NULL != mySurface) {
+ IWineD3DSurface_GetParent(mySurface, (IUnknown **)ppBackBuffer);
+ IWineD3DSurface_Release(mySurface);
+ }
+ return hrc;
}
HRESULT WINAPI IDirect3DSwapChain9Impl_GetRasterStatus(LPDIRECT3DSWAPCHAIN9 iface, D3DRASTER_STATUS* pRasterStatus) {
IDirect3DSwapChain9Impl *This = (IDirect3DSwapChain9Impl *)iface;
- FIXME("(%p) : stub\n", This);
- return D3D_OK;
+ TRACE("(%p) Relay\n", This);
+ return IWineD3DSwapChain_GetRasterStatus(This->wineD3DSwapChain, pRasterStatus);
}
HRESULT WINAPI IDirect3DSwapChain9Impl_GetDisplayMode(LPDIRECT3DSWAPCHAIN9 iface, D3DDISPLAYMODE* pMode) {
IDirect3DSwapChain9Impl *This = (IDirect3DSwapChain9Impl *)iface;
- FIXME("(%p) : stub\n", This);
- return D3D_OK;
+ TRACE("(%p) Relay\n", This);
+ return IWineD3DSwapChain_GetDisplayMode(This->wineD3DSwapChain, pMode);
}
HRESULT WINAPI IDirect3DSwapChain9Impl_GetDevice(LPDIRECT3DSWAPCHAIN9 iface, IDirect3DDevice9** ppDevice) {
- IDirect3DSwapChain9Impl *This = (IDirect3DSwapChain9Impl *)iface;
- TRACE("(%p) : returning %p\n", This, This->Device);
- *ppDevice = (LPDIRECT3DDEVICE9) This->Device;
+ IDirect3DSwapChain9Impl *This = (IDirect3DSwapChain9Impl *)iface;
+ HRESULT hrc = D3D_OK;
+ IWineD3DDevice *device = NULL;
- /* Note Calling this method will increase the internal reference count
- on the IDirect3DDevice9 interface. */
- IDirect3DDevice9Impl_AddRef(*ppDevice);
- return D3D_OK;
+ TRACE("(%p) Relay\n", This);
+
+ hrc = IWineD3DSwapChain_GetDevice(This->wineD3DSwapChain, &device);
+ if (hrc == D3D_OK && NULL != device) {
+ IWineD3DDevice_GetParent(device, (IUnknown **)ppDevice);
+ IWineD3DDevice_Release(device);
+ }
+ return hrc;
}
HRESULT WINAPI IDirect3DSwapChain9Impl_GetPresentParameters(LPDIRECT3DSWAPCHAIN9 iface, D3DPRESENT_PARAMETERS* pPresentationParameters) {
IDirect3DSwapChain9Impl *This = (IDirect3DSwapChain9Impl *)iface;
- FIXME("(%p) : copy\n", This);
- memcpy(pPresentationParameters, &This->PresentParms, sizeof(D3DPRESENT_PARAMETERS));
- return D3D_OK;
+ FIXME("(%p) : inplement using WINED3DPRESENT_PARAMERS\n", This);
+ return IWineD3DSwapChain_GetPresentParameters(This->wineD3DSwapChain, pPresentationParameters);
}
@@ -129,18 +142,67 @@
/* IDirect3DDevice9 IDirect3DSwapChain9 Methods follow: */
HRESULT WINAPI IDirect3DDevice9Impl_CreateAdditionalSwapChain(LPDIRECT3DDEVICE9 iface, D3DPRESENT_PARAMETERS* pPresentationParameters, IDirect3DSwapChain9** pSwapChain) {
IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
- FIXME("(%p) : stub\n", This);
+ IDirect3DSwapChain9Impl* object;
+ HRESULT hrc = D3D_OK;
+ WINED3DPRESENT_PARAMETERS localParameters;
+
+ TRACE("(%p) Relay\n", This);
+
+ object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
+ if (NULL == object) {
+ FIXME("Allocation of memory failed\n");
+ *pSwapChain = NULL;
+ return D3DERR_OUTOFVIDEOMEMORY;
+ }
+ object->ref = 1;
+ object->lpVtbl = &Direct3DSwapChain9_Vtbl;
+
+ /* Allocate an associated WineD3DDevice object */
+ localParameters.BackBufferWidth = &pPresentationParameters->BackBufferWidth;
+ localParameters.BackBufferHeight = &pPresentationParameters->BackBufferHeight;
+ localParameters.BackBufferFormat = &pPresentationParameters->BackBufferFormat;
+ localParameters.BackBufferCount = &pPresentationParameters->BackBufferCount;
+ localParameters.MultiSampleType = &pPresentationParameters->MultiSampleType;
+ localParameters.MultiSampleQuality = &pPresentationParameters->MultiSampleQuality;
+ localParameters.SwapEffect = &pPresentationParameters->SwapEffect;
+ localParameters.hDeviceWindow = &pPresentationParameters->hDeviceWindow;
+ localParameters.Windowed = &pPresentationParameters->Windowed;
+ localParameters.EnableAutoDepthStencil = &pPresentationParameters->EnableAutoDepthStencil;
+ localParameters.AutoDepthStencilFormat = &pPresentationParameters->AutoDepthStencilFormat;
+ localParameters.Flags = &pPresentationParameters->Flags;
+ localParameters.FullScreen_RefreshRateInHz = &pPresentationParameters->FullScreen_RefreshRateInHz;
+ localParameters.PresentationInterval = &pPresentationParameters->PresentationInterval;
+
+
+ hrc = IWineD3DDevice_CreateAdditionalSwapChain(This->WineD3DDevice, &localParameters, &object->wineD3DSwapChain, (IUnknown*)object, D3D9CB_CreateRenderTarget, D3D9CB_CreateDepthStencilSurface);
+ if (hrc != D3D_OK) {
+ FIXME("(%p) call to IWineD3DDevice_CreateAdditionalSwapChain failed\n", This);
+ HeapFree(GetProcessHeap(), 0 , object);
+ *pSwapChain = NULL;
+ }else{
+ *pSwapChain = (IDirect3DSwapChain9 *)object;
+ }
+ TRACE("(%p) returning %p\n", This, *pSwapChain);
return D3D_OK;
}
HRESULT WINAPI IDirect3DDevice9Impl_GetSwapChain(LPDIRECT3DDEVICE9 iface, UINT iSwapChain, IDirect3DSwapChain9** pSwapChain) {
IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
- FIXME("(%p) : stub\n", This);
- return D3D_OK;
+ HRESULT hrc = D3D_OK;
+ IWineD3DSwapChain *swapchain = NULL;
+
+ TRACE("(%p) Relay\n", This);
+
+ hrc = IWineD3DDevice_GetSwapChain(This->WineD3DDevice, iSwapChain, &swapchain);
+ if (hrc == D3D_OK && NULL != swapchain) {
+ IWineD3DSwapChain_GetParent(swapchain, (IUnknown **)pSwapChain);
+ IWineD3DSwapChain_Release(swapchain);
+ }
+ return hrc;
}
UINT WINAPI IDirect3DDevice9Impl_GetNumberOfSwapChains(LPDIRECT3DDEVICE9 iface) {
IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
- FIXME("(%p) : stub\n", This);
- return 1;
+ TRACE("(%p) Relay\n", This);
+ return IWineD3DDevice_GetNumberOfSwapChains(This->WineD3DDevice);
}
diff --git a/dlls/wined3d/Makefile.in b/dlls/wined3d/Makefile.in
index 6c8e2e7..51bb669 100644
--- a/dlls/wined3d/Makefile.in
+++ b/dlls/wined3d/Makefile.in
@@ -19,6 +19,7 @@
resource.c \
stateblock.c \
surface.c \
+ swapchain.c \
texture.c \
utils.c \
vertexbuffer.c \
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index 7e59670..da38662 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -30,6 +30,26 @@
WINE_DECLARE_DEBUG_CHANNEL(d3d_shader);
#define GLINFO_LOCATION ((IWineD3DImpl *)(This->wineD3D))->gl_info
+/* x11drv GDI escapes */
+#define X11DRV_ESCAPE 6789
+enum x11drv_escape_codes
+{
+ X11DRV_GET_DISPLAY, /* get X11 display for a DC */
+ X11DRV_GET_DRAWABLE, /* get current drawable for a DC */
+ X11DRV_GET_FONT, /* get current X font for a DC */
+};
+
+/* retrieve the X display to use on a given DC */
+inline static Display *get_display( HDC hdc )
+{
+ Display *display;
+ enum x11drv_escape_codes escape = X11DRV_GET_DISPLAY;
+
+ if (!ExtEscape( hdc, X11DRV_ESCAPE, sizeof(escape), (LPCSTR)&escape,
+ sizeof(display), (LPSTR)&display )) display = NULL;
+ return display;
+}
+
/* helper macros */
#define D3DMEMCHECK(object, ppResult) if(NULL == object){ *ppResult = NULL; WARN("Out of memory\n"); return D3DERR_OUTOFVIDEOMEMORY;}
@@ -275,7 +295,29 @@
if (((IWineD3DImpl *)This->wineD3D)->dxVersion > 8) { /*We don't create a state block in d3d8 yet*/
/* NOTE: You must release the parent if the objects was created via a callback
** ***************************/
- IWineD3DStateBlock_Release((IWineD3DStateBlock *)This->stateBlock);
+ int i;
+ IUnknown* swapChainParent;
+
+ /* Release all of the swapchains, except the implicite swapchain (#0) */
+ for(i = 1; i < This->numberOfSwapChains; i++){
+ /* TODO: don't access swapchains[x] directly! */
+ IWineD3DSwapChain_Release(This->swapchains[i]);
+ }
+
+ if (This->stateBlock != NULL) {
+ IWineD3DStateBlock_Release((IWineD3DStateBlock *)This->stateBlock);
+ }
+
+ if (This->swapchains[0] != NULL) {
+ /* Swapchain 0 is special because it's created in startup with a hanging parent, so we have to release it's parent now */
+ /* TODO: don't access swapchains[x] directly!, check that there are no-more swapchains left for this device! */
+ IWineD3DSwapChain_GetParent(This->swapchains[0], &swapChainParent);
+ IUnknown_Release(swapChainParent); /* once for the get parent */
+ if (IUnknown_Release(swapChainParent) > 0){ /* the second time for when it was created */
+ FIXME("(%p) Something's still holding the implicite swapchain\n",This);
+ }
+ }
+
}
IWineD3D_Release(This->wineD3D);
HeapFree(GetProcessHeap(), 0, This);
@@ -412,11 +454,11 @@
while (pow2Width < Width) pow2Width <<= 1;
while (pow2Height < Height) pow2Height <<= 1;
- if(pow2Width > Width || pow2Height > Height){
- FIXME("non-power-two textures unsupported\n"); /* OpenGL provides support for these gratis */
+ if((pow2Width > Width || pow2Height > Height) && !Usage & D3DUSAGE_RENDERTARGET) {
+ /** TODO: add support for non power two textures (OpenGL 2 provices support for * non-power-two textures gratis) **/
+ FIXME("non-power-two textures unsupported\n");
return D3DERR_NOTAVAILABLE;
}
-
/** TODO: Check against the maximum texture sizes supported by the video card **/
@@ -779,28 +821,418 @@
}
/* example at http://www.fairyengine.com/articles/dxmultiviews.htm */
-HRESULT WINAPI IWineD3DDeviceImpl_CreateAdditionalSwapChain(IWineD3DDevice* iface, WINED3DPRESENT_PARAMETERS* pPresentationParameters, void** ppSwapChain,
+HRESULT WINAPI IWineD3DDeviceImpl_CreateAdditionalSwapChain(IWineD3DDevice* iface, WINED3DPRESENT_PARAMETERS* pPresentationParameters, IWineD3DSwapChain** ppSwapChain,
IUnknown* parent,
D3DCB_CREATERENDERTARGETFN D3DCB_CreateRenderTarget,
D3DCB_CREATEDEPTHSTENCILSURFACEFN D3DCB_CreateDepthStencil){
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
- *ppSwapChain = NULL;
- FIXME("(%p) : Stub\n",This);
- return D3D_OK;
+
+ HDC hDc;
+ IWineD3DSwapChainImpl *object; /** NOTE: impl ref allowed since this is a create function **/
+ int num;
+ XVisualInfo template;
+ GLXContext oldContext;
+ Drawable oldDrawable;
+ HRESULT hr = D3D_OK;
+
+ TRACE("(%p) : Created Aditional Swap Chain\n", This);
+
+ /** FIXME: Test under windows to find out what the life cycle of a swap chain is,
+ * does a device hold a reference to a swap chain giving them a lifetime of the device
+ * or does the swap chain notify the device of it'd destruction.
+ *******************************/
+
+ D3DCREATEOBJECTINSTANCE(object, SwapChain)
+
+ /* Initialize other useful values */
+ object->presentParms.BackBufferCount = 1; /* TODO:? support for gl_aux buffers */
+
+ /*********************
+ * Lookup the window Handle and the relating X window handle
+ ********************/
+
+ /* Setup hwnd we are using, plus which display this equates to */
+ object->win_handle = *(pPresentationParameters->hDeviceWindow);
+ if (!object->win_handle) {
+ object->win_handle = This->createParms.hFocusWindow;
+ }
+
+ object->win = (Window)GetPropA(object->win_handle, "__wine_x11_whole_window" );
+ hDc = GetDC(object->win_handle);
+ object->display = get_display(hDc);
+ ReleaseDC(object->win_handle, hDc);
+ TRACE("Using a display of %p %p \n", object->display, hDc);
+
+ if (NULL == object->display || NULL == hDc) {
+ WARN("Failed to get a display and HDc for Window %p\n", object->win_handle);
+ return D3DERR_NOTAVAILABLE;
+ }
+
+ if (object->win == 0) {
+ WARN("Failed to get a valid XVisuial ID for the window %p\n", object->win_handle);
+ return D3DERR_NOTAVAILABLE;
+ }
+ /**
+ * Create an opengl context for the display visual
+ * NOTE: the visual is chosen as the window is created and the glcontext cannot
+ * use different properties after that point in time. FIXME: How to handle when requested format
+ * doesn't match actual visual? Cannot choose one here - code removed as it ONLY works if the one
+ * it chooses is identical to the one already being used!
+ **********************************/
+
+ /** FIXME: Handle stencil appropriately via EnableAutoDepthStencil / AutoDepthStencilFormat **/
+ ENTER_GL();
+
+ /* Create a new context for this swapchain */
+ template.visualid = (VisualID)GetPropA(GetDesktopWindow(), "__wine_x11_visual_id");
+ /* TODO: change this to find a similar visual, but one with a stencil/zbuffer buffer that matches the request
+ (or the best possible if none is requested) */
+ TRACE("Found x visual ID : %ld\n", template.visualid);
+
+ object->visInfo = XGetVisualInfo(object->display, VisualIDMask, &template, &num);
+ if (NULL == object->visInfo) {
+ ERR("cannot really get XVisual\n");
+ LEAVE_GL();
+ return D3DERR_NOTAVAILABLE;
+ } else {
+ int n, value;
+ /* Write out some debug info about the visual/s */
+ TRACE("Using x visual ID : %ld\n", template.visualid);
+ TRACE(" visual info: %p\n", object->visInfo);
+ TRACE(" num items : %d\n", num);
+ for(n = 0;n < num; n++){
+ TRACE("=====item=====: %d\n", n + 1);
+ TRACE(" visualid : %ld\n", object->visInfo[n].visualid);
+ TRACE(" screen : %d\n", object->visInfo[n].screen);
+ TRACE(" depth : %u\n", object->visInfo[n].depth);
+ TRACE(" class : %d\n", object->visInfo[n].class);
+ TRACE(" red_mask : %ld\n", object->visInfo[n].red_mask);
+ TRACE(" green_mask : %ld\n", object->visInfo[n].green_mask);
+ TRACE(" blue_mask : %ld\n", object->visInfo[n].blue_mask);
+ TRACE(" colormap_size : %d\n", object->visInfo[n].colormap_size);
+ TRACE(" bits_per_rgb : %d\n", object->visInfo[n].bits_per_rgb);
+ /* log some extra glx info */
+ glXGetConfig(object->display, object->visInfo, GLX_AUX_BUFFERS, &value);
+ TRACE(" gl_aux_buffers : %d\n", value);
+ glXGetConfig(object->display, object->visInfo, GLX_BUFFER_SIZE ,&value);
+ TRACE(" gl_buffer_size : %d\n", value);
+ glXGetConfig(object->display, object->visInfo, GLX_RED_SIZE, &value);
+ TRACE(" gl_red_size : %d\n", value);
+ glXGetConfig(object->display, object->visInfo, GLX_GREEN_SIZE, &value);
+ TRACE(" gl_green_size : %d\n", value);
+ glXGetConfig(object->display, object->visInfo, GLX_BLUE_SIZE, &value);
+ TRACE(" gl_blue_size : %d\n", value);
+ glXGetConfig(object->display, object->visInfo, GLX_ALPHA_SIZE, &value);
+ TRACE(" gl_alpha_size : %d\n", value);
+ glXGetConfig(object->display, object->visInfo, GLX_DEPTH_SIZE ,&value);
+ TRACE(" gl_depth_size : %d\n", value);
+ glXGetConfig(object->display, object->visInfo, GLX_STENCIL_SIZE, &value);
+ TRACE(" gl_stencil_size : %d\n", value);
+ }
+ /* Now choose a simila visual ID*/
+ }
+#ifdef USE_CONTEXT_MANAGER
+
+ /** TODO: use a context mamager **/
+#endif
+
+ {
+ IWineD3DSwapChain *implSwapChain;
+ if (D3D_OK != IWineD3DDevice_GetSwapChain(iface, 0, &implSwapChain)) {
+ /* The first time around we create the context that is shared with all other swapchians and render targets */
+ object->glCtx = glXCreateContext(object->display, object->visInfo, NULL, GL_TRUE);
+ TRACE("Creating implicite context for vis %p, hwnd %p\n", object->display, object->visInfo);
+ } else {
+
+ TRACE("Creating context for vis %p, hwnd %p\n", object->display, object->visInfo);
+ /* TODO: don't use Impl structures outside of create functions! (a context manager will replace the ->glCtx) */
+ /* and create a new context with the implicit swapchains context as the shared context */
+ object->glCtx = glXCreateContext(object->display, object->visInfo, ((IWineD3DSwapChainImpl *)implSwapChain)->glCtx, GL_TRUE);
+ IWineD3DSwapChain_Release(implSwapChain);
+ }
+ }
+
+ /* Cleanup */
+ XFree(object->visInfo);
+ object->visInfo = NULL;
+
+ if (NULL == object->glCtx) {
+ ERR("cannot create glxContext\n");
+ LEAVE_GL();
+ return D3DERR_NOTAVAILABLE;
+ }
+
+ LEAVE_GL();
+ if (object->glCtx == NULL) {
+ ERR("Error in context creation !\n");
+ return D3DERR_INVALIDCALL;
+ } else {
+ TRACE("Context created (HWND=%p, glContext=%p, Window=%ld, VisInfo=%p)\n",
+ object->win_handle, object->glCtx, object->win, object->visInfo);
+ }
+
+ /*********************
+ * Windowed / Fullscreen
+ *******************/
+
+ /**
+ * TODO: MSDNsays that we are only allowed one fullscreen swapchain per device,
+ * so we should really check to see if their is a fullscreen swapchain already
+ * I think Windows and X have differnt ideas about fullscreen, does a single head count as full screen?
+ **************************************/
+
+ if (!*(pPresentationParameters->Windowed)) {
+
+ DEVMODEW devmode;
+ HDC hdc;
+ int bpp = 0;
+
+ /* Get info on the current display setup */
+ hdc = CreateDCA("DISPLAY", NULL, NULL, NULL);
+ bpp = GetDeviceCaps(hdc, BITSPIXEL);
+ DeleteDC(hdc);
+
+ /* Change the display settings */
+ memset(&devmode, 0, sizeof(DEVMODEW));
+ devmode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;
+ devmode.dmBitsPerPel = (bpp >= 24) ? 32 : bpp; /* Stupid XVidMode cannot change bpp */
+ devmode.dmPelsWidth = *(pPresentationParameters->BackBufferWidth);
+ devmode.dmPelsHeight = *(pPresentationParameters->BackBufferHeight);
+ MultiByteToWideChar(CP_ACP, 0, "Gamers CG", -1, devmode.dmDeviceName, CCHDEVICENAME);
+ ChangeDisplaySettingsExW(devmode.dmDeviceName, &devmode, object->win_handle, CDS_FULLSCREEN, NULL);
+
+ /* Make popup window */
+ SetWindowLongA(object->win_handle, GWL_STYLE, WS_POPUP);
+ SetWindowPos(object->win_handle, HWND_TOP, 0, 0,
+ *(pPresentationParameters->BackBufferWidth),
+ *(pPresentationParameters->BackBufferHeight), SWP_SHOWWINDOW | SWP_FRAMECHANGED);
+
+
+ }
+
+
+ /** MSDN: If Windowed is TRUE and either of the BackBufferWidth/Height values is zero,
+ * then the corresponding dimension of the client area of the hDeviceWindow
+ * (or the focus window, if hDeviceWindow is NULL) is taken.
+ **********************/
+
+ if (*(pPresentationParameters->Windowed) &&
+ ((*(pPresentationParameters->BackBufferWidth) == 0) ||
+ (*(pPresentationParameters->BackBufferHeight) == 0))) {
+
+ RECT Rect;
+ GetClientRect(object->win_handle, &Rect);
+
+ if (*(pPresentationParameters->BackBufferWidth) == 0) {
+ *(pPresentationParameters->BackBufferWidth) = Rect.right;
+ TRACE("Updating width to %d\n", *(pPresentationParameters->BackBufferWidth));
+ }
+ if (*(pPresentationParameters->BackBufferHeight) == 0) {
+ *(pPresentationParameters->BackBufferHeight) = Rect.bottom;
+ TRACE("Updating height to %d\n", *(pPresentationParameters->BackBufferHeight));
+ }
+ }
+
+ /*********************
+ * finish off parameter initialization
+ *******************/
+
+ /* Put the correct figures in the presentation parameters */
+ TRACE("Coppying accross presentaion paraneters\n");
+ object->presentParms.BackBufferWidth = *(pPresentationParameters->BackBufferWidth);
+ object->presentParms.BackBufferHeight = *(pPresentationParameters->BackBufferHeight);
+ object->presentParms.BackBufferFormat = *(pPresentationParameters->BackBufferFormat);
+ object->presentParms.BackBufferCount = *(pPresentationParameters->BackBufferCount);
+ object->presentParms.MultiSampleType = *(pPresentationParameters->MultiSampleType);
+ object->presentParms.MultiSampleQuality = *(pPresentationParameters->MultiSampleQuality);
+ object->presentParms.SwapEffect = *(pPresentationParameters->SwapEffect);
+ object->presentParms.hDeviceWindow = *(pPresentationParameters->hDeviceWindow);
+ object->presentParms.Windowed = *(pPresentationParameters->Windowed);
+ object->presentParms.EnableAutoDepthStencil = *(pPresentationParameters->EnableAutoDepthStencil);
+ object->presentParms.AutoDepthStencilFormat = *(pPresentationParameters->AutoDepthStencilFormat);
+ object->presentParms.Flags = *(pPresentationParameters->Flags);
+ object->presentParms.FullScreen_RefreshRateInHz = *(pPresentationParameters->FullScreen_RefreshRateInHz);
+ object->presentParms.PresentationInterval = *(pPresentationParameters->PresentationInterval);
+
+
+ /* FIXME: check for any failures */
+ /*********************
+ * Create the back, front and stencil buffers
+ *******************/
+ TRACE("calling rendertarget CB\n");
+ hr = D3DCB_CreateRenderTarget((IUnknown *) This->parent,
+ object->presentParms.BackBufferWidth,
+ object->presentParms.BackBufferHeight,
+ object->presentParms.BackBufferFormat,
+ object->presentParms.MultiSampleType,
+ object->presentParms.MultiSampleQuality,
+ TRUE /* Lockable */,
+ &object->frontBuffer,
+ NULL /* pShared (always null)*/);
+ if (object->frontBuffer != NULL)
+ IWineD3DSurface_SetContainer(object->frontBuffer, (IUnknown *)object);
+ TRACE("calling rendertarget CB\n");
+ hr = D3DCB_CreateRenderTarget((IUnknown *) This->parent,
+ object->presentParms.BackBufferWidth,
+ object->presentParms.BackBufferHeight,
+ object->presentParms.BackBufferFormat,
+ object->presentParms.MultiSampleType,
+ object->presentParms.MultiSampleQuality,
+ TRUE /* Lockable */,
+ &object->backBuffer,
+ NULL /* pShared (always null)*/);
+ if (object->backBuffer != NULL)
+ IWineD3DSurface_SetContainer(object->backBuffer, (IUnknown *)object);
+
+ /* Under directX swapchains share the depth stencil, so only create one depth-stencil */
+ if (pPresentationParameters->EnableAutoDepthStencil) {
+ TRACE("Creating depth stencil buffer\n");
+ if (This->depthStencilBuffer == NULL ) {
+ hr = D3DCB_CreateDepthStencil((IUnknown *) This->parent,
+ object->presentParms.BackBufferWidth,
+ object->presentParms.BackBufferHeight,
+ object->presentParms.AutoDepthStencilFormat,
+ object->presentParms.MultiSampleType,
+ object->presentParms.MultiSampleQuality,
+ FALSE /* FIXME: Discard */,
+ &This->depthStencilBuffer,
+ NULL /* pShared (always null)*/ );
+ if (This->depthStencilBuffer != NULL)
+ IWineD3DSurface_SetContainer(This->depthStencilBuffer, (IUnknown *)iface);
+ }
+
+ /** TODO: A check on width, height and multisample types
+ *(since the zbuffer must be at least as large as the render target and have the same multisample parameters)
+ ****************************/
+ object->wantsDepthStencilBuffer = TRUE;
+ } else {
+ object->wantsDepthStencilBuffer = FALSE;
+ }
+
+ TRACE("FrontBuf @ %p, BackBuf @ %p, DepthStencil %d\n",object->frontBuffer, object->backBuffer, object->wantsDepthStencilBuffer);
+
+
+ /*********************
+ * init the default renderTarget management
+ *******************/
+ object->drawable = object->win;
+ object->render_ctx = object->glCtx;
+
+ if(hr == D3D_OK){
+ /*********************
+ * Setup some defaults and clear down the buffers
+ *******************/
+ ENTER_GL();
+ /** save current context and drawable **/
+ oldContext = glXGetCurrentContext();
+ oldDrawable = glXGetCurrentDrawable();
+
+ TRACE("Activating context (display %p context %p drawable %ld)!\n", object->display, object->glCtx, object->win);
+ if (glXMakeCurrent(object->display, object->win, object->glCtx) == False) {
+ ERR("Error in setting current context (display %p context %p drawable %ld)!\n", object->display, object->glCtx, object->win);
+ }
+ checkGLcall("glXMakeCurrent");
+
+ TRACE("Setting up the screen\n");
+ /* Clear the screen */
+ glClearColor(0.0, 0.0, 0.0, 0.0);
+ checkGLcall("glClearColor");
+ glClearIndex(0);
+ glClearDepth(1);
+ glClearStencil(0xffff);
+
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_ACCUM_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
+ checkGLcall("glClear");
+
+ glColor3f(1.0, 1.0, 1.0);
+ checkGLcall("glColor3f");
+
+ glEnable(GL_LIGHTING);
+ checkGLcall("glEnable");
+
+ glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);
+ checkGLcall("glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);");
+
+ glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
+ checkGLcall("glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);");
+
+ glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR);
+ checkGLcall("glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR);");
+
+ /* switch back to the original context (unless it was zero)*/
+ if (This->numberOfSwapChains != 0) {
+ /** TODO: restore the context and drawable **/
+ glXMakeCurrent(object->display, oldDrawable, oldContext);
+ }
+
+ LEAVE_GL();
+
+ /* TODO: move this off into a linked list implementation! (add swapchain, remove swapchain or something along those lines) */
+#if 0
+ IListOperator *listOperator;
+ IListStore_CreateListOperator(This->swapchainStore, &listOperator);
+ IListOperator_Append(listOperator, (void *)object);
+ IListOperator_Release(listOperator);
+#endif
+
+ This->swapchains[This->numberOfSwapChains++] = (IWineD3DSwapChain *)object;
+ TRACE("Set swapchain to %p\n", object);
+ } else { /* something went wrong so clean up */
+ IUnknown* bufferParent;
+ if (object->frontBuffer) {
+ IWineD3DSurface_GetParent(object->frontBuffer, &bufferParent);
+ IUnknown_Release(bufferParent); /* once for the get parent */
+ if(IUnknown_Release(bufferParent) > 0){
+ FIXME("(%p) Something's still holding the front buffer\n",This);
+ }
+ }
+ if (object->backBuffer) {
+ IWineD3DSurface_GetParent(object->backBuffer, &bufferParent);
+ IUnknown_Release(bufferParent); /* once for the get parent */
+ if(IUnknown_Release(bufferParent) > 0){
+ FIXME("(%p) Something's still holding the back buffer\n",This);
+ }
+ }
+ /* NOTE: don't clean up the depthstencil buffer because it belongs to the device */
+ /* Clean up the context */
+ /* check that we are the current context first (we shouldn't be though!) */
+ if (object->glCtx != 0) {
+ if(glXGetCurrentContext() == object->glCtx){
+ glXMakeCurrent(object->display, None, NULL);
+ }
+ glXDestroyContext(object->display, object->glCtx);
+ }
+ HeapFree(GetProcessHeap(), 0, object);
+
+ }
+ return hr;
}
/** NOTE: These are ahead of the other getters and setters to save using a forward declartion **/
UINT WINAPI IWineD3DDeviceImpl_GetNumberOfSwapChains(IWineD3DDevice *iface) {
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
-
- FIXME("(%p) : Stub\n",This);
- return 1;
+
+ /* TODO: move over to using a linked list. */
+ TRACE("(%p) returning %d\n", This, This->numberOfSwapChains);
+ return This->numberOfSwapChains;
}
-HRESULT WINAPI IWineD3DDeviceImpl_GetSwapChain(IWineD3DDevice *iface, UINT iSwapChain, void** pSwapChain) {
+HRESULT WINAPI IWineD3DDeviceImpl_GetSwapChain(IWineD3DDevice *iface, UINT iSwapChain, IWineD3DSwapChain **pSwapChain) {
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
-
- FIXME("(%p) : Stub\n",This);
+ TRACE("(%p) : swapchain %d \n", This, iSwapChain);
+
+ if(iSwapChain >= IWineD3DDeviceImpl_GetNumberOfSwapChains(iface) || iSwapChain < 0){
+ *pSwapChain = NULL;
+ return D3DERR_INVALIDCALL;
+ }else{
+ /** TODO: move off to a linked list implementation **/
+ *pSwapChain = This->swapchains[iSwapChain];
+ }
+
+ /* TODO: move over to using stores and linked lists. */
+
+ IWineD3DSwapChain_AddRef(*pSwapChain);
+ TRACE("(%p) returning %p\n", This, *pSwapChain);
return D3D_OK;
}
@@ -3611,19 +4043,19 @@
HRESULT WINAPI IWineD3DDeviceImpl_GetBackBuffer(IWineD3DDevice *iface, UINT iSwapChain, UINT BackBuffer, D3DBACKBUFFER_TYPE Type,
IWineD3DSurface** ppBackBuffer) {
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
-
- *ppBackBuffer = (IWineD3DSurface *) This->backBuffer;
+ IWineD3DSwapChain *swapChain;
+ HRESULT hr;
+
TRACE("(%p) : BackBuf %d Type %d SwapChain %d returning %p\n", This, BackBuffer, Type, iSwapChain, *ppBackBuffer);
- if (BackBuffer > This->presentParms.BackBufferCount - 1) {
- FIXME("Only one backBuffer currently supported\n");
- return D3DERR_INVALIDCALL;
+ hr = IWineD3DDeviceImpl_GetSwapChain(iface, iSwapChain, &swapChain);
+ if(hr == D3D_OK){
+ hr = IWineD3DSwapChain_GetBackBuffer(swapChain, BackBuffer, Type, ppBackBuffer);
+ IWineD3DSwapChain_Release(swapChain);
+ }else{
+ *ppBackBuffer = NULL;
}
-
- /* Note inc ref on returned surface */
- IWineD3DSurface_AddRef(*ppBackBuffer);
-
- return D3D_OK;
+ return hr;
}
HRESULT WINAPI IWineD3DDeviceImpl_GetDeviceCaps(IWineD3DDevice *iface, WINED3DCAPS* pCaps) {
@@ -3632,33 +4064,19 @@
return IWineD3D_GetDeviceCaps(This->wineD3D, This->adapterNo, This->devType, pCaps);
}
-/** TODO: move to swapchains **/
HRESULT WINAPI IWineD3DDeviceImpl_GetDisplayMode(IWineD3DDevice *iface, UINT iSwapChain, D3DDISPLAYMODE* pMode) {
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
- HDC hdc;
- int bpp = 0;
+ IWineD3DSwapChain *swapChain;
+ HRESULT hr;
- pMode->Width = GetSystemMetrics(SM_CXSCREEN);
- pMode->Height = GetSystemMetrics(SM_CYSCREEN);
- pMode->RefreshRate = 85; /*FIXME: How to identify? */
-
- hdc = CreateDCA("DISPLAY", NULL, NULL, NULL);
- bpp = GetDeviceCaps(hdc, BITSPIXEL);
- DeleteDC(hdc);
-
- switch (bpp) {
- case 8: pMode->Format = WINED3DFMT_R8G8B8; break;
- case 16: pMode->Format = WINED3DFMT_R5G6B5; break;
- case 24: /*pMode->Format = WINED3DFMT_R8G8B8; break; */
- case 32: pMode->Format = WINED3DFMT_A8R8G8B8; break;
- default:
- FIXME("Unrecognized display mode format\n");
- pMode->Format = WINED3DFMT_UNKNOWN;
+ hr = IWineD3DDeviceImpl_GetSwapChain(iface, iSwapChain, (IWineD3DSwapChain **)&swapChain);
+ if (hr == D3D_OK) {
+ hr = IWineD3DSwapChain_GetDisplayMode(swapChain, pMode);
+ IWineD3DSwapChain_Release(swapChain);
+ }else{
+ FIXME("(%p) Error getting display mode\n", This);
}
-
- FIXME("(%p) : returning w(%d) h(%d) rr(%d) fmt(%u,%s)\n", This, pMode->Width, pMode->Height, pMode->RefreshRate,
- pMode->Format, debug_d3dformat(pMode->Format));
- return D3D_OK;
+ return hr;
}
/*****
* Stateblock related functions
@@ -3753,76 +4171,19 @@
HRESULT WINAPI IWineD3DDeviceImpl_Present(IWineD3DDevice *iface,
CONST RECT* pSourceRect, CONST RECT* pDestRect,
HWND hDestWindowOverride, CONST RGNDATA* pDirtyRegion) {
- IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
+ IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
+ IWineD3DSwapChain *swapChain = NULL;
+ int i;
+ int swapchains = IWineD3DDeviceImpl_GetNumberOfSwapChains(iface);
+
TRACE("(%p) Presenting the frame\n", This);
- ENTER_GL();
+ for(i = 0 ; i < swapchains ; i ++){
- if (pSourceRect || pDestRect) FIXME("Unhandled present options %p/%p\n", pSourceRect, pDestRect);
-
- glXSwapBuffers(This->display, This->drawable);
- /* Don't call checkGLcall, as glGetError is not applicable here */
-
- TRACE("glXSwapBuffers called, Starting new frame\n");
-
- /* FPS support */
- if (TRACE_ON(d3d_fps))
- {
- static long prev_time, frames;
-
- DWORD time = GetTickCount();
- frames++;
- /* every 1.5 seconds */
- if (time - prev_time > 1500) {
- TRACE_(d3d_fps)("@ approx %.2ffps\n", 1000.0*frames/(time - prev_time));
- prev_time = time;
- frames = 0;
- }
- }
-
-#if defined(FRAME_DEBUGGING)
-{
- if (GetFileAttributesA("C:\\D3DTRACE") != INVALID_FILE_ATTRIBUTES) {
- if (!isOn) {
- isOn = TRUE;
- FIXME("Enabling D3D Trace\n");
- __WINE_SET_DEBUGGING(__WINE_DBCL_TRACE, __wine_dbch_d3d, 1);
-#if defined(SHOW_FRAME_MAKEUP)
- FIXME("Singe Frame snapshots Starting\n");
- isDumpingFrames = TRUE;
- glClear(GL_COLOR_BUFFER_BIT);
-#endif
-
-#if defined(SINGLE_FRAME_DEBUGGING)
- } else {
-#if defined(SHOW_FRAME_MAKEUP)
- FIXME("Singe Frame snapshots Finishing\n");
- isDumpingFrames = FALSE;
-#endif
- FIXME("Singe Frame trace complete\n");
- DeleteFileA("C:\\D3DTRACE");
- __WINE_SET_DEBUGGING(__WINE_DBCL_TRACE, __wine_dbch_d3d, 0);
-#endif
- }
- } else {
- if (isOn) {
- isOn = FALSE;
-#if defined(SHOW_FRAME_MAKEUP)
- FIXME("Singe Frame snapshots Finishing\n");
- isDumpingFrames = FALSE;
-#endif
- FIXME("Disabling D3D Trace\n");
- __WINE_SET_DEBUGGING(__WINE_DBCL_TRACE, __wine_dbch_d3d, 0);
- }
- }
-}
-#endif
-
- LEAVE_GL();
- /* Although this is not strictly required, a simple demo showed this does occur
- on (at least non-debug) d3d */
- if (This->presentParms.SwapEffect == D3DSWAPEFFECT_DISCARD) {
- IWineD3DDevice_Clear(iface, 0, NULL, D3DCLEAR_STENCIL|D3DCLEAR_ZBUFFER|D3DCLEAR_TARGET, 0x00, 1.0, 0);
+ IWineD3DDeviceImpl_GetSwapChain(iface, i , (IWineD3DSwapChain **)&swapChain);
+ TRACE("presentinng chain %d, %p\n", i, swapChain);
+ IWineD3DSwapChain_Present(swapChain, pSourceRect, pDestRect, hDestWindowOverride, pDirtyRegion, 0);
+ IWineD3DSwapChain_Release(swapChain);
}
return D3D_OK;
@@ -4076,10 +4437,14 @@
}
HRESULT WINAPI IWineD3DDeviceImpl_GetFrontBufferData(IWineD3DDevice *iface,UINT iSwapChain, IWineD3DSurface *pDestSurface){
- IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
-
- TRACE("(%p) : stub\n", This);
- return D3D_OK;
+ IWineD3DSwapChain *swapChain;
+ HRESULT hr;
+ hr = IWineD3DDeviceImpl_GetSwapChain(iface, iSwapChain, (IWineD3DSwapChain **)&swapChain);
+ if(hr == D3D_OK){
+ hr = IWineD3DSwapChain_GetFrontBufferData(swapChain, pDestSurface);
+ IWineD3DSwapChain_Release(swapChain);
+ }
+ return hr;
}
HRESULT WINAPI IWineD3DDeviceImpl_ValidateDevice(IWineD3DDevice *iface, DWORD* pNumPasses) {
@@ -4344,24 +4709,28 @@
}
void WINAPI IWineD3DDeviceImpl_SetGammaRamp(IWineD3DDevice * iface, UINT iSwapChain, DWORD Flags, CONST D3DGAMMARAMP* pRamp) {
- HDC hDC;
- IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *) iface;
-
- FIXME("(%p) : pRamp@%p\n", This, pRamp);
- hDC = GetDC(This->win_handle);
- SetDeviceGammaRamp(hDC, (LPVOID) pRamp);
- ReleaseDC(This->win_handle, hDC);
+ IWineD3DSwapChain *swapchain;
+ HRESULT hrc = D3D_OK;
+
+ TRACE("Relaying to swapchain\n");
+
+ if ((hrc = IWineD3DDeviceImpl_GetSwapChain(iface, iSwapChain, &swapchain)) == D3D_OK){
+ IWineD3DSwapChain_SetGammaRamp(swapchain, Flags, (D3DGAMMARAMP *)pRamp);
+ IWineD3DSwapChain_Release(swapchain);
+ }
return;
}
void WINAPI IWineD3DDeviceImpl_GetGammaRamp(IWineD3DDevice *iface, UINT iSwapChain, D3DGAMMARAMP* pRamp) {
- HDC hDC;
- IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *) iface;
+ IWineD3DSwapChain *swapchain;
+ HRESULT hrc = D3D_OK;
- FIXME("(%p) : pRamp@%p\n", This, pRamp);
- hDC = GetDC(This->win_handle);
- GetDeviceGammaRamp(hDC, pRamp);
- ReleaseDC(This->win_handle, hDC);
+ TRACE("Relaying to swapchain\n");
+
+ if ((hrc = IWineD3DDeviceImpl_GetSwapChain(iface, iSwapChain, &swapchain)) == D3D_OK){
+ hrc =IWineD3DSwapChain_GetGammaRamp(swapchain, pRamp);
+ IWineD3DSwapChain_Release(swapchain);
+ }
return;
}
diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c
index deb5e19..e0caaf0 100644
--- a/dlls/wined3d/directx.c
+++ b/dlls/wined3d/directx.c
@@ -4,6 +4,7 @@
* Copyright 2002-2004 Jason Edmeades
* Copyright 2003-2004 Raphael Junqueira
* Copyright 2004 Christian Costa
+ * Copyright 2005 Oliver Stieber
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -1526,15 +1527,12 @@
and fields being inserted in the middle, a new structure is used in place */
HRESULT WINAPI IWineD3DImpl_CreateDevice(IWineD3D *iface, UINT Adapter, D3DDEVTYPE DeviceType, HWND hFocusWindow,
DWORD BehaviourFlags, WINED3DPRESENT_PARAMETERS* pPresentationParameters,
- IWineD3DDevice** ppReturnedDeviceInterface, IUnknown *parent, D3DCB_CREATERENDERTARGETFN D3DCB_CreateRenderTarget) {
+ IWineD3DDevice** ppReturnedDeviceInterface, IUnknown *parent,
+ D3DCB_CREATEADDITIONALSWAPCHAIN D3DCB_CreateAdditionalSwapChain) {
- HWND whichHWND;
- HDC hDc;
IWineD3DDeviceImpl *object = NULL;
IWineD3DImpl *This = (IWineD3DImpl *)iface;
- int num;
- XVisualInfo template;
- HRESULT res;
+ IWineD3DSwapChainImpl *swapchain;
/* Validate the adapter number */
if (Adapter >= IWineD3D_GetAdapterCount(iface)) {
@@ -1573,241 +1571,85 @@
object->adapterNo = Adapter;
object->devType = DeviceType;
- /* Setup hwnd we are using, plus which display this equates to */
- whichHWND = *(pPresentationParameters->hDeviceWindow);
- if (!whichHWND) {
- whichHWND = hFocusWindow;
- }
- object->win_handle = whichHWND;
- object->win = (Window)GetPropA( whichHWND, "__wine_x11_whole_window" );
- hDc = GetDC(whichHWND);
- object->display = get_display(hDc);
- ReleaseDC(whichHWND, hDc);
-
/* FIXME: Use for dx8 code eventually too! */
/* Deliberately no indentation here, as this if will be removed when dx8 support merged in */
- if (This->dxVersion > 8) {
+ if (This->dxVersion > 8) {
- /* Create a context based off the properties of the existing visual */
- /* Note the visual is chosen as the window is created and the glcontext cannot
- use different properties after that point in time. FIXME: How to handle when requested format
- doesn't match actual visual? Cannot choose one here - code removed as it ONLY works if the one
- it chooses is identical to the one already being used! */
- /* FIXME: Handle stencil appropriately via EnableAutoDepthStencil / AutoDepthStencilFormat */
- ENTER_GL();
- template.visualid = (VisualID)GetPropA(GetDesktopWindow(), "__wine_x11_visual_id");
- object->visInfo = XGetVisualInfo(object->display, VisualIDMask, &template, &num);
- if (NULL == object->visInfo) {
- ERR("cannot really get XVisual\n");
- LEAVE_GL();
- return D3DERR_NOTAVAILABLE;
- }
- object->glCtx = glXCreateContext(object->display, object->visInfo, NULL, GL_TRUE);
- if (NULL == object->glCtx) {
- ERR("cannot create glxContext\n");
- LEAVE_GL();
- return D3DERR_NOTAVAILABLE;
- }
- LEAVE_GL();
+ /* Creating the startup stateBlock - Note Special Case: 0 => Don't fill in yet! */
+ IWineD3DDevice_CreateStateBlock((IWineD3DDevice *)object,
+ (D3DSTATEBLOCKTYPE) 0,
+ (IWineD3DStateBlock **)&object->stateBlock,
+ NULL); /* Note: No parent needed for initial internal stateblock */
+ object->updateStateBlock = object->stateBlock;
+ IWineD3DStateBlock_AddRef((IWineD3DStateBlock*)object->updateStateBlock);
+ /* Setup surfaces for the backbuffer, frontbuffer and depthstencil buffer */
- if (object->glCtx == NULL) {
- ERR("Error in context creation !\n");
- return D3DERR_INVALIDCALL;
- } else {
- TRACE("Context created (HWND=%p, glContext=%p, Window=%ld, VisInfo=%p)\n",
- whichHWND, object->glCtx, object->win, object->visInfo);
- }
+ /* Setup the implicite swapchain */
+ TRACE("Creating implicite swapchain\n");
- /* If not windowed, need to go fullscreen, and resize the HWND to the appropriate */
- /* dimensions */
- if (!*(pPresentationParameters->Windowed)) {
+ if (D3D_OK == D3DCB_CreateAdditionalSwapChain((IUnknown *) object->parent, pPresentationParameters, (IWineD3DSwapChain **)&swapchain) && swapchain != NULL) {
- DEVMODEW devmode;
- HDC hdc;
- int bpp = 0;
-
- /* Get info on the current display setup */
- hdc = CreateDCA("DISPLAY", NULL, NULL, NULL);
- bpp = GetDeviceCaps(hdc, BITSPIXEL);
- DeleteDC(hdc);
-
- /* Change the display settings */
- memset(&devmode, 0, sizeof(DEVMODEW));
- devmode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;
- devmode.dmBitsPerPel = (bpp >= 24) ? 32 : bpp; /*Stupid XVidMode cannot change bpp D3DFmtGetBpp(object, pPresentationParameters->BackBufferFormat);*/
- devmode.dmPelsWidth = *(pPresentationParameters->BackBufferWidth);
- devmode.dmPelsHeight = *(pPresentationParameters->BackBufferHeight);
- MultiByteToWideChar(CP_ACP, 0, "Gamers CG", -1, devmode.dmDeviceName, CCHDEVICENAME);
- ChangeDisplaySettingsExW(devmode.dmDeviceName, &devmode, object->win_handle, CDS_FULLSCREEN, NULL);
-
- /* Make popup window */
- SetWindowLongA(whichHWND, GWL_STYLE, WS_POPUP);
- SetWindowPos(object->win_handle, HWND_TOP, 0, 0,
- *(pPresentationParameters->BackBufferWidth),
- *(pPresentationParameters->BackBufferHeight), SWP_SHOWWINDOW | SWP_FRAMECHANGED);
- }
-
- /* MSDN: If Windowed is TRUE and either of the BackBufferWidth/Height values is zero,
- then the corresponding dimension of the client area of the hDeviceWindow
- (or the focus window, if hDeviceWindow is NULL) is taken. */
- if (*(pPresentationParameters->Windowed) &&
- ((*(pPresentationParameters->BackBufferWidth) == 0) ||
- (*(pPresentationParameters->BackBufferHeight) == 0))) {
-
- RECT Rect;
- GetClientRect(whichHWND, &Rect);
-
- if (*(pPresentationParameters->BackBufferWidth) == 0) {
- *(pPresentationParameters->BackBufferWidth) = Rect.right;
- TRACE("Updating width to %d\n", *(pPresentationParameters->BackBufferWidth));
- }
- if (*(pPresentationParameters->BackBufferHeight) == 0) {
- *(pPresentationParameters->BackBufferHeight) = Rect.bottom;
- TRACE("Updating height to %d\n", *(pPresentationParameters->BackBufferHeight));
- }
- }
-
- /* Save the presentation parms now filled in correctly */
- object->presentParms.BackBufferWidth = *(pPresentationParameters->BackBufferWidth);
- object->presentParms.BackBufferHeight = *(pPresentationParameters->BackBufferHeight);
- object->presentParms.BackBufferFormat = *(pPresentationParameters->BackBufferFormat);
- object->presentParms.BackBufferCount = *(pPresentationParameters->BackBufferCount);
- object->presentParms.MultiSampleType = *(pPresentationParameters->MultiSampleType);
- object->presentParms.MultiSampleQuality = *(pPresentationParameters->MultiSampleQuality);
- object->presentParms.SwapEffect = *(pPresentationParameters->SwapEffect);
- object->presentParms.hDeviceWindow = *(pPresentationParameters->hDeviceWindow);
- object->presentParms.Windowed = *(pPresentationParameters->Windowed);
- object->presentParms.EnableAutoDepthStencil = *(pPresentationParameters->EnableAutoDepthStencil);
- object->presentParms.AutoDepthStencilFormat = *(pPresentationParameters->AutoDepthStencilFormat);
- object->presentParms.Flags = *(pPresentationParameters->Flags);
- object->presentParms.FullScreen_RefreshRateInHz = *(pPresentationParameters->FullScreen_RefreshRateInHz);
- object->presentParms.PresentationInterval = *(pPresentationParameters->PresentationInterval);
-
- /* Creating the startup stateBlock - Note Special Case: 0 => Don't fill in yet! */
- IWineD3DDevice_CreateStateBlock((IWineD3DDevice *)object,
- (D3DSTATEBLOCKTYPE) 0,
- (IWineD3DStateBlock **)&object->stateBlock,
- NULL); /* Note: No parent needed for initial internal stateblock */
- object->updateStateBlock = object->stateBlock;
-
- /* Setup surfaces for the backbuffer, frontbuffer and depthstencil buffer */
- TRACE("Creating initial device surfaces\n");
-
- /* We need to 'magic' either d3d8 or d3d9 surfaces for the front and backbuuffer
- but the respective CreateRenderTarget functions take a differing number of
- parms. Fix this by passing in a function to call which takes identical parms
- and handles the differences at the d3dx layer, and returns the IWineD3DSurface
- pointer rather than the created D3D8/9 one */
- if ((res = D3DCB_CreateRenderTarget((IUnknown *) parent,
- *(pPresentationParameters->BackBufferWidth),
- *(pPresentationParameters->BackBufferHeight),
- *(pPresentationParameters->BackBufferFormat),
- *(pPresentationParameters->MultiSampleType),
- *(pPresentationParameters->MultiSampleQuality),
- TRUE,
- (IWineD3DSurface **) &object->frontBuffer,
- NULL) != D3D_OK) ||
- (res = D3DCB_CreateRenderTarget((IUnknown *) parent,
- *(pPresentationParameters->BackBufferWidth),
- *(pPresentationParameters->BackBufferHeight),
- *(pPresentationParameters->BackBufferFormat),
- *(pPresentationParameters->MultiSampleType),
- *(pPresentationParameters->MultiSampleQuality),
- TRUE,
- (IWineD3DSurface **) &object->backBuffer,
- NULL) != D3D_OK))
- {
- ERR("D3DCB_CreateRenderTarget() failed\n");
- return res;
- }
-
-/* TODO:
- if (*(pPresentationParameters->EnableAutoDepthStencil)) {
- IWineD3DDevice_CreateDepthStencilSurface((IWineD3DDevice *) object,
- *(pPresentationParameters->BackBufferWidth),
- *(pPresentationParameters->BackBufferHeight),
- *(pPresentationParameters->AutoDepthStencilFormat,
- D3DMULTISAMPLE_NONE,
- (IWineD3DSurface *) &object->depthStencilBuffer);
- } else {
- object->depthStencilBuffer = NULL;
- }
- TRACE("FrontBuf @ %p, BackBuf @ %p, DepthStencil @ %p\n",object->frontBuffer, object->backBuffer, object->depthStencilBuffer);
-*/
-
- /* init the default renderTarget management */
- object->drawable = object->win;
- object->render_ctx = object->glCtx;
- object->renderTarget = object->backBuffer;
+ object->renderTarget = swapchain->backBuffer;
+ IWineD3DSurface_AddRef(object->renderTarget);
+ /* Depth Stencil support */
+ object->stencilBufferTarget = object->depthStencilBuffer;
+ if (NULL != object->stencilBufferTarget) {
+ IWineD3DSurface_AddRef(object->stencilBufferTarget);
+ }
- IWineD3DSurface_AddRef((IWineD3DSurface *) object->renderTarget);
-/* TODO: Depth Stencil support
- object->stencilBufferTarget = object->depthStencilBuffer;
- if (NULL != object->stencilBufferTarget) {
- IDirect3DSurface8Impl_AddRef((LPDIRECT3DSURFACE8) object->stencilBufferTarget);
+ /* Set up some starting GL setup */
+
+ ENTER_GL();
+ /*
+ * Initialize openGL extension related variables
+ * with Default values
+ */
+
+ This->isGLInfoValid = IWineD3DImpl_FillGLCaps(&This->gl_info, swapchain->display);
+ /* Setup all the devices defaults */
+ IWineD3DStateBlock_InitStartupStateBlock((IWineD3DStateBlock *)object->stateBlock);
+#if 0
+ IWineD3DImpl_CheckGraphicsMemory();
+#endif
+ LEAVE_GL();
+
+ { /* Set a default viewport */
+ D3DVIEWPORT9 vp;
+ vp.X = 0;
+ vp.Y = 0;
+ vp.Width = *(pPresentationParameters->BackBufferWidth);
+ vp.Height = *(pPresentationParameters->BackBufferHeight);
+ vp.MinZ = 0.0f;
+ vp.MaxZ = 1.0f;
+ IWineD3DDevice_SetViewport((IWineD3DDevice *)object, &vp);
+ }
+
+
+ /* Initialize the current view state */
+ object->modelview_valid = 1;
+ object->proj_valid = 0;
+ object->view_ident = 1;
+ object->last_was_rhw = 0;
+ glGetIntegerv(GL_MAX_LIGHTS, &object->maxConcurrentLights);
+ TRACE("(%p,%d) All defaults now set up, leaving CreateDevice with %p\n", This, Adapter, object);
+
+ /* Clear the screen */
+ IWineD3DDevice_Clear((IWineD3DDevice *) object, 0, NULL, D3DCLEAR_STENCIL|D3DCLEAR_ZBUFFER|D3DCLEAR_TARGET, 0x00, 1.0, 0);
+ } else { /* couldn't create swapchain */
+ IWineD3DStateBlock_Release((IWineD3DStateBlock *)object->updateStateBlock);
+ object->updateStateBlock = NULL;
+ IWineD3DStateBlock_Release((IWineD3DStateBlock *)object->stateBlock);
+ object->stateBlock = NULL;
+ HeapFree(GetProcessHeap(), 0, object);
+ *ppReturnedDeviceInterface = NULL;
+ return D3DERR_INVALIDCALL;
+ }
+
+ } else { /* End of FIXME: remove when dx8 merged in */
+
+ FIXME("(%p) Incomplete stub for d3d8\n", This);
+
}
-*/
-
- /* Set up some starting GL setup */
- ENTER_GL();
-
- if (glXMakeCurrent(object->display, object->win, object->glCtx) == False) {
- ERR("Error in setting current context (context %p drawable %ld)!\n", object->glCtx, object->win);
- }
- checkGLcall("glXMakeCurrent");
-
- /* Clear the screen */
- glClearColor(1.0, 0.0, 0.0, 0.0);
- checkGLcall("glClearColor");
- glColor3f(1.0, 1.0, 1.0);
- checkGLcall("glColor3f");
-
- glEnable(GL_LIGHTING);
- checkGLcall("glEnable");
-
- glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);
- checkGLcall("glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);");
-
- glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
- checkGLcall("glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);");
-
- glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR);
- checkGLcall("glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR);");
-
- /*
- * Initialize openGL extension related variables
- * with Default values
- */
- This->isGLInfoValid = IWineD3DImpl_FillGLCaps(&This->gl_info, object->display);
-
- /* Setup all the devices defaults */
- IWineD3DStateBlock_InitStartupStateBlock((IWineD3DStateBlock *)object->stateBlock);
-
- LEAVE_GL();
-
- { /* Set a default viewport */
- D3DVIEWPORT9 vp;
- vp.X = 0;
- vp.Y = 0;
- vp.Width = *(pPresentationParameters->BackBufferWidth);
- vp.Height = *(pPresentationParameters->BackBufferHeight);
- vp.MinZ = 0.0f;
- vp.MaxZ = 1.0f;
- IWineD3DDevice_SetViewport((IWineD3DDevice *)object, &vp);
- }
-
- /* Initialize the current view state */
- object->modelview_valid = 1;
- object->proj_valid = 0;
- object->view_ident = 1;
- object->last_was_rhw = 0;
- glGetIntegerv(GL_MAX_LIGHTS, &object->maxConcurrentLights);
- TRACE("(%p,%d) All defaults now set up, leaving CreateDevice with %p\n", This, Adapter, object);
-
- /* Clear the screen */
- IWineD3DDevice_Clear((IWineD3DDevice *) object, 0, NULL, D3DCLEAR_STENCIL|D3DCLEAR_ZBUFFER|D3DCLEAR_TARGET, 0x00, 1.0, 0);
-
- } /* End of FIXME: remove when dx8 merged in */
return D3D_OK;
}
diff --git a/dlls/wined3d/swapchain.c b/dlls/wined3d/swapchain.c
new file mode 100644
index 0000000..4dae6d2
--- /dev/null
+++ b/dlls/wined3d/swapchain.c
@@ -0,0 +1,458 @@
+/*
+ *IDirect3DSwapChain9 implementation
+ *
+ *Copyright 2002-2003 Jason Edmeades
+ *Copyright 2002-2003 Raphael Junqueira
+ *Copyright 2005 Oliver Stieber
+ *
+ *This library is free software; you can redistribute it and/or
+ *modify it under the terms of the GNU Lesser General Public
+ *License as published by the Free Software Foundation; either
+ *version 2.1 of the License, or (at your option) any later version.
+ *
+ *This library is distributed in the hope that it will be useful,
+ *but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ *Lesser General Public License for more details.
+ *
+ *You should have received a copy of the GNU Lesser General Public
+ *License along with this library; if not, write to the Free Software
+ *Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "config.h"
+#include "wined3d_private.h"
+
+
+/* TODO: move to shared header (or context manager )*/
+/* x11drv GDI escapes */
+#define X11DRV_ESCAPE 6789
+enum x11drv_escape_codes
+{
+ X11DRV_GET_DISPLAY, /* get X11 display for a DC */
+ X11DRV_GET_DRAWABLE, /* get current drawable for a DC */
+ X11DRV_GET_FONT, /* get current X font for a DC */
+};
+
+/* retrieve the X display to use on a given DC */
+inline static Display *get_display( HDC hdc )
+{
+ Display *display;
+ enum x11drv_escape_codes escape = X11DRV_GET_DISPLAY;
+
+ if (!ExtEscape( hdc, X11DRV_ESCAPE, sizeof(escape), (LPCSTR)&escape,
+ sizeof(display), (LPSTR)&display )) display = NULL;
+ return display;
+}
+
+/*TODO: some of the additional parameters may be required to
+ set the gamma ramp (for some weird reason microsoft have left swap gammaramp in device
+ but it operates on a swapchain, it may be a good idea to move it to IWineD3DSwapChain for IWineD3D)*/
+
+
+WINE_DEFAULT_DEBUG_CHANNEL(d3d);
+WINE_DECLARE_DEBUG_CHANNEL(d3d_fps);
+
+
+/* IDirect3DSwapChain IUnknown parts follow: */
+ULONG WINAPI IWineD3DSwapChainImpl_AddRef(IWineD3DSwapChain *iface) {
+ IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface;
+ DWORD refCount = InterlockedIncrement(&This->ref);
+ TRACE("(%p) : AddRef increasing from %ld\n", This, refCount - 1);
+ return refCount;
+}
+
+HRESULT WINAPI IWineD3DSwapChainImpl_QueryInterface(IWineD3DSwapChain *iface, REFIID riid, LPVOID *ppobj)
+{
+ IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface;
+ TRACE("(%p)->(%s,%p) \n",This,debugstr_guid(riid),ppobj);
+ if (IsEqualGUID(riid, &IID_IUnknown)
+ || IsEqualGUID(riid, &IID_IWineD3DSwapChain)){
+ IWineD3DSwapChainImpl_AddRef(iface);
+ if(ppobj == NULL){
+ ERR("Query interface called but now data allocated\n");
+ return E_NOINTERFACE;
+ }
+ *ppobj = This;
+ return D3D_OK;
+ }
+ return E_NOINTERFACE;
+}
+
+
+ULONG WINAPI IWineD3DSwapChainImpl_Release(IWineD3DSwapChain *iface) {
+ IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface;
+ DWORD refCount;
+ refCount = InterlockedDecrement(&This->ref);
+ TRACE("(%p) : ReleaseRef to %ld\n", This, refCount);
+ if (refCount == 0) {
+ IUnknown* bufferParent;
+ IWineD3DSurface_GetParent(This->frontBuffer, &bufferParent);
+ IUnknown_Release(bufferParent); /* once for the get parent */
+ if(IUnknown_Release(bufferParent) > 0){
+ FIXME("(%p) Something's still holding the front buffer\n",This);
+ }
+
+ IWineD3DSurface_GetParent(This->backBuffer, &bufferParent);
+ IUnknown_Release(bufferParent); /* once for the get parent */
+ if(IUnknown_Release(bufferParent) > 0){
+ FIXME("(%p) Something's still holding the back buffer\n",This);
+ }
+ /* Clean up the context */
+ /* check that we are the current context first */
+ if(glXGetCurrentContext() == This->glCtx){
+ glXMakeCurrent(This->display, None, NULL);
+ }
+ glXDestroyContext(This->display, This->glCtx);
+ /* IUnknown_Release(This->parent); This should only apply to the primary swapchain,
+ all others are crated by the caller, so releasing the parent should cause
+ the child to be released, not the other way around!
+ */
+ /* TODO: notify the device that this swapchain doesn't exist any more */
+ HeapFree(GetProcessHeap(), 0, This);
+ }
+ return refCount;
+}
+
+HRESULT WINAPI IWineD3DSwapChainImpl_GetParent(IWineD3DSwapChain *iface, IUnknown ** ppParent){
+ IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface;
+ *ppParent = This->parent;
+ IUnknown_AddRef(*ppParent);
+ TRACE("(%p) returning %p\n", This , *ppParent);
+ return D3D_OK;
+}
+
+/*IWineD3DSwapChain parts follow: */
+HRESULT WINAPI IWineD3DSwapChainImpl_Present(IWineD3DSwapChain *iface, CONST RECT *pSourceRect, CONST RECT *pDestRect, HWND hDestWindowOverride, CONST RGNDATA *pDirtyRegion, DWORD dwFlags) {
+ IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface;
+
+ ENTER_GL();
+
+ if (pSourceRect || pDestRect) FIXME("Unhandled present options %p/%p\n", pSourceRect, pDestRect);
+ /* TODO: If only source rect or dest rect are supplied then clip the window to match */
+ TRACE("preseting display %p, drawable %ld\n", This->display, This->drawable);
+
+ /* Don't call checkGLcall, as glGetError is not applicable here */
+ if (hDestWindowOverride && This->win_handle != hDestWindowOverride) {
+ /* Set this swapchain up to point to the new destination.. */
+#ifdef USE_CONTEXT_MANAGER
+ /* TODO: use a context mamager */
+#endif
+
+ /* FIXME: Never access */
+ IWineD3DSwapChainImpl *swapChainImpl;
+ IWineD3DDevice_GetSwapChain((IWineD3DDevice *)This->wineD3DDevice, 0 , (IWineD3DSwapChain **)&swapChainImpl);
+ FIXME("Unable to render to a destination window %d\n", (int)hDestWindowOverride );
+ if(This == swapChainImpl){
+ /* FIXME: this will be fixed by moving to a context management system */
+ FIXME("Cannot change the target of the implicite swapchain\n");
+ }else{
+ HDC hDc;
+ XVisualInfo template;
+ int num;
+ Display *oldDisplay = This->display;
+ GLXContext oldContext = This->glCtx;
+ IUnknown* tmp;
+ GLXContext currentContext;
+ Drawable currentDrawable;
+ hDc = GetDC(hDestWindowOverride);
+ This->win_handle = hDestWindowOverride;
+ This->win = (Window)GetPropA( hDestWindowOverride, "__wine_x11_whole_window" );
+
+ TRACE("Creating a new context for the window %p \n", hDestWindowOverride);
+ ENTER_GL();
+ TRACE("Desctroying context %p %p\n", This->display, This->render_ctx);
+
+
+
+ LEAVE_GL();
+ ENTER_GL();
+
+ This->display = get_display(hDc);
+ TRACE("Got display%p for %p %p\n", This->display, hDc, hDestWindowOverride);
+ ReleaseDC(hDestWindowOverride, hDc);
+ template.visualid = (VisualID)GetPropA(GetDesktopWindow(), "__wine_x11_visual_id");
+ This->visInfo = XGetVisualInfo(This->display, VisualIDMask, &template, &num);
+ if (NULL == This->visInfo) {
+ ERR("cannot really get XVisual\n");
+ LEAVE_GL();
+ return D3DERR_NOTAVAILABLE;
+ }
+ /* Now we have problems? well not really we just need to know what the implicite context is */
+ /* now destroy the old context and create a new one (we should really copy the buffers over, and do the whole make current thing! */
+ /* destroy the active context?*/
+ TRACE("Creating new context for %p %p %p\n",This->display, This->visInfo, swapChainImpl->glCtx);
+ This->glCtx = glXCreateContext(This->display, This->visInfo, swapChainImpl->glCtx, GL_TRUE);
+
+ if (NULL == This->glCtx) {
+ ERR("cannot create glxContext\n");
+ }
+ This->drawable = This->win;
+ This->render_ctx = This->glCtx;
+ /* SEtup some default states TODO: apply the stateblock to the new context */
+ /** save current context and drawable **/
+ currentContext = glXGetCurrentContext();
+ currentDrawable = glXGetCurrentDrawable();
+
+ if (glXMakeCurrent(This->display, This->win, This->glCtx) == False) {
+ ERR("Error in setting current context (display %p context %p drawable %ld)!\n", This->display, This->glCtx, This->win);
+ }
+
+ checkGLcall("glXMakeCurrent");
+
+ /* Clear the screen */
+ glClearColor(0.0, 0.0, 0.0, 0.0);
+ checkGLcall("glClearColor");
+ glClearIndex(0);
+ glClearDepth(1);
+ glClearStencil(0);
+
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_ACCUM_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
+ checkGLcall("glClear");
+
+ glColor3f(1.0, 1.0, 1.0);
+ checkGLcall("glColor3f");
+
+ glEnable(GL_LIGHTING);
+ checkGLcall("glEnable");
+
+ glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);
+ checkGLcall("glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);");
+
+ glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
+ checkGLcall("glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);");
+
+ glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR);
+ checkGLcall("glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR);");
+
+ /* If this swapchain is currently the active context then make this swapchain active */
+ if(IWineD3DSurface_GetContainer((IWineD3DSurface *)This->wineD3DDevice->renderTarget, &IID_IWineD3DSwapChain, (void **)&tmp) == D3D_OK){
+ if(tmp != (IUnknown *)This){
+ glXMakeCurrent(This->display, currentDrawable, currentContext);
+ checkGLcall("glXMakeCurrent");
+ }
+ IUnknown_Release(tmp);
+ }else{
+ /* reset the context */
+ glXMakeCurrent(This->display, currentDrawable, currentContext);
+ checkGLcall("glXMakeCurrent");
+ }
+ /* delete the old contxt*/
+ glXDestroyContext(oldDisplay, oldContext); /* Should this happen on an active context? seems a bad idea */
+ LEAVE_GL();
+ }
+ IWineD3DSwapChain_Release((IWineD3DSwapChain *)swapChainImpl);
+
+ }
+
+
+ /* TODO: The slow way, save the data to memory, create a new context for the destination window, transfer the data cleanup, it may be a good idea to the move this swapchain over to the using the target winows context so that it runs faster in feature. */
+
+ glXSwapBuffers(This->display, This->drawable); /* TODO: cycle through the swapchain buffers */
+
+ TRACE("glXSwapBuffers called, Starting new frame\n");
+ /* FPS support */
+ if (TRACE_ON(d3d_fps))
+ {
+ static long prev_time, frames;
+
+ DWORD time = GetTickCount();
+ frames++;
+ /* every 1.5 seconds */
+ if (time - prev_time > 1500) {
+ TRACE_(d3d_fps)("@ approx %.2ffps\n", 1000.0*frames/(time - prev_time));
+ prev_time = time;
+ frames = 0;
+ }
+ }
+
+#if defined(FRAME_DEBUGGING)
+{
+ if (GetFileAttributesA("C:\\D3DTRACE") != INVALID_FILE_ATTRIBUTES) {
+ if (!isOn) {
+ isOn = TRUE;
+ FIXME("Enabling D3D Trace\n");
+ __WINE_SET_DEBUGGING(__WINE_DBCL_TRACE, __wine_dbch_d3d, 1);
+#if defined(SHOW_FRAME_MAKEUP)
+ FIXME("Singe Frame snapshots Starting\n");
+ isDumpingFrames = TRUE;
+ glClear(GL_COLOR_BUFFER_BIT);
+#endif
+
+#if defined(SINGLE_FRAME_DEBUGGING)
+ } else {
+#if defined(SHOW_FRAME_MAKEUP)
+ FIXME("Singe Frame snapshots Finishing\n");
+ isDumpingFrames = FALSE;
+#endif
+ FIXME("Singe Frame trace complete\n");
+ DeleteFileA("C:\\D3DTRACE");
+ __WINE_SET_DEBUGGING(__WINE_DBCL_TRACE, __wine_dbch_d3d, 0);
+#endif
+ }
+ } else {
+ if (isOn) {
+ isOn = FALSE;
+#if defined(SHOW_FRAME_MAKEUP)
+ FIXME("Single Frame snapshots Finishing\n");
+ isDumpingFrames = FALSE;
+#endif
+ FIXME("Disabling D3D Trace\n");
+ __WINE_SET_DEBUGGING(__WINE_DBCL_TRACE, __wine_dbch_d3d, 0);
+ }
+ }
+}
+#endif
+
+ LEAVE_GL();
+ /* Although this is not strictly required, a simple demo showed this does occur
+ on (at least non-debug) d3d */
+ if (This->presentParms.SwapEffect & D3DSWAPEFFECT_DISCARD) {
+
+ TRACE("Clearing\n");
+
+ IWineD3DDevice_Clear((IWineD3DDevice*)This->wineD3DDevice, 0, NULL, D3DCLEAR_STENCIL|D3DCLEAR_ZBUFFER|D3DCLEAR_TARGET, 0x00, 1.0, 0);
+
+ }
+ TRACE("returning\n");
+ return D3D_OK;
+}
+
+HRESULT WINAPI IWineD3DSwapChainImpl_GetFrontBufferData(IWineD3DSwapChain *iface, IWineD3DSurface *pDestSurface) {
+ IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface;
+ IWineD3DSurfaceImpl *surface = (IWineD3DSurfaceImpl *)pDestSurface;
+ GLenum format;
+ GLenum type;
+
+ TRACE("(%p) : iface(%p) pDestSurface(%p) \n", This, iface, pDestSurface);
+ ENTER_GL();
+
+ /* check to see if it's the backbuffer or the frontbuffer being requested (to make sureteh data is upto date) */
+ format = D3DFmt2GLFmt(This->wineD3DDevice, surface->resource.format);
+ type = D3DFmt2GLType(This->wineD3DDevice, surface->resource.format);
+ glReadBuffer(GL_FRONT);
+ glReadPixels(0,
+ 0,
+ surface->currentDesc.Width,
+ surface->currentDesc.Height,
+ format,
+ type,
+ surface->resource.allocatedMemory);
+ LEAVE_GL();
+ return D3D_OK;
+}
+
+HRESULT WINAPI IWineD3DSwapChainImpl_GetBackBuffer(IWineD3DSwapChain *iface, UINT iBackBuffer, D3DBACKBUFFER_TYPE Type, IWineD3DSurface **ppBackBuffer) {
+
+ IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface;
+
+ *ppBackBuffer = (IWineD3DSurface *) This->backBuffer;
+ TRACE("(%p) : BackBuf %d Type %d returning %p\n", This, iBackBuffer, Type, *ppBackBuffer);
+
+ if (iBackBuffer > This->presentParms.BackBufferCount - 1) {
+ FIXME("Only one backBuffer currently supported\n");
+ return D3DERR_INVALIDCALL;
+ }
+
+ /* Note inc ref on returned surface */
+ IWineD3DSurface_AddRef(*ppBackBuffer);
+ return D3D_OK;
+
+}
+
+HRESULT WINAPI IWineD3DSwapChainImpl_GetRasterStatus(IWineD3DSwapChain *iface, D3DRASTER_STATUS*pRasterStatus) {
+ IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface;
+ pRasterStatus->InVBlank = TRUE;
+ pRasterStatus->ScanLine = 0;
+ FIXME("(%p) : stub\n", This);
+ return D3D_OK;
+}
+
+HRESULT WINAPI IWineD3DSwapChainImpl_GetDisplayMode(IWineD3DSwapChain *iface, D3DDISPLAYMODE*pMode) {
+ IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface;
+ HDC hdc;
+ int bpp = 0;
+
+ pMode->Width = GetSystemMetrics(SM_CXSCREEN);
+ pMode->Height = GetSystemMetrics(SM_CYSCREEN);
+ pMode->RefreshRate = 85; /* FIXME: How to identify? */
+
+ hdc = CreateDCA("DISPLAY", NULL, NULL, NULL);
+ bpp = GetDeviceCaps(hdc, BITSPIXEL);
+ DeleteDC(hdc);
+
+ switch (bpp) {
+ case 8: pMode->Format = D3DFMT_R8G8B8; break;
+ case 16: pMode->Format = D3DFMT_R5G6B5; break;
+ case 24: /*pMode->Format = D3DFMT_R8G8B8; break; */ /* 32bpp and 24bpp can be aliased for X */
+ case 32: pMode->Format = D3DFMT_A8R8G8B8; break;
+ default:
+ FIXME("Unrecognized display mode format\n");
+ pMode->Format = D3DFMT_UNKNOWN;
+ }
+
+ TRACE("(%p) : returning w(%d) h(%d) rr(%d) fmt(%u,%s)\n", This, pMode->Width, pMode->Height, pMode->RefreshRate,
+ pMode->Format, debug_d3dformat(pMode->Format));
+ return D3D_OK;
+}
+
+HRESULT WINAPI IWineD3DSwapChainImpl_GetDevice(IWineD3DSwapChain *iface, IWineD3DDevice**ppDevice) {
+ IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface;
+
+ *ppDevice = (IWineD3DDevice *) This->wineD3DDevice;
+
+ /* Note Calling this method will increase the internal reference count
+ on the IDirect3DDevice9 interface. */
+ IWineD3DDevice_AddRef(*ppDevice);
+ TRACE("(%p) : returning %p\n", This, *ppDevice);
+ return D3D_OK;
+}
+
+HRESULT WINAPI IWineD3DSwapChainImpl_GetPresentParameters(IWineD3DSwapChain *iface, D3DPRESENT_PARAMETERS *pPresentationParameters) {
+ IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface;
+ FIXME("(%p) : copy\n", This);
+ memcpy(pPresentationParameters, &This->presentParms, sizeof(D3DPRESENT_PARAMETERS));
+ return D3D_OK;
+}
+
+HRESULT WINAPI IWineD3DSwapChainImpl_SetGammaRamp(IWineD3DSwapChain *iface, DWORD Flags, CONST D3DGAMMARAMP *pRamp){
+
+ IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface;
+ HDC hDC;
+ TRACE("(%p) : pRamp@%p flags(%ld) \n", This, pRamp, Flags);
+ hDC = GetDC(This->win_handle);
+ SetDeviceGammaRamp(hDC, (LPVOID)pRamp);
+ ReleaseDC(This->win_handle, hDC);
+ return D3D_OK;
+
+}
+
+HRESULT WINAPI IWineD3DSwapChainImpl_GetGammaRamp(IWineD3DSwapChain *iface, D3DGAMMARAMP *pRamp){
+
+ IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface;
+ HDC hDC;
+ TRACE("(%p) : pRamp@%p\n", This, pRamp);
+ hDC = GetDC(This->win_handle);
+ GetDeviceGammaRamp(hDC, pRamp);
+ ReleaseDC(This->win_handle, hDC);
+ return D3D_OK;
+
+}
+
+
+IWineD3DSwapChainVtbl IWineD3DSwapChain_Vtbl =
+{
+ IWineD3DSwapChainImpl_QueryInterface,
+ IWineD3DSwapChainImpl_AddRef,
+ IWineD3DSwapChainImpl_Release,
+ IWineD3DSwapChainImpl_GetParent,
+ IWineD3DSwapChainImpl_GetDevice,
+ IWineD3DSwapChainImpl_Present,
+ IWineD3DSwapChainImpl_GetFrontBufferData,
+ IWineD3DSwapChainImpl_GetBackBuffer,
+ IWineD3DSwapChainImpl_GetRasterStatus,
+ IWineD3DSwapChainImpl_GetDisplayMode,
+ IWineD3DSwapChainImpl_GetPresentParameters,
+ IWineD3DSwapChainImpl_SetGammaRamp,
+ IWineD3DSwapChainImpl_GetGammaRamp
+};
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index b5a8cc9..d2baf75 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -3,7 +3,8 @@
*
* Copyright 2002-2003 The wine-d3d team
* Copyright 2002-2003 Raphael Junqueira
- * Copyright 2004 Jason Edmeades
+ * Copyright 2004 Jason Edmeades
+ * Copyright 2005 Oliver Stieber
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -41,6 +42,9 @@
#include "wine/wined3d_interface.h"
#include "wine/wined3d_gl.h"
+/* Swap chains */
+#define MAX_SWAPCHAINS 256
+
extern int vs_mode;
#define VS_NONE 0
#define VS_HW 1
@@ -339,13 +343,6 @@
IWineD3D *wineD3D;
/* X and GL Information */
- HWND win_handle;
- Window win;
- Display *display;
- GLXContext glCtx;
- XVisualInfo *visInfo;
- GLXContext render_ctx;
- Drawable drawable;
GLint maxConcurrentLights;
/* Optimization */
@@ -376,6 +373,10 @@
UINT adapterNo;
D3DDEVTYPE devType;
+ /* TODO: Replace with a linked list */
+ IWineD3DSwapChain *swapchains[MAX_SWAPCHAINS]; /* no-one wil ever need more that MAX_SWAPCHAINS swapchains */
+ int numberOfSwapChains;
+
/* Render Target Support */
IWineD3DSurface *frontBuffer;
IWineD3DSurface *backBuffer;
@@ -754,6 +755,43 @@
extern const IWineD3DQueryVtbl IWineD3DQuery_Vtbl;
/*****************************************************************************
+ * IWineD3DSwapChainImpl implementation structure (extends IUnknown)
+ */
+
+typedef struct IWineD3DSwapChainImpl
+{
+ /*IUnknown part*/
+ IWineD3DSwapChainVtbl *lpVtbl;
+ DWORD ref; /* Note: Ref counting not required */
+
+ IUnknown *parent;
+ IWineD3DDeviceImpl *wineD3DDevice;
+
+ /* IWineD3DSwapChain fields */
+ IWineD3DSurface *backBuffer;
+ IWineD3DSurface *frontBuffer;
+ BOOL wantsDepthStencilBuffer;
+ D3DPRESENT_PARAMETERS presentParms;
+
+ /* TODO: move everything upto drawable off into a context manager
+ and store the 'data' in the contextManagerData interface.
+ IUnknown *contextManagerData;
+ */
+
+ HWND win_handle;
+ Window win;
+ Display *display;
+
+ GLXContext glCtx;
+ XVisualInfo *visInfo;
+ GLXContext render_ctx;
+ /* This has been left in device for now, but needs moving off into a rendertarget mamangement class and seperated out from swapchains and devices. */
+ Drawable drawable;
+} IWineD3DSwapChainImpl;
+
+extern IWineD3DSwapChainVtbl IWineD3DSwapChain_Vtbl;
+
+/*****************************************************************************
* Utility function prototypes
*/