Implement swapchains.

This commit is contained in:
Oliver Stieber 2005-06-23 11:05:24 +00:00 committed by Alexandre Julliard
parent a9b5052ff9
commit 46e7c30a71
12 changed files with 1399 additions and 460 deletions

View File

@ -655,6 +655,9 @@ struct IDirect3DSwapChain8Impl
/* OpenGL/GLX related */
GLXContext swap_ctx;
Drawable swap_drawable;
/* ready for when we move over to wined3d */
IWineD3DSwapChain *wineD3DSwapChain;
};
/* IUnknown: */

View File

@ -579,6 +579,61 @@ HRESULT WINAPI D3D8CB_CreateRenderTarget(IUnknown *device, UINT Width, UINT Heig
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 @@ HRESULT WINAPI IDirect3D8Impl_CreateDevice (LPDIRECT3D8 iface,
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;

View File

@ -184,7 +184,6 @@ typedef struct IDirect3DCubeTexture9Impl IDirect3DCubeTexture9Impl;
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 @@ extern const IDirect3DSwapChain9Vtbl Direct3DSwapChain9_Vtbl;
/*****************************************************************************
* 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 @@ extern HRESULT WINAPI D3D9CB_CreateVolume(IUnknown *pDevice, UINT Width, UINT H
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 */

View File

@ -57,7 +57,6 @@ ULONG WINAPI IDirect3DDevice9Impl_Release(LPDIRECT3DDEVICE9 iface) {
TRACE("(%p) : ReleaseRef to %ld\n", This, ref);
if (ref == 0) {
IDirect3D9_Release((LPDIRECT3D9) This->direct3d);
IWineD3DDevice_Release(This->WineD3DDevice);
HeapFree(GetProcessHeap(), 0, This);
}

View File

@ -175,38 +175,103 @@ HMONITOR WINAPI IDirect3D9Impl_GetAdapterMonitor(LPDIRECT3D9 iface, UINT Adapte
}
/* 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 @@ HRESULT WINAPI IDirect3D9Impl_CreateDevice(LPDIRECT3D9 iface, UINT Adapter, D3
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,

View File

@ -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 @@ HRESULT WINAPI IDirect3DSwapChain9Impl_QueryInterface(LPDIRECT3DSWAPCHAIN9 iface
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 @@ ULONG WINAPI IDirect3DSwapChain9Impl_Release(LPDIRECT3DSWAPCHAIN9 iface) {
/* 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 @@ const IDirect3DSwapChain9Vtbl Direct3DSwapChain9_Vtbl =
/* 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);
}

View File

@ -19,6 +19,7 @@ C_SRCS = \
resource.c \
stateblock.c \
surface.c \
swapchain.c \
texture.c \
utils.c \
vertexbuffer.c \

View File

@ -30,6 +30,26 @@ WINE_DECLARE_DEBUG_CHANNEL(d3d_fps);
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 @@ ULONG WINAPI IWineD3DDeviceImpl_Release(IWineD3DDevice *iface) {
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 @@ HRESULT WINAPI IWineD3DDeviceImpl_CreateSurface(IWineD3DDevice *iface, UINT Wid
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 @@ HRESULT WINAPI IWineD3DDeviceImpl_CreateQuery(IWineD3DDevice *iface, WINED3DQUER
}
/* 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_GetTexture(IWineD3DDevice *iface, DWORD Stage,
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 @@ HRESULT WINAPI IWineD3DDeviceImpl_GetDeviceCaps(IWineD3DDevice *iface, WINED3DCA
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_EndScene(IWineD3DDevice *iface) {
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_GetRenderTargetData(IWineD3DDevice *iface, I
}
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 @@ HRESULT WINAPI IWineD3DDeviceImpl_GetCreationParameters(IWineD3DDevice *iface,
}
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;
}

View File

@ -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 @@ HRESULT WINAPI IWineD3DImpl_GetDeviceCaps(IWineD3D *iface, UINT Adapter, D3DDEVT
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 @@ HRESULT WINAPI IWineD3DImpl_CreateDevice(IWineD3D *iface, UINT Adapter, D3DDEV
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;
}

458
dlls/wined3d/swapchain.c Normal file
View File

@ -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
};

View File

@ -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 @@ typedef struct IWineD3DDeviceImpl
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 @@ typedef struct IWineD3DDeviceImpl
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;
@ -753,6 +754,43 @@ typedef struct IWineD3DQueryImpl
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
*/

View File

@ -151,6 +151,7 @@ typedef struct IWineD3DVertexDeclaration IWineD3DVertexDeclaration;
typedef struct IWineD3DVertexShader IWineD3DVertexShader;
typedef struct IWineD3DPixelShader IWineD3DPixelShader;
typedef struct IWineD3DQuery IWineD3DQuery;
typedef struct IWineD3DSwapChain IWineD3DSwapChain;
/*****************************************************************************
* Callback functions required for predefining surfaces / stencils
@ -195,11 +196,11 @@ typedef HRESULT WINAPI (*D3DCB_CREATEVOLUMEFN) (IUnknown *pDevice,
DWORD Usage,
IWineD3DVolume **ppVolume,
HANDLE *pSharedHandle);
typedef HRESULT WINAPI (*D3DCB_CREATEADDITIONALSWAPCHAIN) (IUnknown *pDevice,
WINED3DPRESENT_PARAMETERS *pPresentationParameters,
void **pSwapChain
);
IWineD3DSwapChain **pSwapChain
);
/*****************************************************************************
* IWineD3D interface
@ -227,7 +228,8 @@ DECLARE_INTERFACE_(IWineD3D,IUnknown)
STDMETHOD(CheckDeviceFormat)(THIS_ UINT Adapter, D3DDEVTYPE DeviceType, WINED3DFORMAT AdapterFormat, DWORD Usage, D3DRESOURCETYPE RType, WINED3DFORMAT CheckFormat) PURE;
STDMETHOD(CheckDeviceFormatConversion)(THIS_ UINT Adapter, D3DDEVTYPE DeviceType, WINED3DFORMAT SourceFormat, WINED3DFORMAT TargetFormat) PURE;
STDMETHOD(GetDeviceCaps)(THIS_ UINT Adapter, D3DDEVTYPE DeviceType, WINED3DCAPS *pCaps) PURE;
STDMETHOD(CreateDevice)(THIS_ UINT Adapter, D3DDEVTYPE DeviceType,HWND hFocusWindow, DWORD BehaviorFlags, WINED3DPRESENT_PARAMETERS * pPresentationParameters, IWineD3DDevice ** ppReturnedDeviceInterface, IUnknown *parent, D3DCB_CREATERENDERTARGETFN pFn) PURE;
STDMETHOD(CreateDevice)(THIS_ UINT Adapter, D3DDEVTYPE DeviceType,HWND hFocusWindow, DWORD BehaviorFlags, WINED3DPRESENT_PARAMETERS *pPresentationParameters, IWineD3DDevice **ppReturnedDeviceInterface, IUnknown *parent, D3DCB_CREATEADDITIONALSWAPCHAIN pFn3) PURE;
};
#undef INTERFACE
@ -278,7 +280,7 @@ DECLARE_INTERFACE_(IWineD3DDevice,IUnknown)
STDMETHOD(CreateVolume)(THIS_ UINT Width, UINT Height, UINT Depth, DWORD Usage, WINED3DFORMAT Format, D3DPOOL Pool, IWineD3DVolume** ppVolumeTexture, HANDLE* pSharedHandle, IUnknown *parent) PURE;
STDMETHOD(CreateCubeTexture)(THIS_ UINT EdgeLength, UINT Levels, DWORD Usage, WINED3DFORMAT Format, D3DPOOL Pool, IWineD3DCubeTexture** ppCubeTexture, HANDLE* pSharedHandle, IUnknown *parent, D3DCB_CREATESURFACEFN pFn) PURE;
STDMETHOD(CreateQuery)(THIS_ WINED3DQUERYTYPE Type, IWineD3DQuery **ppQuery, IUnknown *pParent);
STDMETHOD(CreateAdditionalSwapChain)(THIS_ WINED3DPRESENT_PARAMETERS* pPresentationParameters, void** pSwapChain, IUnknown* pParent, D3DCB_CREATERENDERTARGETFN pFn, D3DCB_CREATEDEPTHSTENCILSURFACEFN pFn2);
STDMETHOD(CreateAdditionalSwapChain)(THIS_ WINED3DPRESENT_PARAMETERS *pPresentationParameters, IWineD3DSwapChain **pSwapChain, IUnknown *pParent, D3DCB_CREATERENDERTARGETFN pFn, D3DCB_CREATEDEPTHSTENCILSURFACEFN pFn2);
STDMETHOD(CreateVertexDeclaration)(THIS_ CONST VOID* pDeclaration, IWineD3DVertexDeclaration** ppDecl, IUnknown* pParent) PURE;
STDMETHOD(CreateVertexShader)(THIS_ CONST DWORD* pFunction, IWineD3DVertexShader** ppShader, IUnknown *pParent) PURE;
STDMETHOD(CreatePixelShader)(THIS_ CONST DWORD* pFunction, IWineD3DPixelShader** ppShader, IUnknown *pParent) PURE;
@ -291,7 +293,7 @@ DECLARE_INTERFACE_(IWineD3DDevice,IUnknown)
STDMETHOD(GetDisplayMode)(THIS_ UINT iSwapChain, D3DDISPLAYMODE* pMode) PURE;
STDMETHOD_(UINT, GetNumberOfSwapChains)(THIS) PURE;
STDMETHOD(GetRasterStatus)(THIS_ UINT iSwapChain, D3DRASTER_STATUS* pRasterStatus) PURE;
STDMETHOD(GetSwapChain)(THIS_ UINT iSwapChain, void** pSwapChain) PURE;
STDMETHOD(GetSwapChain)(THIS_ UINT iSwapChain, IWineD3DSwapChain **pSwapChain) PURE;
STDMETHOD(Reset)(THIS_ WINED3DPRESENT_PARAMETERS* pPresentationParameters) PURE;
STDMETHOD(SetDialogBoxMode)(THIS_ BOOL bEnableDialogs) PURE;
STDMETHOD(SetCursorProperties)(THIS_ UINT XHotSpot, UINT YHotSpot, IWineD3DSurface* pCursorBitmap) PURE;
@ -1162,6 +1164,51 @@ DECLARE_INTERFACE_(IWineD3DQuery,IUnknown)
#endif
/*****************************************************************************
* IWineD3DSwapChain interface
* TODO: add gamma-ramp setting functions to make life easier
* (There kinda missing from Microsofts DirectX!)
*/
#define INTERFACE IWineD3DSwapChain
DECLARE_INTERFACE_(IWineD3DSwapChain,IUnknown)
{
/*** IUnknown methods ***/
STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void **ppvObject) PURE;
STDMETHOD_(ULONG,AddRef)(THIS) PURE;
STDMETHOD_(ULONG,Release)(THIS) PURE;
/*** IDirect3DSwapChain9 methods ***/
STDMETHOD(GetParent)(THIS_ IUnknown **pParent) PURE;
STDMETHOD(GetDevice)(THIS_ IWineD3DDevice **ppDevice) PURE;
STDMETHOD(Present)(THIS_ CONST RECT *pSourceRect, CONST RECT *pDestRect, HWND hDestWindowOverride, CONST RGNDATA *pDirtyRegion, DWORD dwFlags) PURE;
STDMETHOD(GetFrontBufferData)(THIS_ IWineD3DSurface *pDestSurface) PURE;
STDMETHOD(GetBackBuffer)(THIS_ UINT iBackBuffer, D3DBACKBUFFER_TYPE Type, IWineD3DSurface **ppBackBuffer) PURE;
STDMETHOD(GetRasterStatus)(THIS_ D3DRASTER_STATUS *pRasterStatus) PURE;
STDMETHOD(GetDisplayMode)(THIS_ D3DDISPLAYMODE *pMode) PURE;
STDMETHOD(GetPresentParameters)(THIS_ D3DPRESENT_PARAMETERS *pPresentationParameters) PURE;
STDMETHOD(SetGammaRamp)(THIS_ DWORD Flags, const D3DGAMMARAMP *pRamp) PURE;
STDMETHOD(GetGammaRamp)(THIS_ D3DGAMMARAMP *pRamp) PURE;
};
#undef INTERFACE
#if !defined(__cplusplus) || defined(CINTERFACE)
/*** IUnknown methods ***/
#define IWineD3DSwapChain_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
#define IWineD3DSwapChain_AddRef(p) (p)->lpVtbl->AddRef(p)
#define IWineD3DSwapChain_Release(p) (p)->lpVtbl->Release(p)
/*** IWineD3DSwapChain methods ***/
#define IWineD3DSwapChain_GetParent(p,a) (p)->lpVtbl->GetParent(p,a)
#define IWineD3DSwapChain_GetDevice(p,a) (p)->lpVtbl->GetDevice(p,a)
#define IWineD3DSwapChain_Present(p,a,b,c,d,e) (p)->lpVtbl->Present(p,a,b,c,d,e)
#define IWineD3DSwapChain_GetFrontBufferData(p,a) (p)->lpVtbl->GetFrontBufferData(p,a)
#define IWineD3DSwapChain_GetBackBuffer(p,a,b,c) (p)->lpVtbl->GetBackBuffer(p,a,b,c)
#define IWineD3DSwapChain_GetRasterStatus(p,a) (p)->lpVtbl->GetRasterStatus(p,a)
#define IWineD3DSwapChain_GetDisplayMode(p,a) (p)->lpVtbl->GetDisplayMode(p,a)
#define IWineD3DSwapChain_GetPresentParameters(p,a) (p)->lpVtbl->GetPresentParameters(p,a)
#define IWineD3DSwapChain_SetGammaRamp(p,a,b) (p)->lpVtbl->SetGammaRamp(p,a,b)
#define IWineD3DSwapChain_GetGammaRamp(p,a) (p)->lpVtbl->GetGammaRamp(p,a)
#endif
/*****************************************************************************
* IWineD3DVertexShader interface
*/