device.c 52.5 KB
Newer Older
1 2 3
/*
 * IDirect3DDevice9 implementation
 *
4
 * Copyright 2002-2005 Jason Edmeades
5 6
 * Copyright 2002-2005 Raphael Junqueira
 * Copyright 2005 Oliver Stieber
7 8 9 10 11 12 13 14 15 16 17 18 19
 *
 * 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
20
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 22 23 24 25
 */

#include "config.h"
#include "d3d9_private.h"

26
WINE_DEFAULT_DEBUG_CHANNEL(d3d9);
27 28 29


/* IDirect3D IUnknown parts follow: */
30
static HRESULT WINAPI IDirect3DDevice9Impl_QueryInterface(LPDIRECT3DDEVICE9 iface, REFIID riid, LPVOID* ppobj) {
31
    IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
32 33 34

    if (IsEqualGUID(riid, &IID_IUnknown)
        || IsEqualGUID(riid, &IID_IDirect3DDevice9)) {
35
        IUnknown_AddRef(iface);
36
        *ppobj = This;
H. Verbeet's avatar
H. Verbeet committed
37
        return S_OK;
38 39 40
    }

    WARN("(%p)->(%s,%p),not found\n", This, debugstr_guid(riid), ppobj);
H. Verbeet's avatar
H. Verbeet committed
41
    *ppobj = NULL;
42 43 44
    return E_NOINTERFACE;
}

45
static ULONG WINAPI IDirect3DDevice9Impl_AddRef(LPDIRECT3DDEVICE9 iface) {
46
    IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
47 48
    ULONG ref = InterlockedIncrement(&This->ref);

49
    TRACE("(%p) : AddRef from %d\n", This, ref - 1);
50 51

    return ref;
52 53
}

54
static ULONG WINAPI IDirect3DDevice9Impl_Release(LPDIRECT3DDEVICE9 iface) {
55
    IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
56 57 58 59
    ULONG ref;

    if (This->inDestruction) return 0;
    ref = InterlockedDecrement(&This->ref);
60

61
    TRACE("(%p) : ReleaseRef to %d\n", This, ref);
62

63
    if (ref == 0) {
64
      int i;
65
      This->inDestruction = TRUE;
66 67 68 69 70 71 72 73 74

      for(i = 0; i < This->numConvertedDecls; i++) {
          /* Unless Wine is buggy or the app has a bug the refcount will be 0, because decls hold a reference to the
           * device
           */
          IDirect3DVertexDeclaration9Impl_Destroy(This->convertedDecls[i]);
      }
      HeapFree(GetProcessHeap(), 0, This->convertedDecls);

75
      IWineD3DDevice_Uninit3D(This->WineD3DDevice, D3D9CB_DestroyDepthStencilSurface, D3D9CB_DestroySwapChain);
76
      IWineD3DDevice_Release(This->WineD3DDevice);
77 78 79 80 81 82
      HeapFree(GetProcessHeap(), 0, This);
    }
    return ref;
}

/* IDirect3DDevice Interface follow: */
83
static HRESULT  WINAPI  IDirect3DDevice9Impl_TestCooperativeLevel(LPDIRECT3DDEVICE9 iface) {
84
    IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
85 86 87
    
    TRACE("(%p) : Relay\n", This);
    return IWineD3DDevice_TestCooperativeLevel(This->WineD3DDevice);
88 89
}

90
static UINT     WINAPI  IDirect3DDevice9Impl_GetAvailableTextureMem(LPDIRECT3DDEVICE9 iface) {
91
    IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
92 93 94
    
    TRACE("(%p) Relay\n", This);
    return IWineD3DDevice_GetAvailableTextureMem(This->WineD3DDevice);    
95 96
}

97
static HRESULT  WINAPI  IDirect3DDevice9Impl_EvictManagedResources(LPDIRECT3DDEVICE9 iface) {
98
    IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
99

100
    TRACE("(%p) : Relay\n", This);
101
    return IWineD3DDevice_EvictManagedResources(This->WineD3DDevice);
102 103 104
}

HRESULT  WINAPI  IDirect3DDevice9Impl_GetDirect3D(LPDIRECT3DDEVICE9 iface, IDirect3D9** ppD3D9) {
105
    IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
106 107 108 109 110 111 112 113 114 115 116
    HRESULT hr = D3D_OK;
    IWineD3D* pWineD3D;

    TRACE("(%p) Relay\n", This);

    if (NULL == ppD3D9) {
        return D3DERR_INVALIDCALL;
    }
    hr = IWineD3DDevice_GetDirect3D(This->WineD3DDevice, &pWineD3D);
    if (hr == D3D_OK && pWineD3D != NULL)
    {
117 118
        IWineD3D_GetParent(pWineD3D,(IUnknown **)ppD3D9);
        IWineD3D_Release(pWineD3D);
119 120 121 122
    } else {
        FIXME("Call to IWineD3DDevice_GetDirect3D failed\n");
        *ppD3D9 = NULL;
    }
123
    TRACE("(%p) returning %p\n", This, *ppD3D9);
124
    return hr;
125 126
}

127
static HRESULT  WINAPI  IDirect3DDevice9Impl_GetDeviceCaps(LPDIRECT3DDEVICE9 iface, D3DCAPS9* pCaps) {
128
    IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
129 130 131
    HRESULT hrc = D3D_OK;
    WINED3DCAPS *pWineCaps;

132
    TRACE("(%p) : Relay pCaps %p\n", This, pCaps);
133 134 135 136 137 138 139 140 141 142 143 144 145
    if(NULL == pCaps){
        return D3DERR_INVALIDCALL;
    }
    pWineCaps = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(WINED3DCAPS));
    if(pWineCaps == NULL){
        return D3DERR_INVALIDCALL; /* well this is what MSDN says to return */
    }

    D3D9CAPSTOWINECAPS(pCaps, pWineCaps)
    hrc = IWineD3DDevice_GetDeviceCaps(This->WineD3DDevice, pWineCaps);
    HeapFree(GetProcessHeap(), 0, pWineCaps);
    TRACE("Returning %p %p\n", This, pCaps);
    return hrc;
146 147
}

148
static HRESULT  WINAPI  IDirect3DDevice9Impl_GetDisplayMode(LPDIRECT3DDEVICE9 iface, UINT iSwapChain, D3DDISPLAYMODE* pMode) {
149
    IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
150
    TRACE("(%p) Relay\n", This);
151
    return IWineD3DDevice_GetDisplayMode(This->WineD3DDevice, iSwapChain, (WINED3DDISPLAYMODE *) pMode);
152 153
}

154
static HRESULT  WINAPI  IDirect3DDevice9Impl_GetCreationParameters(LPDIRECT3DDEVICE9 iface, D3DDEVICE_CREATION_PARAMETERS *pParameters) {
155
    IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
156
    TRACE("(%p) Relay\n", This);
157
    return IWineD3DDevice_GetCreationParameters(This->WineD3DDevice, (WINED3DDEVICE_CREATION_PARAMETERS *) pParameters);
158 159
}

160
static HRESULT  WINAPI  IDirect3DDevice9Impl_SetCursorProperties(LPDIRECT3DDEVICE9 iface, UINT XHotSpot, UINT YHotSpot, IDirect3DSurface9* pCursorBitmap) {
161
    IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
162 163
    IDirect3DSurface9Impl *pSurface = (IDirect3DSurface9Impl*)pCursorBitmap;
    TRACE("(%p) Relay\n", This);
164 165 166 167
    if(!pCursorBitmap) {
        WARN("No cursor bitmap, returning WINED3DERR_INVALIDCALL\n");
        return WINED3DERR_INVALIDCALL;
    }
168
    return IWineD3DDevice_SetCursorProperties(This->WineD3DDevice,XHotSpot,YHotSpot,(IWineD3DSurface*)pSurface->wineD3DSurface);
169 170
}

171
static void     WINAPI  IDirect3DDevice9Impl_SetCursorPosition(LPDIRECT3DDEVICE9 iface, int XScreenSpace, int YScreenSpace, DWORD Flags) {
172
    IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
173
    TRACE("(%p) Relay\n", This);
174
    IWineD3DDevice_SetCursorPosition(This->WineD3DDevice, XScreenSpace, YScreenSpace, Flags);
175 176
}

177
static BOOL     WINAPI  IDirect3DDevice9Impl_ShowCursor(LPDIRECT3DDEVICE9 iface, BOOL bShow) {
178
    IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
179
    TRACE("(%p) Relay\n", This);
180

181
    return IWineD3DDevice_ShowCursor(This->WineD3DDevice, bShow);
182 183
}

184
static HRESULT  WINAPI  IDirect3DDevice9Impl_Reset(LPDIRECT3DDEVICE9 iface, D3DPRESENT_PARAMETERS* pPresentationParameters) {
185
    IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
186
    WINED3DPRESENT_PARAMETERS localParameters;
187 188
    HRESULT hr;

189
    TRACE("(%p) Relay pPresentationParameters(%p)\n", This, pPresentationParameters);
190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223

    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;

    hr = IWineD3DDevice_Reset(This->WineD3DDevice, &localParameters);

    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 hr;
224 225
}

226
static HRESULT  WINAPI  IDirect3DDevice9Impl_Present(LPDIRECT3DDEVICE9 iface, CONST RECT* pSourceRect,CONST RECT* pDestRect,HWND hDestWindowOverride,CONST RGNDATA*
227 228 229
 pDirtyRegion) {
    IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
    TRACE("(%p) Relay\n", This);
230
    return IWineD3DDevice_Present(This->WineD3DDevice, pSourceRect, pDestRect, hDestWindowOverride, pDirtyRegion);
231 232
}

233
static HRESULT  WINAPI  IDirect3DDevice9Impl_GetBackBuffer(LPDIRECT3DDEVICE9 iface, UINT iSwapChain, UINT BackBuffer, D3DBACKBUFFER_TYPE Type, IDirect3DSurface9 ** ppBackBuffer) {
234
    IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
235 236 237
    IWineD3DSurface *retSurface = NULL;
    HRESULT rc = D3D_OK;

238 239
    TRACE("(%p) Relay\n", This);

240
    rc = IWineD3DDevice_GetBackBuffer(This->WineD3DDevice, iSwapChain, BackBuffer, (WINED3DBACKBUFFER_TYPE) Type, (IWineD3DSurface **)&retSurface);
241
    if (rc == D3D_OK && NULL != retSurface && NULL != ppBackBuffer) {
242
        IWineD3DSurface_GetParent(retSurface, (IUnknown **)ppBackBuffer);
243
        IWineD3DSurface_Release(retSurface);
244
    }
245
    return rc;
246
}
247
static HRESULT  WINAPI  IDirect3DDevice9Impl_GetRasterStatus(LPDIRECT3DDEVICE9 iface, UINT iSwapChain, D3DRASTER_STATUS* pRasterStatus) {
248
    IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
249 250
    TRACE("(%p) Relay\n", This);
    
251
    return IWineD3DDevice_GetRasterStatus(This->WineD3DDevice, iSwapChain, (WINED3DRASTER_STATUS *) pRasterStatus);        
252 253
}

254
static HRESULT WINAPI IDirect3DDevice9Impl_SetDialogBoxMode(LPDIRECT3DDEVICE9 iface, BOOL bEnableDialogs) {
255
    IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
256 257 258
    TRACE("(%p) Relay\n", This);
    
    return IWineD3DDevice_SetDialogBoxMode(This->WineD3DDevice, bEnableDialogs);
259 260
}

261
static void WINAPI IDirect3DDevice9Impl_SetGammaRamp(LPDIRECT3DDEVICE9 iface, UINT iSwapChain, DWORD Flags, CONST D3DGAMMARAMP* pRamp) {
262
    
263
    IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
264
    TRACE("(%p) Relay\n", This);
265 266
   
    /* Note: D3DGAMMARAMP is compatible with WINED3DGAMMARAMP */ 
267
    IWineD3DDevice_SetGammaRamp(This->WineD3DDevice, iSwapChain, Flags, (CONST WINED3DGAMMARAMP *)pRamp);
268 269
}

270
static void WINAPI IDirect3DDevice9Impl_GetGammaRamp(LPDIRECT3DDEVICE9 iface, UINT iSwapChain, D3DGAMMARAMP* pRamp) {    
271
    IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
272 273
    TRACE("(%p) Relay\n", This);
    
274
    /* Note: D3DGAMMARAMP is compatible with WINED3DGAMMARAMP */
275
    IWineD3DDevice_GetGammaRamp(This->WineD3DDevice, iSwapChain, (WINED3DGAMMARAMP *) pRamp);
276 277
}

278

279
static HRESULT  WINAPI IDirect3DDevice9Impl_CreateSurface(LPDIRECT3DDEVICE9 iface, UINT Width, UINT Height, D3DFORMAT Format, BOOL Lockable, BOOL Discard, UINT Level, IDirect3DSurface9 **ppSurface,D3DRESOURCETYPE Type, UINT Usage, D3DPOOL Pool, D3DMULTISAMPLE_TYPE MultiSample, DWORD MultisampleQuality,HANDLE* pSharedHandle )  {
280
    HRESULT hrc;
281
    IDirect3DSurface9Impl *object;
282 283 284
    IDirect3DDevice9Impl  *This = (IDirect3DDevice9Impl *)iface;
    TRACE("(%p) Relay\n", This);
    if(MultisampleQuality < 0) { 
285
        FIXME("MultisampleQuality out of range %d, substituting 0\n", MultisampleQuality);
286 287 288 289 290
    /*FIXME: Find out what windows does with a MultisampleQuality < 0 */
        MultisampleQuality=0;
    }
    
    if(MultisampleQuality > 0){
291
        FIXME("MultisampleQuality set to %d, bstituting 0\n", MultisampleQuality);
292 293 294 295 296 297 298 299
    /*
    MultisampleQuality
 [in] Quality level. The valid range is between zero and one less than the level returned by pQualityLevels used by IDirect3D9::CheckDeviceMultiSampleType. Passing a larger value returns the error D3DERR_INVALIDCALL. The MultisampleQuality values of paired render targets, depth stencil surfaces, and the MultiSample type must all match.
 */
 
        MultisampleQuality=0;
    }
    /*FIXME: Check MAX bounds of MultisampleQuality*/
300 301 302

    /* Allocate the storage for the device */
    object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DSurface9Impl));
303 304 305 306 307
    if (NULL == object) {
        FIXME("Allocation of memory failed\n");
        return D3DERR_OUTOFVIDEOMEMORY;
    }

308 309
    object->lpVtbl = &Direct3DSurface9_Vtbl;
    object->ref = 1;
310 311 312
    
    TRACE("(%p) : w(%d) h(%d) fmt(%d) surf@%p\n", This, Width, Height, Format, *ppSurface);
           
313
    hrc = IWineD3DDevice_CreateSurface(This->WineD3DDevice, Width, Height, Format, Lockable, Discard, Level,  &object->wineD3DSurface, Type, Usage & WINED3DUSAGE_MASK, (WINED3DPOOL) Pool,MultiSample,MultisampleQuality,pSharedHandle,SURFACE_OPENGL,(IUnknown *)object);
314
    
315
    if (hrc != D3D_OK || NULL == object->wineD3DSurface) {
316

317
       /* free up object */
318
        FIXME("(%p) call to IWineD3DDevice_CreateSurface failed\n", This);
319 320
        HeapFree(GetProcessHeap(), 0, object);
    } else {
321 322
        IUnknown_AddRef(iface);
        object->parentDevice = iface;
323
        TRACE("(%p) : Created surface %p\n", This, object);
324
        *ppSurface = (LPDIRECT3DSURFACE9) object;
325
    }
326
    return hrc;
327 328
}

329 330


331
static HRESULT  WINAPI  IDirect3DDevice9Impl_CreateRenderTarget(LPDIRECT3DDEVICE9 iface, UINT Width, UINT Height, 
332 333 334 335 336 337 338 339 340 341
                                                         D3DFORMAT Format, D3DMULTISAMPLE_TYPE MultiSample, 
                                                         DWORD MultisampleQuality, BOOL Lockable, 
                                                         IDirect3DSurface9 **ppSurface, HANDLE* pSharedHandle) {
   TRACE("Relay\n");
   /* Is this correct? */
   return IDirect3DDevice9Impl_CreateSurface(iface,Width,Height,Format,Lockable,FALSE/*Discard*/, 0/*Level*/, ppSurface,D3DRTYPE_SURFACE,D3DUSAGE_RENDERTARGET,D3DPOOL_DEFAULT,MultiSample,MultisampleQuality,pSharedHandle);
     

}

342
static HRESULT  WINAPI  IDirect3DDevice9Impl_CreateDepthStencilSurface(LPDIRECT3DDEVICE9 iface, UINT Width, UINT Height,
343 344 345 346 347 348 349
                                                                D3DFORMAT Format, D3DMULTISAMPLE_TYPE MultiSample,
                                                                DWORD MultisampleQuality, BOOL Discard,
                                                                IDirect3DSurface9 **ppSurface, HANDLE* pSharedHandle) {
     TRACE("Relay\n");
     return IDirect3DDevice9Impl_CreateSurface(iface,Width,Height,Format,TRUE/* Lockable */,Discard, 0/* Level */
                                               ,ppSurface,D3DRTYPE_SURFACE,D3DUSAGE_DEPTHSTENCIL,
                                                D3DPOOL_DEFAULT,MultiSample,MultisampleQuality,pSharedHandle);
350 351
}

352

353
static HRESULT  WINAPI  IDirect3DDevice9Impl_UpdateSurface(LPDIRECT3DDEVICE9 iface, IDirect3DSurface9* pSourceSurface, CONST RECT* pSourceRect, IDirect3DSurface9* pDestinationSurface, CONST POINT* pDestPoint) {
354 355 356
    IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;     
    TRACE("(%p) Relay\n" , This);
    return IWineD3DDevice_UpdateSurface(This->WineD3DDevice, ((IDirect3DSurface9Impl *)pSourceSurface)->wineD3DSurface, pSourceRect, ((IDirect3DSurface9Impl *)pDestinationSurface)->wineD3DSurface, pDestPoint);
357 358
}

359
static HRESULT  WINAPI  IDirect3DDevice9Impl_UpdateTexture(LPDIRECT3DDEVICE9 iface, IDirect3DBaseTexture9* pSourceTexture, IDirect3DBaseTexture9* pDestinationTexture) {
360
    IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
361 362
    TRACE("(%p) Relay\n" , This);
    return IWineD3DDevice_UpdateTexture(This->WineD3DDevice,  ((IDirect3DBaseTexture9Impl *)pSourceTexture)->wineD3DBaseTexture, ((IDirect3DBaseTexture9Impl *)pDestinationTexture)->wineD3DBaseTexture);
363 364
}

365
/* This isn't in MSDN!
366
static HRESULT  WINAPI  IDirect3DDevice9Impl_GetFrontBuffer(LPDIRECT3DDEVICE9 iface, IDirect3DSurface9* pDestSurface) {
367
    IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
368 369 370
    FIXME("(%p) : stub\n", This);
    return D3D_OK;
}
371
*/
372

373
static HRESULT  WINAPI  IDirect3DDevice9Impl_GetRenderTargetData(LPDIRECT3DDEVICE9 iface, IDirect3DSurface9* pRenderTarget, IDirect3DSurface9* pDestSurface) {
374
    IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
375 376
    IDirect3DSurface9Impl *renderTarget = (IDirect3DSurface9Impl *)pRenderTarget;
    IDirect3DSurface9Impl *destSurface = (IDirect3DSurface9Impl *)pDestSurface;
377
    TRACE("(%p)->(%p,%p)\n" , This, renderTarget, destSurface);
378
    return IWineD3DSurface_BltFast(destSurface->wineD3DSurface, 0, 0, renderTarget->wineD3DSurface, NULL, WINEDDBLTFAST_NOCOLORKEY);
379 380
}

381
static HRESULT  WINAPI  IDirect3DDevice9Impl_GetFrontBufferData(LPDIRECT3DDEVICE9 iface, UINT iSwapChain, IDirect3DSurface9* pDestSurface) {
382
    IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
383 384 385
    IDirect3DSurface9Impl *destSurface = (IDirect3DSurface9Impl *)pDestSurface;
    TRACE("(%p) Relay\n" , This);
    return IWineD3DDevice_GetFrontBufferData(This->WineD3DDevice, iSwapChain, destSurface->wineD3DSurface);    
386 387
}

388
static HRESULT  WINAPI  IDirect3DDevice9Impl_StretchRect(LPDIRECT3DDEVICE9 iface, IDirect3DSurface9* pSourceSurface, CONST RECT* pSourceRect, IDirect3DSurface9* pDestSurface, CONST RECT* pDestRect, D3DTEXTUREFILTERTYPE Filter) {
389 390 391 392 393
    IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
    IDirect3DSurface9Impl *src = (IDirect3DSurface9Impl *) pSourceSurface;
    IDirect3DSurface9Impl *dst = (IDirect3DSurface9Impl *) pDestSurface;

    TRACE("(%p)->(%p,%p,%p,%p,%d)\n" , This, src, pSourceRect, dst, pDestRect, Filter);
394
    return IWineD3DSurface_Blt(dst->wineD3DSurface, (RECT *) pDestRect, src->wineD3DSurface, (RECT *) pSourceRect, 0, NULL, Filter);
395 396
}

397
static HRESULT  WINAPI  IDirect3DDevice9Impl_ColorFill(LPDIRECT3DDEVICE9 iface, IDirect3DSurface9* pSurface, CONST RECT* pRect, D3DCOLOR color) {
398
    IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
399 400
    IDirect3DSurface9Impl *surface = (IDirect3DSurface9Impl *)pSurface;
    TRACE("(%p) Relay\n" , This);
401 402 403

    /* Note: D3DRECT is compatible with WINED3DRECT */
    return IWineD3DDevice_ColorFill(This->WineD3DDevice, surface->wineD3DSurface, (CONST WINED3DRECT*)pRect, color);    
404 405
}

406
static HRESULT  WINAPI  IDirect3DDevice9Impl_CreateOffscreenPlainSurface(LPDIRECT3DDEVICE9 iface, UINT Width, UINT Height, D3DFORMAT Format, D3DPOOL Pool, IDirect3DSurface9 **ppSurface, HANDLE* pSharedHandle) {
407 408 409 410 411 412 413 414 415 416 417 418 419
    TRACE("Relay\n");
    if(Pool == D3DPOOL_MANAGED ){
        FIXME("Attempting to create a managed offscreen plain surface\n");
        return D3DERR_INVALIDCALL;
    }    
        /*MSDN: D3DPOOL_SCRATCH will return a surface that has identical characteristics to a surface created by the Microsoft DirectX 8.x method CreateImageSurface.
        
        'Off-screen plain surfaces are always lockable, regardless of their pool types.'
        but then...
        D3DPOOL_DEFAULT is the appropriate pool for use with the IDirect3DDevice9::StretchRect and IDirect3DDevice9::ColorFill.
        Why, their always lockable?
        should I change the usage to dynamic?        
        */
420
    return IDirect3DDevice9Impl_CreateSurface(iface,Width,Height,Format,TRUE/*Loackable*/,FALSE/*Discard*/,0/*Level*/ , ppSurface,D3DRTYPE_SURFACE, 0/*Usage (undefined/none)*/,(WINED3DPOOL) Pool,D3DMULTISAMPLE_NONE,0/*MultisampleQuality*/,pSharedHandle);
421 422 423
}

/* TODO: move to wineD3D */
424
static HRESULT  WINAPI  IDirect3DDevice9Impl_SetRenderTarget(LPDIRECT3DDEVICE9 iface, DWORD RenderTargetIndex, IDirect3DSurface9* pRenderTarget) {
425
    IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
426 427
    IDirect3DSurface9Impl *pSurface = (IDirect3DSurface9Impl*)pRenderTarget;
    TRACE("(%p) Relay\n" , This);
428
    return IWineD3DDevice_SetRenderTarget(This->WineD3DDevice, RenderTargetIndex, pSurface ? (IWineD3DSurface*)pSurface->wineD3DSurface : NULL);
429
}
430

431
static HRESULT  WINAPI  IDirect3DDevice9Impl_GetRenderTarget(LPDIRECT3DDEVICE9 iface, DWORD RenderTargetIndex, IDirect3DSurface9 **ppRenderTarget) {
432 433 434 435 436 437 438 439
    IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
    HRESULT hr = D3D_OK;
    IWineD3DSurface *pRenderTarget;

    TRACE("(%p) Relay\n" , This);

    if (ppRenderTarget == NULL) {
        return D3DERR_INVALIDCALL;
440
    }
441
    hr=IWineD3DDevice_GetRenderTarget(This->WineD3DDevice,RenderTargetIndex,&pRenderTarget);
442

443
    if (hr == D3D_OK && pRenderTarget != NULL) {
444 445
        IWineD3DSurface_GetParent(pRenderTarget,(IUnknown**)ppRenderTarget);
        IWineD3DSurface_Release(pRenderTarget);
446 447 448 449 450
    } else {
        FIXME("Call to IWineD3DDevice_GetRenderTarget failed\n");
        *ppRenderTarget = NULL;
    }
    return hr;
451 452
}

453
static HRESULT  WINAPI  IDirect3DDevice9Impl_SetDepthStencilSurface(LPDIRECT3DDEVICE9 iface, IDirect3DSurface9* pZStencilSurface) {
454
    IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
455 456 457 458 459 460
    IDirect3DSurface9Impl *pSurface;

    TRACE("(%p) Relay\n" , This);

    pSurface = (IDirect3DSurface9Impl*)pZStencilSurface;
    return IWineD3DDevice_SetDepthStencilSurface(This->WineD3DDevice,NULL==pSurface?NULL:(IWineD3DSurface*)pSurface->wineD3DSurface);
461 462
}

463
static HRESULT  WINAPI  IDirect3DDevice9Impl_GetDepthStencilSurface(LPDIRECT3DDEVICE9 iface, IDirect3DSurface9 **ppZStencilSurface) {
464
    IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
465 466 467 468 469 470
    HRESULT hr = D3D_OK;
    IWineD3DSurface *pZStencilSurface;

    TRACE("(%p) Relay\n" , This);
    if(ppZStencilSurface == NULL){
        return D3DERR_INVALIDCALL;
471
    }
472

473 474
    hr=IWineD3DDevice_GetDepthStencilSurface(This->WineD3DDevice,&pZStencilSurface);
    if(hr == D3D_OK && pZStencilSurface != NULL){
475 476
        IWineD3DSurface_GetParent(pZStencilSurface,(IUnknown**)ppZStencilSurface);
        IWineD3DSurface_Release(pZStencilSurface);
477 478 479 480
    }else{
        FIXME("Call to IWineD3DDevice_GetRenderTarget failed\n");
        *ppZStencilSurface = NULL;
    }
481 482 483
    return D3D_OK;
}

484
static HRESULT  WINAPI  IDirect3DDevice9Impl_BeginScene(LPDIRECT3DDEVICE9 iface) {
485
    IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
486
    TRACE("(%p) Relay\n" , This);
487
    return IWineD3DDevice_BeginScene(This->WineD3DDevice);
488 489
}

490
static HRESULT  WINAPI  IDirect3DDevice9Impl_EndScene(LPDIRECT3DDEVICE9 iface) {
491
    IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
492
    TRACE("(%p) Relay\n" , This);
493
    return IWineD3DDevice_EndScene(This->WineD3DDevice);
494
    
495 496
}

497
static HRESULT  WINAPI  IDirect3DDevice9Impl_Clear(LPDIRECT3DDEVICE9 iface, DWORD Count, CONST D3DRECT* pRects, DWORD Flags, D3DCOLOR Color, float Z, DWORD Stencil) {
498
    IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
499
    TRACE("(%p) Relay\n" , This);
500 501 502

    /* Note: D3DRECT is compatible with WINED3DRECT */
    return IWineD3DDevice_Clear(This->WineD3DDevice, Count, (CONST WINED3DRECT*) pRects, Flags, Color, Z, Stencil);
503 504
}

505
static HRESULT  WINAPI  IDirect3DDevice9Impl_SetTransform(LPDIRECT3DDEVICE9 iface, D3DTRANSFORMSTATETYPE State, CONST D3DMATRIX* lpMatrix) {
506
    IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
507
    TRACE("(%p) Relay\n" , This);
508 509 510

    /* Note: D3DMATRIX is compatible with WINED3DMATRIX */
    return IWineD3DDevice_SetTransform(This->WineD3DDevice, State, (CONST WINED3DMATRIX*) lpMatrix);
511 512
}

513
static HRESULT  WINAPI  IDirect3DDevice9Impl_GetTransform(LPDIRECT3DDEVICE9 iface, D3DTRANSFORMSTATETYPE State, D3DMATRIX* pMatrix) {
514
    IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
515
    TRACE("(%p) Relay\n" , This);
516 517 518

    /* Note: D3DMATRIX is compatible with WINED3DMATRIX */
    return IWineD3DDevice_GetTransform(This->WineD3DDevice, State, (WINED3DMATRIX*) pMatrix);
519 520
}

521
static HRESULT  WINAPI  IDirect3DDevice9Impl_MultiplyTransform(LPDIRECT3DDEVICE9 iface, D3DTRANSFORMSTATETYPE State, CONST D3DMATRIX* pMatrix) {
522
    IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
523
    TRACE("(%p) Relay\n" , This);
524 525 526

    /* Note: D3DMATRIX is compatible with WINED3DMATRIX */
    return IWineD3DDevice_MultiplyTransform(This->WineD3DDevice, State, (CONST WINED3DMATRIX*) pMatrix);
527 528
}

529
static HRESULT  WINAPI  IDirect3DDevice9Impl_SetViewport(LPDIRECT3DDEVICE9 iface, CONST D3DVIEWPORT9* pViewport) {
530
    IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
531
    TRACE("(%p) Relay\n" , This);
532 533

    /* Note: D3DVIEWPORT9 is compatible with WINED3DVIEWPORT */
Eric Pouech's avatar
Eric Pouech committed
534
    return IWineD3DDevice_SetViewport(This->WineD3DDevice, (const WINED3DVIEWPORT *)pViewport);
535 536
}

537
static HRESULT  WINAPI  IDirect3DDevice9Impl_GetViewport(LPDIRECT3DDEVICE9 iface, D3DVIEWPORT9* pViewport) {
538
    IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
539
    TRACE("(%p) Relay\n" , This);
540 541

    /* Note: D3DVIEWPORT9 is compatible with WINED3DVIEWPORT */
542
    return IWineD3DDevice_GetViewport(This->WineD3DDevice, (WINED3DVIEWPORT *)pViewport);
543 544
}

545
static HRESULT  WINAPI  IDirect3DDevice9Impl_SetMaterial(LPDIRECT3DDEVICE9 iface, CONST D3DMATERIAL9* pMaterial) {
546
    IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
547
    TRACE("(%p) Relay\n" , This);
548 549

    /* Note: D3DMATERIAL9 is compatible with WINED3DMATERIAL */
Eric Pouech's avatar
Eric Pouech committed
550
    return IWineD3DDevice_SetMaterial(This->WineD3DDevice, (const WINED3DMATERIAL *)pMaterial);
551 552
}

553
static HRESULT  WINAPI  IDirect3DDevice9Impl_GetMaterial(LPDIRECT3DDEVICE9 iface, D3DMATERIAL9* pMaterial) {
554
    IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
555
    TRACE("(%p) Relay\n" , This);
556 557

    /* Note: D3DMATERIAL9 is compatible with WINED3DMATERIAL */
558
    return IWineD3DDevice_GetMaterial(This->WineD3DDevice, (WINED3DMATERIAL *)pMaterial);
559 560
}

561
static HRESULT  WINAPI  IDirect3DDevice9Impl_SetLight(LPDIRECT3DDEVICE9 iface, DWORD Index, CONST D3DLIGHT9* pLight) {
562
    IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
563
    TRACE("(%p) Relay\n" , This);
564 565

    /* Note: D3DLIGHT9 is compatible with WINED3DLIGHT */
Eric Pouech's avatar
Eric Pouech committed
566
    return IWineD3DDevice_SetLight(This->WineD3DDevice, Index, (const WINED3DLIGHT *)pLight);
567 568
}

569
static HRESULT  WINAPI  IDirect3DDevice9Impl_GetLight(LPDIRECT3DDEVICE9 iface, DWORD Index, D3DLIGHT9* pLight) {
570
    IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
571
    TRACE("(%p) Relay\n" , This);
572 573

    /* Note: D3DLIGHT9 is compatible with WINED3DLIGHT */
574
    return IWineD3DDevice_GetLight(This->WineD3DDevice, Index, (WINED3DLIGHT *)pLight);
575 576
}

577
static HRESULT  WINAPI  IDirect3DDevice9Impl_LightEnable(LPDIRECT3DDEVICE9 iface, DWORD Index, BOOL Enable) {
578
    IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
579
    TRACE("(%p) Relay\n" , This);
580
    return IWineD3DDevice_SetLightEnable(This->WineD3DDevice, Index, Enable);
581 582
}

583
static HRESULT  WINAPI  IDirect3DDevice9Impl_GetLightEnable(LPDIRECT3DDEVICE9 iface, DWORD Index, BOOL* pEnable) {
584
    IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
585
    TRACE("(%p) Relay\n" , This);
586
    return IWineD3DDevice_GetLightEnable(This->WineD3DDevice, Index, pEnable);
587 588
}

589
static HRESULT  WINAPI  IDirect3DDevice9Impl_SetClipPlane(LPDIRECT3DDEVICE9 iface, DWORD Index, CONST float* pPlane) {
590
    IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
591
    TRACE("(%p) Relay\n" , This);
592
    return IWineD3DDevice_SetClipPlane(This->WineD3DDevice, Index, pPlane);
593 594
}

595
static HRESULT  WINAPI  IDirect3DDevice9Impl_GetClipPlane(LPDIRECT3DDEVICE9 iface, DWORD Index, float* pPlane) {
596
    IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
597
    TRACE("(%p) Relay\n" , This);
598
    return IWineD3DDevice_GetClipPlane(This->WineD3DDevice, Index, pPlane);
599 600
}

601
static HRESULT  WINAPI  IDirect3DDevice9Impl_SetRenderState(LPDIRECT3DDEVICE9 iface, D3DRENDERSTATETYPE State, DWORD Value) {
602
    IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
603
    TRACE("(%p) Relay\n" , This);
604
    return IWineD3DDevice_SetRenderState(This->WineD3DDevice, State, Value);
605 606
}

607
static HRESULT  WINAPI  IDirect3DDevice9Impl_GetRenderState(LPDIRECT3DDEVICE9 iface, D3DRENDERSTATETYPE State, DWORD* pValue) {
608
    IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
609
    TRACE("(%p) Relay\n" , This);
610
    return IWineD3DDevice_GetRenderState(This->WineD3DDevice, State, pValue);
611 612
}

613
static HRESULT  WINAPI  IDirect3DDevice9Impl_SetClipStatus(LPDIRECT3DDEVICE9 iface, CONST D3DCLIPSTATUS9* pClipStatus) {
614
    IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
615
    TRACE("(%p) Relay\n" , This);
Eric Pouech's avatar
Eric Pouech committed
616
    return IWineD3DDevice_SetClipStatus(This->WineD3DDevice, (const WINED3DCLIPSTATUS *)pClipStatus);
617 618
}

619
static HRESULT  WINAPI  IDirect3DDevice9Impl_GetClipStatus(LPDIRECT3DDEVICE9 iface, D3DCLIPSTATUS9* pClipStatus) {
620
    IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
621
    TRACE("(%p) Relay\n" , This);
622
    return IWineD3DDevice_GetClipStatus(This->WineD3DDevice, (WINED3DCLIPSTATUS *)pClipStatus);
623 624
}

625
static HRESULT  WINAPI  IDirect3DDevice9Impl_GetTexture(LPDIRECT3DDEVICE9 iface, DWORD Stage, IDirect3DBaseTexture9 **ppTexture) {
626
    IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
627 628 629
    IWineD3DBaseTexture *retTexture = NULL;
    HRESULT rc = D3D_OK;

630 631 632 633 634 635
    TRACE("(%p) Relay\n" , This);

    if(ppTexture == NULL){
        return D3DERR_INVALIDCALL;
    }

636
    rc = IWineD3DDevice_GetTexture(This->WineD3DDevice, Stage, (IWineD3DBaseTexture **)&retTexture);
637
    if (rc == D3D_OK && NULL != retTexture) {
638
        IWineD3DBaseTexture_GetParent(retTexture, (IUnknown **)ppTexture);
639
        IWineD3DBaseTexture_Release(retTexture);
640
    }else{
641
        FIXME("Call to get texture  (%d) failed (%p)\n", Stage, retTexture);
642
        *ppTexture = NULL;
643 644
    }
    return rc;
645 646
}

647
static HRESULT  WINAPI  IDirect3DDevice9Impl_SetTexture(LPDIRECT3DDEVICE9 iface, DWORD Stage, IDirect3DBaseTexture9* pTexture) {
648
    IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
649
    TRACE("(%p) Relay %d %p\n" , This, Stage, pTexture);
650 651
    return IWineD3DDevice_SetTexture(This->WineD3DDevice, Stage,
                                     pTexture==NULL ? NULL:((IDirect3DBaseTexture9Impl *)pTexture)->wineD3DBaseTexture); 
652 653
}

654
static HRESULT  WINAPI  IDirect3DDevice9Impl_GetTextureStageState(LPDIRECT3DDEVICE9 iface, DWORD Stage, D3DTEXTURESTAGESTATETYPE Type, DWORD* pValue) {
655
    IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
656
    TRACE("(%p) Relay\n" , This);
657
    return IWineD3DDevice_GetTextureStageState(This->WineD3DDevice, Stage, Type, pValue);
658 659
}

660
static HRESULT  WINAPI  IDirect3DDevice9Impl_SetTextureStageState(LPDIRECT3DDEVICE9 iface, DWORD Stage, D3DTEXTURESTAGESTATETYPE Type, DWORD Value) {
661
    IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
662
    TRACE("(%p) Relay\n" , This);
663
    return IWineD3DDevice_SetTextureStageState(This->WineD3DDevice, Stage, Type, Value);
664 665
}

666
static HRESULT  WINAPI  IDirect3DDevice9Impl_GetSamplerState(LPDIRECT3DDEVICE9 iface, DWORD Sampler, D3DSAMPLERSTATETYPE Type, DWORD* pValue) {
667 668 669
    IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;    
    TRACE("(%p) Relay\n" , This);
    return IWineD3DDevice_GetSamplerState(This->WineD3DDevice, Sampler, Type, pValue);
670 671
}

672
static HRESULT  WINAPI  IDirect3DDevice9Impl_SetSamplerState(LPDIRECT3DDEVICE9 iface, DWORD Sampler, D3DSAMPLERSTATETYPE Type, DWORD Value) {
673
    IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
674 675
    TRACE("(%p) Relay\n" , This);
    return IWineD3DDevice_SetSamplerState(This->WineD3DDevice, Sampler, Type, Value);    
676 677
}

678
static HRESULT  WINAPI  IDirect3DDevice9Impl_ValidateDevice(LPDIRECT3DDEVICE9 iface, DWORD* pNumPasses) {
679
    IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
680 681
    TRACE("(%p) Relay\n" , This);
    return IWineD3DDevice_ValidateDevice(This->WineD3DDevice, pNumPasses);
682 683
}

684
static HRESULT  WINAPI  IDirect3DDevice9Impl_SetPaletteEntries(LPDIRECT3DDEVICE9 iface, UINT PaletteNumber, CONST PALETTEENTRY* pEntries) {
685 686 687
    IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;    
    TRACE("(%p) Relay\n" , This);
    return IWineD3DDevice_SetPaletteEntries(This->WineD3DDevice, PaletteNumber, pEntries);
688 689
}

690
static HRESULT  WINAPI  IDirect3DDevice9Impl_GetPaletteEntries(LPDIRECT3DDEVICE9 iface, UINT PaletteNumber, PALETTEENTRY* pEntries) {
691
    IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
692 693
    TRACE("(%p) Relay\n" , This);
    return IWineD3DDevice_GetPaletteEntries(This->WineD3DDevice, PaletteNumber, pEntries);
694 695
}

696
static HRESULT  WINAPI  IDirect3DDevice9Impl_SetCurrentTexturePalette(LPDIRECT3DDEVICE9 iface, UINT PaletteNumber) {
697
    IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
698 699
    TRACE("(%p) Relay\n" , This);
    return IWineD3DDevice_SetCurrentTexturePalette(This->WineD3DDevice, PaletteNumber);
700 701
}

702
static HRESULT  WINAPI  IDirect3DDevice9Impl_GetCurrentTexturePalette(LPDIRECT3DDEVICE9 iface, UINT* PaletteNumber) {
703
    IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
704 705
    TRACE("(%p) Relay\n" , This);
    return IWineD3DDevice_GetCurrentTexturePalette(This->WineD3DDevice, PaletteNumber);
706 707
}

708
static HRESULT  WINAPI  IDirect3DDevice9Impl_SetScissorRect(LPDIRECT3DDEVICE9 iface, CONST RECT* pRect) {
709
    IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
710 711
    TRACE("(%p) Relay\n" , This);
    return IWineD3DDevice_SetScissorRect(This->WineD3DDevice, pRect);    
712 713
}

714
static HRESULT  WINAPI  IDirect3DDevice9Impl_GetScissorRect(LPDIRECT3DDEVICE9 iface, RECT* pRect) {
715
    IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
716 717
    TRACE("(%p) Relay\n" , This);
    return IWineD3DDevice_GetScissorRect(This->WineD3DDevice, pRect);   
718 719
}

720
static HRESULT  WINAPI  IDirect3DDevice9Impl_SetSoftwareVertexProcessing(LPDIRECT3DDEVICE9 iface, BOOL bSoftware) {
721
    IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
722 723
    TRACE("(%p) Relay\n" , This);
    return IWineD3DDevice_SetSoftwareVertexProcessing(This->WineD3DDevice, bSoftware);
724 725
}

726
static BOOL     WINAPI  IDirect3DDevice9Impl_GetSoftwareVertexProcessing(LPDIRECT3DDEVICE9 iface) {
727
    IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
728 729
    TRACE("(%p) Relay\n" , This);
    return IWineD3DDevice_GetSoftwareVertexProcessing(This->WineD3DDevice);
730 731
}

732
static HRESULT  WINAPI  IDirect3DDevice9Impl_SetNPatchMode(LPDIRECT3DDEVICE9 iface, float nSegments) {
733
    IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
734 735
    TRACE("(%p) Relay\n" , This);
    return IWineD3DDevice_SetNPatchMode(This->WineD3DDevice, nSegments);
736 737
}

738
static float    WINAPI  IDirect3DDevice9Impl_GetNPatchMode(LPDIRECT3DDEVICE9 iface) {
739
    IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
740 741
    TRACE("(%p) Relay\n" , This);
    return IWineD3DDevice_GetNPatchMode(This->WineD3DDevice);
742 743
}

744
static HRESULT WINAPI IDirect3DDevice9Impl_DrawPrimitive(LPDIRECT3DDEVICE9 iface, D3DPRIMITIVETYPE PrimitiveType, UINT StartVertex, UINT PrimitiveCount) {
745 746
    IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;    
    TRACE("(%p) Relay\n" , This);
747
    return IWineD3DDevice_DrawPrimitive(This->WineD3DDevice, PrimitiveType, StartVertex, PrimitiveCount);
748 749
}

750
static HRESULT  WINAPI  IDirect3DDevice9Impl_DrawIndexedPrimitive(LPDIRECT3DDEVICE9 iface, D3DPRIMITIVETYPE PrimitiveType,
751
                                                           INT BaseVertexIndex, UINT MinVertexIndex, UINT NumVertices, UINT startIndex, UINT primCount) {
752
    IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
753
    TRACE("(%p) Relay\n" , This);
754 755 756 757

    /* D3D8 passes the baseVertexIndex in SetIndices, and due to the stateblock functions wined3d has to work that way */
    IWineD3DDevice_SetBaseVertexIndex(This->WineD3DDevice, BaseVertexIndex);
    return IWineD3DDevice_DrawIndexedPrimitive(This->WineD3DDevice, PrimitiveType, MinVertexIndex, NumVertices, startIndex, primCount);
758 759
}

760
static HRESULT  WINAPI  IDirect3DDevice9Impl_DrawPrimitiveUP(LPDIRECT3DDEVICE9 iface, D3DPRIMITIVETYPE PrimitiveType, UINT PrimitiveCount, CONST void* pVertexStreamZeroData, UINT VertexStreamZeroStride) {
761 762
    IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;    
    TRACE("(%p) Relay\n" , This);
763
    return IWineD3DDevice_DrawPrimitiveUP(This->WineD3DDevice, PrimitiveType, PrimitiveCount, pVertexStreamZeroData, VertexStreamZeroStride);
764 765
}

766
static HRESULT  WINAPI  IDirect3DDevice9Impl_DrawIndexedPrimitiveUP(LPDIRECT3DDEVICE9 iface, D3DPRIMITIVETYPE PrimitiveType, UINT MinVertexIndex,
767 768
                                                             UINT NumVertexIndices, UINT PrimitiveCount, CONST void* pIndexData,
                                                             D3DFORMAT IndexDataFormat, CONST void* pVertexStreamZeroData, UINT VertexStreamZeroStride) {
769
    IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
770
    TRACE("(%p) Relay\n" , This);
771 772
    return IWineD3DDevice_DrawIndexedPrimitiveUP(This->WineD3DDevice, PrimitiveType, MinVertexIndex, NumVertexIndices, PrimitiveCount,
                                                 pIndexData, IndexDataFormat, pVertexStreamZeroData, VertexStreamZeroStride);
773 774
}

775
static HRESULT  WINAPI  IDirect3DDevice9Impl_ProcessVertices(LPDIRECT3DDEVICE9 iface, UINT SrcStartIndex, UINT DestIndex, UINT VertexCount, IDirect3DVertexBuffer9* pDestBuffer, IDirect3DVertexDeclaration9* pVertexDecl, DWORD Flags) {
776
    IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
777
    IDirect3DVertexDeclaration9Impl *Decl = (IDirect3DVertexDeclaration9Impl *) pVertexDecl;
778
    TRACE("(%p) Relay\n" , This);
779
    return IWineD3DDevice_ProcessVertices(This->WineD3DDevice,SrcStartIndex, DestIndex, VertexCount, ((IDirect3DVertexBuffer9Impl *)pDestBuffer)->wineD3DVertexBuffer, Decl ? Decl->wineD3DVertexDeclaration : NULL, Flags);
780 781
}

782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829
IDirect3DVertexDeclaration9 *getConvertedDecl(IDirect3DDevice9Impl *This, DWORD fvf) {
    HRESULT hr;
    D3DVERTEXELEMENT9* elements = NULL;
    IDirect3DVertexDeclaration9* pDecl = NULL;
    int p, low, high; /* deliberately signed */
    IDirect3DVertexDeclaration9  **convertedDecls = This->convertedDecls;

    TRACE("Searching for declaration for fvf %08x... ", fvf);

    low = 0;
    high = This->numConvertedDecls - 1;
    while(low <= high) {
        p = (low + high) >> 1;
        TRACE("%d ", p);
        if(((IDirect3DVertexDeclaration9Impl *) convertedDecls[p])->convFVF == fvf) {
            TRACE("found %p\n", convertedDecls[p]);
            return convertedDecls[p];
        } else if(((IDirect3DVertexDeclaration9Impl *) convertedDecls[p])->convFVF < fvf) {
            low = p + 1;
        } else {
            high = p - 1;
        }
    }
    TRACE("not found. Creating and inserting at position %d.\n", low);

    hr = vdecl_convert_fvf(fvf, &elements);
    if (hr != S_OK) return NULL;

    hr = IDirect3DDevice9Impl_CreateVertexDeclaration((IDirect3DDevice9 *) This, elements, &pDecl);
    if (hr != S_OK) return NULL;

    if(This->declArraySize == This->numConvertedDecls) {
        int grow = max(This->declArraySize / 2, 8);
        convertedDecls = HeapReAlloc(GetProcessHeap(), 0, convertedDecls,
                                     sizeof(convertedDecls[0]) * (This->numConvertedDecls + grow));
        if(!convertedDecls) {
            /* This will destroy it */
            IDirect3DVertexDeclaration9_Release(pDecl);
            return NULL;
        }
        This->convertedDecls = convertedDecls;
        This->declArraySize += grow;
    }

    memmove(convertedDecls + low + 1, convertedDecls + low, sizeof(IDirect3DVertexDeclaration9Impl *) * (This->numConvertedDecls - low));
    convertedDecls[low] = pDecl;
    This->numConvertedDecls++;

830
    /* Will prevent the decl from being destroyed */
831 832 833 834 835 836 837
    ((IDirect3DVertexDeclaration9Impl *) pDecl)->convFVF = fvf;
    IDirect3DVertexDeclaration9_Release(pDecl); /* Does not destroy now */

    TRACE("Returning %p. %d decls in array\n", pDecl, This->numConvertedDecls);
    return pDecl;
}

838
HRESULT  WINAPI  IDirect3DDevice9Impl_SetFVF(LPDIRECT3DDEVICE9 iface, DWORD FVF) {
839
    IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
840
    TRACE("(%p) Relay\n" , This);
841 842 843

    if (0 != FVF) {
         HRESULT hr;
844
         IDirect3DVertexDeclaration9* pDecl = getConvertedDecl(This, FVF);
845

846 847 848 849 850
         if(!pDecl) {
             /* Any situation when this should happen, except out of memory? */
             ERR("Failed to create a converted vertex declaration\n");
             return D3DERR_DRIVERINTERNALERROR;
         }
851

852 853 854 855
         hr = IDirect3DDevice9Impl_SetVertexDeclaration(iface, pDecl);
         if (hr != S_OK) return hr;
    }

856
    return IWineD3DDevice_SetFVF(This->WineD3DDevice, FVF);
857 858 859
}

HRESULT  WINAPI  IDirect3DDevice9Impl_GetFVF(LPDIRECT3DDEVICE9 iface, DWORD* pFVF) {
860
    IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
861
    TRACE("(%p) Relay\n" , This);
862
    return IWineD3DDevice_GetFVF(This->WineD3DDevice, pFVF);
863 864 865
}

HRESULT  WINAPI  IDirect3DDevice9Impl_SetStreamSource(LPDIRECT3DDEVICE9 iface, UINT StreamNumber, IDirect3DVertexBuffer9* pStreamData, UINT OffsetInBytes, UINT Stride) {
866
    IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
867
    TRACE("(%p) Relay\n" , This);
868 869 870
    return IWineD3DDevice_SetStreamSource(This->WineD3DDevice, StreamNumber, 
                                          pStreamData==NULL ? NULL:((IDirect3DVertexBuffer9Impl *)pStreamData)->wineD3DVertexBuffer, 
                                          OffsetInBytes, Stride);
871 872
}

873
HRESULT  WINAPI  IDirect3DDevice9Impl_GetStreamSource(LPDIRECT3DDEVICE9 iface, UINT StreamNumber, IDirect3DVertexBuffer9 **pStream, UINT* OffsetInBytes, UINT* pStride) {
874
    IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
875 876 877
    IWineD3DVertexBuffer *retStream = NULL;
    HRESULT rc = D3D_OK;

878 879 880 881 882 883
    TRACE("(%p) Relay\n" , This);

    if(pStream == NULL){
        return D3DERR_INVALIDCALL;
    }

884
    rc = IWineD3DDevice_GetStreamSource(This->WineD3DDevice, StreamNumber, (IWineD3DVertexBuffer **)&retStream, OffsetInBytes, pStride);
885
    if (rc == D3D_OK  && NULL != retStream) {
886
        IWineD3DVertexBuffer_GetParent(retStream, (IUnknown **)pStream);
887
        IWineD3DVertexBuffer_Release(retStream);
888
    }else{
889 890 891
        if (rc != D3D_OK){
            FIXME("Call to GetStreamSource failed %p %p\n", OffsetInBytes, pStride);
        }
892
        *pStream = NULL;
893
    }
894
    return rc;
895 896
}

897
static HRESULT  WINAPI  IDirect3DDevice9Impl_SetStreamSourceFreq(LPDIRECT3DDEVICE9 iface, UINT StreamNumber, UINT Divider) {
898 899 900
    IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;    
    TRACE("(%p) Relay\n" , This);
    IWineD3DDevice_SetStreamSourceFreq(This->WineD3DDevice, StreamNumber, Divider);
901 902 903
    return D3D_OK;
}

904
static HRESULT  WINAPI  IDirect3DDevice9Impl_GetStreamSourceFreq(LPDIRECT3DDEVICE9 iface, UINT StreamNumber, UINT* Divider) {
905
    IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
906 907
    TRACE("(%p) Relay\n" , This);
    return IWineD3DDevice_GetStreamSourceFreq(This->WineD3DDevice, StreamNumber, Divider);
908 909
}

910
static HRESULT  WINAPI  IDirect3DDevice9Impl_SetIndices(LPDIRECT3DDEVICE9 iface, IDirect3DIndexBuffer9* pIndexData) {
911
    IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
912
    TRACE("(%p) Relay\n", This);
913 914
    return IWineD3DDevice_SetIndices(This->WineD3DDevice,
            pIndexData ? ((IDirect3DIndexBuffer9Impl *)pIndexData)->wineD3DIndexBuffer : NULL);
915 916
}

917
static HRESULT  WINAPI  IDirect3DDevice9Impl_GetIndices(LPDIRECT3DDEVICE9 iface, IDirect3DIndexBuffer9 **ppIndexData) {
918
    IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
919 920
    IWineD3DIndexBuffer *retIndexData = NULL;
    HRESULT rc = D3D_OK;
921

922 923 924 925 926 927
    TRACE("(%p) Relay\n", This);

    if(ppIndexData == NULL){
        return D3DERR_INVALIDCALL;
    }

928 929
    rc = IWineD3DDevice_GetIndices(This->WineD3DDevice, &retIndexData);
    if (SUCCEEDED(rc) && retIndexData) {
930 931
        IWineD3DIndexBuffer_GetParent(retIndexData, (IUnknown **)ppIndexData);
        IWineD3DIndexBuffer_Release(retIndexData);
932 933
    } else {
        if (FAILED(rc)) FIXME("Call to GetIndices failed\n");
934
        *ppIndexData = NULL;
935 936
    }
    return rc;
937 938
}

939
static HRESULT  WINAPI  IDirect3DDevice9Impl_DrawRectPatch(LPDIRECT3DDEVICE9 iface, UINT Handle, CONST float* pNumSegs, CONST D3DRECTPATCH_INFO* pRectPatchInfo) {
940
    IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
941
    TRACE("(%p) Relay\n", This);
942
    return IWineD3DDevice_DrawRectPatch(This->WineD3DDevice, Handle, pNumSegs, (CONST WINED3DRECTPATCH_INFO *)pRectPatchInfo);
943
}
944
/*http://msdn.microsoft.com/library/default.asp?url=/library/en-us/directx9_c/directx/graphics/reference/d3d/interfaces/idirect3ddevice9/DrawTriPatch.asp*/
945
static HRESULT  WINAPI  IDirect3DDevice9Impl_DrawTriPatch(LPDIRECT3DDEVICE9 iface, UINT Handle, CONST float* pNumSegs, CONST D3DTRIPATCH_INFO* pTriPatchInfo) {
946
    IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
947
    TRACE("(%p) Relay\n", This);
948
    return IWineD3DDevice_DrawTriPatch(This->WineD3DDevice, Handle, pNumSegs, (CONST WINED3DTRIPATCH_INFO *)pTriPatchInfo);
949 950
}

951
static HRESULT  WINAPI  IDirect3DDevice9Impl_DeletePatch(LPDIRECT3DDEVICE9 iface, UINT Handle) {
952
    IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
953 954
    TRACE("(%p) Relay\n", This);
    return IWineD3DDevice_DeletePatch(This->WineD3DDevice, Handle);
955 956
}

957
const IDirect3DDevice9Vtbl Direct3DDevice9_Vtbl =
958
{
959
    /* IUnknown */
960 961 962
    IDirect3DDevice9Impl_QueryInterface,
    IDirect3DDevice9Impl_AddRef,
    IDirect3DDevice9Impl_Release,
963
    /* IDirect3DDevice9 */
964 965
    IDirect3DDevice9Impl_TestCooperativeLevel,
    IDirect3DDevice9Impl_GetAvailableTextureMem,
966
    IDirect3DDevice9Impl_EvictManagedResources,
967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994
    IDirect3DDevice9Impl_GetDirect3D,
    IDirect3DDevice9Impl_GetDeviceCaps,
    IDirect3DDevice9Impl_GetDisplayMode,
    IDirect3DDevice9Impl_GetCreationParameters,
    IDirect3DDevice9Impl_SetCursorProperties,
    IDirect3DDevice9Impl_SetCursorPosition,
    IDirect3DDevice9Impl_ShowCursor,
    IDirect3DDevice9Impl_CreateAdditionalSwapChain,
    IDirect3DDevice9Impl_GetSwapChain,
    IDirect3DDevice9Impl_GetNumberOfSwapChains,
    IDirect3DDevice9Impl_Reset,
    IDirect3DDevice9Impl_Present,
    IDirect3DDevice9Impl_GetBackBuffer,
    IDirect3DDevice9Impl_GetRasterStatus,
    IDirect3DDevice9Impl_SetDialogBoxMode,
    IDirect3DDevice9Impl_SetGammaRamp,
    IDirect3DDevice9Impl_GetGammaRamp,
    IDirect3DDevice9Impl_CreateTexture,
    IDirect3DDevice9Impl_CreateVolumeTexture,
    IDirect3DDevice9Impl_CreateCubeTexture,
    IDirect3DDevice9Impl_CreateVertexBuffer,
    IDirect3DDevice9Impl_CreateIndexBuffer,
    IDirect3DDevice9Impl_CreateRenderTarget,
    IDirect3DDevice9Impl_CreateDepthStencilSurface,
    IDirect3DDevice9Impl_UpdateSurface,
    IDirect3DDevice9Impl_UpdateTexture,
    IDirect3DDevice9Impl_GetRenderTargetData,
    IDirect3DDevice9Impl_GetFrontBufferData,
995
    IDirect3DDevice9Impl_StretchRect,
996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080
    IDirect3DDevice9Impl_ColorFill,
    IDirect3DDevice9Impl_CreateOffscreenPlainSurface,
    IDirect3DDevice9Impl_SetRenderTarget,
    IDirect3DDevice9Impl_GetRenderTarget,
    IDirect3DDevice9Impl_SetDepthStencilSurface,
    IDirect3DDevice9Impl_GetDepthStencilSurface,
    IDirect3DDevice9Impl_BeginScene,
    IDirect3DDevice9Impl_EndScene,
    IDirect3DDevice9Impl_Clear,
    IDirect3DDevice9Impl_SetTransform,
    IDirect3DDevice9Impl_GetTransform,
    IDirect3DDevice9Impl_MultiplyTransform,
    IDirect3DDevice9Impl_SetViewport,
    IDirect3DDevice9Impl_GetViewport,
    IDirect3DDevice9Impl_SetMaterial,
    IDirect3DDevice9Impl_GetMaterial,
    IDirect3DDevice9Impl_SetLight,
    IDirect3DDevice9Impl_GetLight,
    IDirect3DDevice9Impl_LightEnable,
    IDirect3DDevice9Impl_GetLightEnable,
    IDirect3DDevice9Impl_SetClipPlane,
    IDirect3DDevice9Impl_GetClipPlane,
    IDirect3DDevice9Impl_SetRenderState,
    IDirect3DDevice9Impl_GetRenderState,
    IDirect3DDevice9Impl_CreateStateBlock,
    IDirect3DDevice9Impl_BeginStateBlock,
    IDirect3DDevice9Impl_EndStateBlock,
    IDirect3DDevice9Impl_SetClipStatus,
    IDirect3DDevice9Impl_GetClipStatus,
    IDirect3DDevice9Impl_GetTexture,
    IDirect3DDevice9Impl_SetTexture,
    IDirect3DDevice9Impl_GetTextureStageState,
    IDirect3DDevice9Impl_SetTextureStageState,
    IDirect3DDevice9Impl_GetSamplerState,
    IDirect3DDevice9Impl_SetSamplerState,
    IDirect3DDevice9Impl_ValidateDevice,
    IDirect3DDevice9Impl_SetPaletteEntries,
    IDirect3DDevice9Impl_GetPaletteEntries,
    IDirect3DDevice9Impl_SetCurrentTexturePalette,
    IDirect3DDevice9Impl_GetCurrentTexturePalette,
    IDirect3DDevice9Impl_SetScissorRect,
    IDirect3DDevice9Impl_GetScissorRect,
    IDirect3DDevice9Impl_SetSoftwareVertexProcessing,
    IDirect3DDevice9Impl_GetSoftwareVertexProcessing,
    IDirect3DDevice9Impl_SetNPatchMode,
    IDirect3DDevice9Impl_GetNPatchMode,
    IDirect3DDevice9Impl_DrawPrimitive,
    IDirect3DDevice9Impl_DrawIndexedPrimitive,
    IDirect3DDevice9Impl_DrawPrimitiveUP,
    IDirect3DDevice9Impl_DrawIndexedPrimitiveUP,
    IDirect3DDevice9Impl_ProcessVertices,
    IDirect3DDevice9Impl_CreateVertexDeclaration,
    IDirect3DDevice9Impl_SetVertexDeclaration,
    IDirect3DDevice9Impl_GetVertexDeclaration,
    IDirect3DDevice9Impl_SetFVF,
    IDirect3DDevice9Impl_GetFVF,
    IDirect3DDevice9Impl_CreateVertexShader,
    IDirect3DDevice9Impl_SetVertexShader,
    IDirect3DDevice9Impl_GetVertexShader,
    IDirect3DDevice9Impl_SetVertexShaderConstantF,
    IDirect3DDevice9Impl_GetVertexShaderConstantF,
    IDirect3DDevice9Impl_SetVertexShaderConstantI,
    IDirect3DDevice9Impl_GetVertexShaderConstantI,
    IDirect3DDevice9Impl_SetVertexShaderConstantB,
    IDirect3DDevice9Impl_GetVertexShaderConstantB,
    IDirect3DDevice9Impl_SetStreamSource,
    IDirect3DDevice9Impl_GetStreamSource,
    IDirect3DDevice9Impl_SetStreamSourceFreq,
    IDirect3DDevice9Impl_GetStreamSourceFreq,
    IDirect3DDevice9Impl_SetIndices,
    IDirect3DDevice9Impl_GetIndices,
    IDirect3DDevice9Impl_CreatePixelShader,
    IDirect3DDevice9Impl_SetPixelShader,
    IDirect3DDevice9Impl_GetPixelShader,
    IDirect3DDevice9Impl_SetPixelShaderConstantF,
    IDirect3DDevice9Impl_GetPixelShaderConstantF,
    IDirect3DDevice9Impl_SetPixelShaderConstantI,
    IDirect3DDevice9Impl_GetPixelShaderConstantI,
    IDirect3DDevice9Impl_SetPixelShaderConstantB,
    IDirect3DDevice9Impl_GetPixelShaderConstantB,
    IDirect3DDevice9Impl_DrawRectPatch,
    IDirect3DDevice9Impl_DrawTriPatch,
    IDirect3DDevice9Impl_DeletePatch,
    IDirect3DDevice9Impl_CreateQuery
};
1081 1082 1083


/* Internal function called back during the CreateDevice to create a render target  */
1084
HRESULT WINAPI D3D9CB_CreateSurface(IUnknown *device, IUnknown *pSuperior, UINT Width, UINT Height,
1085
                                         WINED3DFORMAT Format, DWORD Usage, WINED3DPOOL Pool, UINT Level,
1086 1087
                                         WINED3DCUBEMAP_FACES Face,IWineD3DSurface** ppSurface,
                                         HANDLE* pSharedHandle) {
1088

1089 1090 1091 1092 1093 1094 1095 1096
    HRESULT res = D3D_OK;
    IDirect3DSurface9Impl *d3dSurface = NULL;
    BOOL Lockable = TRUE;
    
    if((Pool == D3DPOOL_DEFAULT &&  Usage != D3DUSAGE_DYNAMIC)) 
        Lockable = FALSE;
        
    TRACE("relay\n");
1097 1098 1099
    res = IDirect3DDevice9Impl_CreateSurface((IDirect3DDevice9 *)device, Width, Height, (D3DFORMAT)Format,
                Lockable, FALSE/*Discard*/, Level,  (IDirect3DSurface9 **)&d3dSurface, D3DRTYPE_SURFACE,
                Usage, (D3DPOOL) Pool, D3DMULTISAMPLE_NONE, 0 /* MultisampleQuality */, pSharedHandle);  
1100

1101
    if (SUCCEEDED(res)) {
1102
        *ppSurface = d3dSurface->wineD3DSurface;
1103
        d3dSurface->container = pSuperior;
1104 1105
        IUnknown_Release(d3dSurface->parentDevice);
        d3dSurface->parentDevice = NULL;
1106
        d3dSurface->forwardReference = pSuperior;
1107
    } else {
1108 1109 1110 1111
        FIXME("(%p) IDirect3DDevice9_CreateSurface failed\n", device);
    }
    return res;
}
1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122

ULONG WINAPI D3D9CB_DestroySurface(IWineD3DSurface *pSurface) {
    IDirect3DSurface9Impl* surfaceParent;
    TRACE("(%p) call back\n", pSurface);

    IWineD3DSurface_GetParent(pSurface, (IUnknown **) &surfaceParent);
    /* GetParent's AddRef was forwarded to an object in destruction.
     * Releasing it here again would cause an endless recursion. */
    surfaceParent->forwardReference = NULL;
    return IDirect3DSurface9_Release((IDirect3DSurface9*) surfaceParent);
}