1 /* 2 * COPYRIGHT: See COPYING in the top level directory 3 * PROJECT: ReactOS ReactX 4 * FILE: dll/directx/d3d9/d3d9_swapchain.c 5 * PURPOSE: Direct3D9's swap chain object 6 * PROGRAMERS: Gregor Gullwi <gbrunmar (dot) ros (at) gmail (dot) com> 7 */ 8 #include "d3d9_swapchain.h" 9 10 #include <debug.h> 11 #include <ddraw.h> 12 13 #include "d3d9_helpers.h" 14 #include "d3d9_device.h" 15 #include "d3d9_cursor.h" 16 17 #define LOCK_D3DDEVICE9() D3D9BaseObject_LockDevice(&This->BaseObject) 18 #define UNLOCK_D3DDEVICE9() D3D9BaseObject_UnlockDevice(&This->BaseObject) 19 20 /* Convert a IDirect3DSwapChain9 pointer safely to the internal implementation struct */ 21 LPDIRECT3DSWAPCHAIN9_INT IDirect3DSwapChain9ToImpl(LPDIRECT3DSWAPCHAIN9 iface) 22 { 23 if (NULL == iface) 24 return NULL; 25 26 return (LPDIRECT3DSWAPCHAIN9_INT)((ULONG_PTR)iface - FIELD_OFFSET(Direct3DSwapChain9_INT, lpVtbl)); 27 } 28 29 /* IDirect3DSwapChain9: IUnknown implementation */ 30 static HRESULT WINAPI Direct3DSwapChain9_QueryInterface(LPDIRECT3DSWAPCHAIN9 iface, REFIID riid, void** ppvObject) 31 { 32 LPDIRECT3DSWAPCHAIN9_INT This = IDirect3DSwapChain9ToImpl(iface); 33 34 if (IsEqualGUID(riid, &IID_IUnknown) || IsEqualGUID(riid, &IID_IDirect3DSwapChain9)) 35 { 36 IUnknown_AddRef(iface); 37 *ppvObject = &This->lpVtbl; 38 return S_OK; 39 } 40 41 *ppvObject = NULL; 42 return E_NOINTERFACE; 43 } 44 45 static ULONG WINAPI Direct3DSwapChain9_AddRef(LPDIRECT3DSWAPCHAIN9 iface) 46 { 47 LPDIRECT3DSWAPCHAIN9_INT This = IDirect3DSwapChain9ToImpl(iface); 48 return D3D9BaseObject_AddRef((D3D9BaseObject*) &This->BaseObject.lpVtbl); 49 } 50 51 static ULONG WINAPI Direct3DSwapChain9_Release(LPDIRECT3DSWAPCHAIN9 iface) 52 { 53 LPDIRECT3DSWAPCHAIN9_INT This = IDirect3DSwapChain9ToImpl(iface); 54 return D3D9BaseObject_Release((D3D9BaseObject*) &This->BaseObject.lpVtbl); 55 } 56 57 /* IDirect3DSwapChain9 interface */ 58 static HRESULT WINAPI Direct3DSwapChain9_Present(LPDIRECT3DSWAPCHAIN9 iface, CONST RECT* pSourceRect,CONST RECT* pDestRect,HWND hDestWindowOverride,CONST RGNDATA* pDirtyRegion,DWORD dwFlags) 59 { 60 UNIMPLEMENTED 61 return D3D_OK; 62 } 63 64 static HRESULT WINAPI Direct3DSwapChain9_GetFrontBufferData(LPDIRECT3DSWAPCHAIN9 iface, IDirect3DSurface9* pDestSurface) 65 { 66 UNIMPLEMENTED 67 return D3D_OK; 68 } 69 70 static HRESULT WINAPI Direct3DSwapChain9_GetBackBuffer(LPDIRECT3DSWAPCHAIN9 iface, UINT iBackBuffer,D3DBACKBUFFER_TYPE Type,IDirect3DSurface9** ppBackBuffer) 71 { 72 UNIMPLEMENTED 73 return D3D_OK; 74 } 75 76 static HRESULT WINAPI Direct3DSwapChain9_GetRasterStatus(LPDIRECT3DSWAPCHAIN9 iface, D3DRASTER_STATUS* pRasterStatus) 77 { 78 UNIMPLEMENTED 79 return D3D_OK; 80 } 81 82 static HRESULT WINAPI Direct3DSwapChain9_GetDisplayMode(LPDIRECT3DSWAPCHAIN9 iface, D3DDISPLAYMODE* pMode) 83 { 84 UNIMPLEMENTED 85 return D3D_OK; 86 } 87 88 /*++ 89 * @name IDirect3DSwapChain9::GetDevice 90 * @implemented 91 * 92 * The function Direct3DSwapChain9_GetDevice sets the ppDevice argument 93 * to the device connected to create the swap chain. 94 * 95 * @param LPDIRECT3DSWAPCHAIN9 iface 96 * Pointer to a IDirect3DSwapChain9 object returned from IDirect3D9Device::GetSwapChain() 97 * 98 * @param IDirect3DDevice9** ppDevice 99 * Pointer to a IDirect3DDevice9* structure to be set to the device object. 100 * 101 * @return HRESULT 102 * If the method successfully sets the ppDevice value, the return value is D3D_OK. 103 * If ppDevice is a bad pointer the return value will be D3DERR_INVALIDCALL. 104 * If the swap chain didn't contain any device, the return value will be D3DERR_INVALIDDEVICE. 105 * 106 */ 107 static HRESULT WINAPI Direct3DSwapChain9_GetDevice(LPDIRECT3DSWAPCHAIN9 iface, IDirect3DDevice9** ppDevice) 108 { 109 LPDIRECT3DSWAPCHAIN9_INT This = IDirect3DSwapChain9ToImpl(iface); 110 LOCK_D3DDEVICE9(); 111 112 if (NULL == ppDevice) 113 { 114 DPRINT1("Invalid ppDevice parameter specified"); 115 UNLOCK_D3DDEVICE9(); 116 return D3DERR_INVALIDCALL; 117 } 118 119 if (FAILED(D3D9BaseObject_GetDevice(&This->BaseObject, ppDevice))) 120 { 121 DPRINT1("Invalid This parameter specified"); 122 UNLOCK_D3DDEVICE9(); 123 return D3DERR_INVALIDDEVICE; 124 } 125 126 UNLOCK_D3DDEVICE9(); 127 return D3D_OK; 128 } 129 130 /*++ 131 * @name IDirect3DSwapChain9::GetPresentParameters 132 * @implemented 133 * 134 * The function Direct3DSwapChain9_GetPresentParameters fills the pPresentationParameters 135 * argument with the D3DPRESENT_PARAMETERS parameters that was used to create the swap chain. 136 * 137 * @param LPDIRECT3DSWAPCHAIN9 iface 138 * Pointer to a IDirect3DSwapChain9 object returned from IDirect3D9Device::GetSwapChain() 139 * 140 * @param D3DPRESENT_PARAMETERS* pPresentationParameters 141 * Pointer to a D3DPRESENT_PARAMETERS structure to be filled with the creation parameters. 142 * 143 * @return HRESULT 144 * If the method successfully fills the pPresentationParameters structure, the return value is D3D_OK. 145 * If pPresentationParameters is a bad pointer the return value will be D3DERR_INVALIDCALL. 146 * 147 */ 148 static HRESULT WINAPI Direct3DSwapChain9_GetPresentParameters(LPDIRECT3DSWAPCHAIN9 iface, D3DPRESENT_PARAMETERS* pPresentationParameters) 149 { 150 LPDIRECT3DSWAPCHAIN9_INT This = IDirect3DSwapChain9ToImpl(iface); 151 LOCK_D3DDEVICE9(); 152 153 if (NULL == pPresentationParameters) 154 { 155 DPRINT1("Invalid pPresentationParameters parameter specified"); 156 UNLOCK_D3DDEVICE9(); 157 return D3DERR_INVALIDCALL; 158 } 159 160 *pPresentationParameters = This->PresentParameters; 161 162 UNLOCK_D3DDEVICE9(); 163 return D3D_OK; 164 } 165 166 static IDirect3DSwapChain9Vtbl Direct3DSwapChain9_Vtbl = 167 { 168 /* IUnknown */ 169 Direct3DSwapChain9_QueryInterface, 170 Direct3DSwapChain9_AddRef, 171 Direct3DSwapChain9_Release, 172 173 /* IDirect3DSwapChain9 */ 174 Direct3DSwapChain9_Present, 175 Direct3DSwapChain9_GetFrontBufferData, 176 Direct3DSwapChain9_GetBackBuffer, 177 Direct3DSwapChain9_GetRasterStatus, 178 Direct3DSwapChain9_GetDisplayMode, 179 Direct3DSwapChain9_GetDevice, 180 Direct3DSwapChain9_GetPresentParameters, 181 }; 182 183 Direct3DSwapChain9_INT* CreateDirect3DSwapChain9(enum REF_TYPE RefType, struct _Direct3DDevice9_INT* pBaseDevice, DWORD ChainIndex) 184 { 185 Direct3DSwapChain9_INT* pThisSwapChain; 186 if (FAILED(AlignedAlloc((LPVOID*)&pThisSwapChain, sizeof(Direct3DSwapChain9_INT)))) 187 { 188 DPRINT1("Could not create Direct3DSwapChain9_INT"); 189 return NULL; 190 } 191 192 InitD3D9BaseObject((D3D9BaseObject*) &pThisSwapChain->BaseObject.lpVtbl, RefType, (IUnknown*) &pBaseDevice->lpVtbl); 193 194 pThisSwapChain->lpVtbl = &Direct3DSwapChain9_Vtbl; 195 196 pThisSwapChain->ChainIndex = ChainIndex; 197 pThisSwapChain->AdapterGroupIndex = ChainIndex; 198 pThisSwapChain->pUnknown6BC = pBaseDevice->DeviceData[ChainIndex].pUnknown6BC; 199 pThisSwapChain->pUnknown015c = (LPVOID)0xD3D9D3D9; 200 201 return pThisSwapChain; 202 } 203 204 VOID Direct3DSwapChain9_SetDisplayMode(Direct3DSwapChain9_INT* pThisSwapChain, D3DPRESENT_PARAMETERS* pPresentationParameters) 205 { 206 pThisSwapChain->dwWidth = pPresentationParameters->BackBufferWidth; 207 pThisSwapChain->dwHeight = pPresentationParameters->BackBufferHeight; 208 } 209 210 HRESULT Direct3DSwapChain9_Init(Direct3DSwapChain9_INT* pThisSwapChain, D3DPRESENT_PARAMETERS* pPresentationParameters) 211 { 212 int i; 213 DIRECT3DDEVICE9_INT* pDevice; 214 215 for (i = 0; i < 256; i++) 216 { 217 pThisSwapChain->GammaRamp.red[i] = 218 pThisSwapChain->GammaRamp.green[i] = 219 pThisSwapChain->GammaRamp.blue[i] = i; 220 } 221 222 pThisSwapChain->PresentParameters = pPresentationParameters[pThisSwapChain->ChainIndex]; 223 pThisSwapChain->SwapEffect = pPresentationParameters->SwapEffect; 224 Direct3DSwapChain9_SetDisplayMode(pThisSwapChain, &pThisSwapChain->PresentParameters); 225 226 if (FAILED(D3D9BaseObject_GetDeviceInt(&pThisSwapChain->BaseObject, &pDevice))) 227 { 228 DPRINT1("Could not get the swapchain device"); 229 return DDERR_GENERIC; 230 } 231 232 pThisSwapChain->pCursor = CreateD3D9Cursor(pDevice, pThisSwapChain); 233 if (NULL == pThisSwapChain->pCursor) 234 { 235 DPRINT1("Could not allocate D3D9Cursor"); 236 return DDERR_OUTOFMEMORY; 237 } 238 239 return Direct3DSwapChain9_Reset(pThisSwapChain, pPresentationParameters); 240 } 241 242 HRESULT Direct3DSwapChain9_Reset(Direct3DSwapChain9_INT* pThisSwapChain, D3DPRESENT_PARAMETERS* pPresentationParameters) 243 { 244 // TODO: Do all the dirty work... 245 return D3D_OK; 246 } 247 248 VOID Direct3DSwapChain9_GetGammaRamp(Direct3DSwapChain9_INT* pThisSwapChain, D3DGAMMARAMP* pRamp) 249 { 250 memcpy(pRamp, &pThisSwapChain->GammaRamp, sizeof(D3DGAMMARAMP)); 251 } 252 253 VOID Direct3DSwapChain9_SetGammaRamp(Direct3DSwapChain9_INT* pThisSwapChain, DWORD Flags, CONST D3DGAMMARAMP* pRamp) 254 { 255 UNIMPLEMENTED 256 } 257