Remove the remaining casts of NULL.
[wine] / dlls / d3d8 / device.c
1 /*
2  * IDirect3DDevice8 implementation
3  *
4  * Copyright 2002-2004 Jason Edmeades
5  * Copyright 2004 Christian Costa
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20  */
21
22 #include "config.h"
23
24 #include <math.h>
25 #include <stdarg.h>
26
27 #define NONAMELESSUNION
28 #define NONAMELESSSTRUCT
29 #include "windef.h"
30 #include "winbase.h"
31 #include "winuser.h"
32 #include "wingdi.h"
33 #include "wine/debug.h"
34
35 #include "d3d8_private.h"
36
37 WINE_DEFAULT_DEBUG_CHANNEL(d3d8);
38
39 /* Shader handle functions */
40 static shader_handle *alloc_shader_handle(IDirect3DDevice8Impl *This) {
41     if (This->free_shader_handles) {
42         /* Use a free handle */
43         shader_handle *handle = This->free_shader_handles;
44         This->free_shader_handles = *handle;
45         return handle;
46     }
47     if (!(This->allocated_shader_handles < This->shader_handle_table_size)) {
48         /* Grow the table */
49         DWORD new_size = This->shader_handle_table_size + (This->shader_handle_table_size >> 1);
50         shader_handle *new_handles = HeapReAlloc(GetProcessHeap(), 0, This->shader_handles, new_size * sizeof(shader_handle));
51         if (!new_handles) return NULL;
52         This->shader_handles = new_handles;
53         This->shader_handle_table_size = new_size;
54     }
55
56     return &This->shader_handles[This->allocated_shader_handles++];
57 }
58
59 static void free_shader_handle(IDirect3DDevice8Impl *This, shader_handle *handle) {
60     *handle = This->free_shader_handles;
61     This->free_shader_handles = handle;
62 }
63
64 /* IDirect3D IUnknown parts follow: */
65 static HRESULT WINAPI IDirect3DDevice8Impl_QueryInterface(LPDIRECT3DDEVICE8 iface,REFIID riid,LPVOID *ppobj)
66 {
67     IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
68
69     if (IsEqualGUID(riid, &IID_IUnknown)
70         || IsEqualGUID(riid, &IID_IDirect3DDevice8)) {
71         IUnknown_AddRef(iface);
72         *ppobj = This;
73         return S_OK;
74     }
75
76     WARN("(%p)->(%s,%p),not found\n", This, debugstr_guid(riid), ppobj);
77     *ppobj = NULL;
78     return E_NOINTERFACE;
79 }
80
81 static ULONG WINAPI IDirect3DDevice8Impl_AddRef(LPDIRECT3DDEVICE8 iface) {
82     IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
83     ULONG ref = InterlockedIncrement(&This->ref);
84
85     TRACE("(%p) : AddRef from %d\n", This, ref - 1);
86
87     return ref;
88 }
89
90 static ULONG WINAPI IDirect3DDevice8Impl_Release(LPDIRECT3DDEVICE8 iface) {
91     IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
92     ULONG ref;
93
94     if (This->inDestruction) return 0;
95     ref = InterlockedDecrement(&This->ref);
96
97     TRACE("(%p) : ReleaseRef to %d\n", This, ref);
98
99     if (ref == 0) {
100         unsigned i;
101
102         TRACE("Releasing wined3d device %p\n", This->WineD3DDevice);
103         EnterCriticalSection(&d3d8_cs);
104         This->inDestruction = TRUE;
105
106         for(i = 0; i < This->numConvertedDecls; i++) {
107             IWineD3DVertexDeclaration_Release(This->decls[i].decl);
108         }
109         HeapFree(GetProcessHeap(), 0, This->decls);
110
111         IWineD3DDevice_Uninit3D(This->WineD3DDevice, D3D8CB_DestroyDepthStencilSurface, D3D8CB_DestroySwapChain);
112         IWineD3DDevice_Release(This->WineD3DDevice);
113         HeapFree(GetProcessHeap(), 0, This->shader_handles);
114         HeapFree(GetProcessHeap(), 0, This);
115         LeaveCriticalSection(&d3d8_cs);
116     }
117     return ref;
118 }
119
120 /* IDirect3DDevice Interface follow: */
121 static HRESULT WINAPI IDirect3DDevice8Impl_TestCooperativeLevel(LPDIRECT3DDEVICE8 iface) {
122     IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
123     HRESULT hr;
124
125     TRACE("(%p) : Relay\n", This);
126     EnterCriticalSection(&d3d8_cs);
127     hr = IWineD3DDevice_TestCooperativeLevel(This->WineD3DDevice);
128     LeaveCriticalSection(&d3d8_cs);
129     return hr;
130 }
131
132 static UINT WINAPI  IDirect3DDevice8Impl_GetAvailableTextureMem(LPDIRECT3DDEVICE8 iface) {
133     IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
134     HRESULT hr;
135
136     TRACE("(%p) Relay\n", This);
137     EnterCriticalSection(&d3d8_cs);
138     hr = IWineD3DDevice_GetAvailableTextureMem(This->WineD3DDevice);
139     LeaveCriticalSection(&d3d8_cs);
140     return hr;
141 }
142
143 static HRESULT WINAPI IDirect3DDevice8Impl_ResourceManagerDiscardBytes(LPDIRECT3DDEVICE8 iface, DWORD Bytes) {
144     IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
145     HRESULT hr;
146
147     TRACE("(%p) : Relay bytes(%d)\n", This, Bytes);
148     EnterCriticalSection(&d3d8_cs);
149     hr = IWineD3DDevice_EvictManagedResources(This->WineD3DDevice);
150     LeaveCriticalSection(&d3d8_cs);
151     return hr;
152 }
153
154 static HRESULT WINAPI IDirect3DDevice8Impl_GetDirect3D(LPDIRECT3DDEVICE8 iface, IDirect3D8** ppD3D8) {
155     IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
156     HRESULT hr = D3D_OK;
157     IWineD3D* pWineD3D;
158
159     TRACE("(%p) Relay\n", This);
160
161     if (NULL == ppD3D8) {
162         return D3DERR_INVALIDCALL;
163     }
164
165     EnterCriticalSection(&d3d8_cs);
166     hr = IWineD3DDevice_GetDirect3D(This->WineD3DDevice, &pWineD3D);
167     if (hr == D3D_OK && pWineD3D != NULL)
168     {
169         IWineD3D_GetParent(pWineD3D,(IUnknown **)ppD3D8);
170         IWineD3D_Release(pWineD3D);
171     } else {
172         FIXME("Call to IWineD3DDevice_GetDirect3D failed\n");
173         *ppD3D8 = NULL;
174     }
175     TRACE("(%p) returning %p\n",This , *ppD3D8);
176     LeaveCriticalSection(&d3d8_cs);
177
178     return hr;
179 }
180
181 static HRESULT WINAPI IDirect3DDevice8Impl_GetDeviceCaps(LPDIRECT3DDEVICE8 iface, D3DCAPS8* pCaps) {
182     IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
183     HRESULT hrc = D3D_OK;
184     WINED3DCAPS *pWineCaps;
185
186     TRACE("(%p) : Relay pCaps %p\n", This, pCaps);
187     if(NULL == pCaps){
188         return D3DERR_INVALIDCALL;
189     }
190     pWineCaps = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(WINED3DCAPS));
191     if(pWineCaps == NULL){
192         return D3DERR_INVALIDCALL; /* well this is what MSDN says to return */
193     }
194
195     EnterCriticalSection(&d3d8_cs);
196     hrc = IWineD3DDevice_GetDeviceCaps(This->WineD3DDevice, pWineCaps);
197     LeaveCriticalSection(&d3d8_cs);
198     WINECAPSTOD3D8CAPS(pCaps, pWineCaps)
199     HeapFree(GetProcessHeap(), 0, pWineCaps);
200
201     /* D3D8 doesn't support SM 2.0 or higher, so clamp to 1.x */
202     if(pCaps->PixelShaderVersion > D3DPS_VERSION(1,4)){
203         pCaps->PixelShaderVersion = D3DPS_VERSION(1,4);
204     }
205     if(pCaps->VertexShaderVersion > D3DVS_VERSION(1,1)){
206         pCaps->VertexShaderVersion = D3DVS_VERSION(1,1);
207     }
208
209     TRACE("Returning %p %p\n", This, pCaps);
210     return hrc;
211 }
212
213 static HRESULT WINAPI IDirect3DDevice8Impl_GetDisplayMode(LPDIRECT3DDEVICE8 iface, D3DDISPLAYMODE* pMode) {
214     IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
215     HRESULT hr;
216     TRACE("(%p) Relay\n", This);
217
218     EnterCriticalSection(&d3d8_cs);
219     hr = IWineD3DDevice_GetDisplayMode(This->WineD3DDevice, 0, (WINED3DDISPLAYMODE *) pMode);
220     LeaveCriticalSection(&d3d8_cs);
221     return hr;
222 }
223
224 static HRESULT WINAPI IDirect3DDevice8Impl_GetCreationParameters(LPDIRECT3DDEVICE8 iface, D3DDEVICE_CREATION_PARAMETERS *pParameters) {
225     IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
226     HRESULT hr;
227     TRACE("(%p) Relay\n", This);
228
229     EnterCriticalSection(&d3d8_cs);
230     hr = IWineD3DDevice_GetCreationParameters(This->WineD3DDevice, (WINED3DDEVICE_CREATION_PARAMETERS *) pParameters);
231     LeaveCriticalSection(&d3d8_cs);
232     return hr;
233 }
234
235 static HRESULT WINAPI IDirect3DDevice8Impl_SetCursorProperties(LPDIRECT3DDEVICE8 iface, UINT XHotSpot, UINT YHotSpot, IDirect3DSurface8* pCursorBitmap) {
236     IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
237     IDirect3DSurface8Impl *pSurface = (IDirect3DSurface8Impl*)pCursorBitmap;
238     HRESULT hr;
239     TRACE("(%p) Relay\n", This);
240     if(!pCursorBitmap) {
241         WARN("No cursor bitmap, returning WINED3DERR_INVALIDCALL\n");
242         return WINED3DERR_INVALIDCALL;
243     }
244
245     EnterCriticalSection(&d3d8_cs);
246     hr = IWineD3DDevice_SetCursorProperties(This->WineD3DDevice,XHotSpot,YHotSpot,pSurface->wineD3DSurface);
247     LeaveCriticalSection(&d3d8_cs);
248     return hr;
249 }
250
251 static void WINAPI IDirect3DDevice8Impl_SetCursorPosition(LPDIRECT3DDEVICE8 iface, UINT XScreenSpace, UINT YScreenSpace, DWORD Flags) {
252     IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
253     TRACE("(%p) Relay\n", This);
254
255     EnterCriticalSection(&d3d8_cs);
256     IWineD3DDevice_SetCursorPosition(This->WineD3DDevice, XScreenSpace, YScreenSpace, Flags);
257     LeaveCriticalSection(&d3d8_cs);
258 }
259
260 static BOOL WINAPI IDirect3DDevice8Impl_ShowCursor(LPDIRECT3DDEVICE8 iface, BOOL bShow) {
261     IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
262     BOOL ret;
263     TRACE("(%p) Relay\n", This);
264
265     EnterCriticalSection(&d3d8_cs);
266     ret = IWineD3DDevice_ShowCursor(This->WineD3DDevice, bShow);
267     LeaveCriticalSection(&d3d8_cs);
268     return ret;
269 }
270
271 static HRESULT WINAPI IDirect3DDevice8Impl_CreateAdditionalSwapChain(LPDIRECT3DDEVICE8 iface, D3DPRESENT_PARAMETERS* pPresentationParameters, IDirect3DSwapChain8** pSwapChain) {
272     IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
273     IDirect3DSwapChain8Impl* object;
274     HRESULT hrc = D3D_OK;
275     WINED3DPRESENT_PARAMETERS localParameters;
276
277     TRACE("(%p) Relay\n", This);
278
279     /* Fix the back buffer count */
280     if(pPresentationParameters->BackBufferCount == 0) {
281         pPresentationParameters->BackBufferCount = 1;
282     }
283
284     object = HeapAlloc(GetProcessHeap(),  HEAP_ZERO_MEMORY, sizeof(*object));
285     if (NULL == object) {
286         FIXME("Allocation of memory failed\n");
287         *pSwapChain = NULL;
288         return D3DERR_OUTOFVIDEOMEMORY;
289     }
290     object->ref = 1;
291     object->lpVtbl = &Direct3DSwapChain8_Vtbl;
292
293     /* Allocate an associated WineD3DDevice object */
294     localParameters.BackBufferWidth                             = pPresentationParameters->BackBufferWidth;
295     localParameters.BackBufferHeight                            = pPresentationParameters->BackBufferHeight;
296     localParameters.BackBufferFormat                            = pPresentationParameters->BackBufferFormat;
297     localParameters.BackBufferCount                             = pPresentationParameters->BackBufferCount;
298     localParameters.MultiSampleType                             = pPresentationParameters->MultiSampleType;
299     localParameters.MultiSampleQuality                          = 0; /* d3d9 only */
300     localParameters.SwapEffect                                  = pPresentationParameters->SwapEffect;
301     localParameters.hDeviceWindow                               = pPresentationParameters->hDeviceWindow;
302     localParameters.Windowed                                    = pPresentationParameters->Windowed;
303     localParameters.EnableAutoDepthStencil                      = pPresentationParameters->EnableAutoDepthStencil;
304     localParameters.AutoDepthStencilFormat                      = pPresentationParameters->AutoDepthStencilFormat;
305     localParameters.Flags                                       = pPresentationParameters->Flags;
306     localParameters.FullScreen_RefreshRateInHz                  = pPresentationParameters->FullScreen_RefreshRateInHz;
307     localParameters.PresentationInterval                        = pPresentationParameters->FullScreen_PresentationInterval;
308     localParameters.AutoRestoreDisplayMode                      = TRUE;
309
310     EnterCriticalSection(&d3d8_cs);
311     hrc = IWineD3DDevice_CreateSwapChain(This->WineD3DDevice, &localParameters, &object->wineD3DSwapChain, (IUnknown*)object, D3D8CB_CreateRenderTarget, D3D8CB_CreateDepthStencilSurface, SURFACE_OPENGL);
312     LeaveCriticalSection(&d3d8_cs);
313
314     pPresentationParameters->BackBufferWidth                    = localParameters.BackBufferWidth;
315     pPresentationParameters->BackBufferHeight                   = localParameters.BackBufferHeight;
316     pPresentationParameters->BackBufferFormat                   = localParameters.BackBufferFormat;
317     pPresentationParameters->BackBufferCount                    = localParameters.BackBufferCount;
318     pPresentationParameters->MultiSampleType                    = localParameters.MultiSampleType;
319     pPresentationParameters->SwapEffect                         = localParameters.SwapEffect;
320     pPresentationParameters->hDeviceWindow                      = localParameters.hDeviceWindow;
321     pPresentationParameters->Windowed                           = localParameters.Windowed;
322     pPresentationParameters->EnableAutoDepthStencil             = localParameters.EnableAutoDepthStencil;
323     pPresentationParameters->AutoDepthStencilFormat             = localParameters.AutoDepthStencilFormat;
324     pPresentationParameters->Flags                              = localParameters.Flags;
325     pPresentationParameters->FullScreen_RefreshRateInHz         = localParameters.FullScreen_RefreshRateInHz;
326     pPresentationParameters->FullScreen_PresentationInterval    = localParameters.PresentationInterval;
327
328     if (hrc != D3D_OK) {
329         FIXME("(%p) call to IWineD3DDevice_CreateSwapChain failed\n", This);
330         HeapFree(GetProcessHeap(), 0 , object);
331         *pSwapChain = NULL;
332     }else{
333         IUnknown_AddRef(iface);
334         object->parentDevice = iface;
335         *pSwapChain = (IDirect3DSwapChain8 *)object;
336     }
337     TRACE("(%p) returning %p\n", This, *pSwapChain);
338     return hrc;
339 }
340
341 static HRESULT WINAPI IDirect3DDevice8Impl_Reset(LPDIRECT3DDEVICE8 iface, D3DPRESENT_PARAMETERS* pPresentationParameters) {
342     IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
343     WINED3DPRESENT_PARAMETERS localParameters;
344     HRESULT hr;
345
346     TRACE("(%p) Relay pPresentationParameters(%p)\n", This, pPresentationParameters);
347
348     localParameters.BackBufferWidth                             = pPresentationParameters->BackBufferWidth;
349     localParameters.BackBufferHeight                            = pPresentationParameters->BackBufferHeight;
350     localParameters.BackBufferFormat                            = pPresentationParameters->BackBufferFormat;
351     localParameters.BackBufferCount                             = pPresentationParameters->BackBufferCount;
352     localParameters.MultiSampleType                             = pPresentationParameters->MultiSampleType;
353     localParameters.MultiSampleQuality                          = 0; /* d3d9 only */
354     localParameters.SwapEffect                                  = pPresentationParameters->SwapEffect;
355     localParameters.hDeviceWindow                               = pPresentationParameters->hDeviceWindow;
356     localParameters.Windowed                                    = pPresentationParameters->Windowed;
357     localParameters.EnableAutoDepthStencil                      = pPresentationParameters->EnableAutoDepthStencil;
358     localParameters.AutoDepthStencilFormat                      = pPresentationParameters->AutoDepthStencilFormat;
359     localParameters.Flags                                       = pPresentationParameters->Flags;
360     localParameters.FullScreen_RefreshRateInHz                  = pPresentationParameters->FullScreen_RefreshRateInHz;
361     localParameters.PresentationInterval                        = pPresentationParameters->FullScreen_PresentationInterval;
362     localParameters.AutoRestoreDisplayMode                      = TRUE;
363
364     EnterCriticalSection(&d3d8_cs);
365     hr = IWineD3DDevice_Reset(This->WineD3DDevice, &localParameters);
366     LeaveCriticalSection(&d3d8_cs);
367
368     pPresentationParameters->BackBufferWidth                    = localParameters.BackBufferWidth;
369     pPresentationParameters->BackBufferHeight                   = localParameters.BackBufferHeight;
370     pPresentationParameters->BackBufferFormat                   = localParameters.BackBufferFormat;
371     pPresentationParameters->BackBufferCount                    = localParameters.BackBufferCount;
372     pPresentationParameters->MultiSampleType                    = localParameters.MultiSampleType;
373     pPresentationParameters->SwapEffect                         = localParameters.SwapEffect;
374     pPresentationParameters->hDeviceWindow                      = localParameters.hDeviceWindow;
375     pPresentationParameters->Windowed                           = localParameters.Windowed;
376     pPresentationParameters->EnableAutoDepthStencil             = localParameters.EnableAutoDepthStencil;
377     pPresentationParameters->AutoDepthStencilFormat             = localParameters.AutoDepthStencilFormat;
378     pPresentationParameters->Flags                              = localParameters.Flags;
379     pPresentationParameters->FullScreen_RefreshRateInHz         = localParameters.FullScreen_RefreshRateInHz;
380     pPresentationParameters->FullScreen_PresentationInterval    = localParameters.PresentationInterval;
381
382     return hr;
383 }
384
385 static HRESULT WINAPI IDirect3DDevice8Impl_Present(LPDIRECT3DDEVICE8 iface, CONST RECT* pSourceRect,CONST RECT* pDestRect,HWND hDestWindowOverride,CONST RGNDATA* pDirtyRegion) {
386     IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
387     HRESULT hr;
388     TRACE("(%p) Relay\n", This);
389
390     EnterCriticalSection(&d3d8_cs);
391     hr = IWineD3DDevice_Present(This->WineD3DDevice, pSourceRect, pDestRect, hDestWindowOverride, pDirtyRegion);
392     LeaveCriticalSection(&d3d8_cs);
393     return hr;
394 }
395
396 static HRESULT WINAPI IDirect3DDevice8Impl_GetBackBuffer(LPDIRECT3DDEVICE8 iface, UINT BackBuffer, D3DBACKBUFFER_TYPE Type, IDirect3DSurface8** ppBackBuffer) {
397     IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
398     IWineD3DSurface *retSurface = NULL;
399     HRESULT rc = D3D_OK;
400
401     TRACE("(%p) Relay\n", This);
402
403     EnterCriticalSection(&d3d8_cs);
404     rc = IWineD3DDevice_GetBackBuffer(This->WineD3DDevice, 0, BackBuffer, (WINED3DBACKBUFFER_TYPE) Type, &retSurface);
405     if (rc == D3D_OK && NULL != retSurface && NULL != ppBackBuffer) {
406         IWineD3DSurface_GetParent(retSurface, (IUnknown **)ppBackBuffer);
407         IWineD3DSurface_Release(retSurface);
408     }
409     LeaveCriticalSection(&d3d8_cs);
410     return rc;
411 }
412
413 static HRESULT WINAPI IDirect3DDevice8Impl_GetRasterStatus(LPDIRECT3DDEVICE8 iface, D3DRASTER_STATUS* pRasterStatus) {
414     IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
415     HRESULT hr;
416     TRACE("(%p) Relay\n", This);
417
418     EnterCriticalSection(&d3d8_cs);
419     hr = IWineD3DDevice_GetRasterStatus(This->WineD3DDevice, 0, (WINED3DRASTER_STATUS *) pRasterStatus);
420     LeaveCriticalSection(&d3d8_cs);
421     return hr;
422 }
423
424 static void WINAPI IDirect3DDevice8Impl_SetGammaRamp(LPDIRECT3DDEVICE8 iface, DWORD Flags, CONST D3DGAMMARAMP* pRamp) {
425     IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
426     TRACE("(%p) Relay\n", This);
427
428     /* Note: D3DGAMMARAMP is compatible with WINED3DGAMMARAMP */
429     EnterCriticalSection(&d3d8_cs);
430     IWineD3DDevice_SetGammaRamp(This->WineD3DDevice, 0, Flags, (CONST WINED3DGAMMARAMP *) pRamp);
431     LeaveCriticalSection(&d3d8_cs);
432 }
433
434 static void WINAPI IDirect3DDevice8Impl_GetGammaRamp(LPDIRECT3DDEVICE8 iface, D3DGAMMARAMP* pRamp) {
435     IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
436     TRACE("(%p) Relay\n", This);
437
438     /* Note: D3DGAMMARAMP is compatible with WINED3DGAMMARAMP */
439     EnterCriticalSection(&d3d8_cs);
440     IWineD3DDevice_GetGammaRamp(This->WineD3DDevice, 0, (WINED3DGAMMARAMP *) pRamp);
441     LeaveCriticalSection(&d3d8_cs);
442 }
443
444 static HRESULT WINAPI IDirect3DDevice8Impl_CreateTexture(LPDIRECT3DDEVICE8 iface, UINT Width, UINT Height, UINT Levels, DWORD Usage,
445                                                     D3DFORMAT Format, D3DPOOL Pool, IDirect3DTexture8 **ppTexture) {
446     IDirect3DTexture8Impl *object;
447     IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
448     HRESULT hrc = D3D_OK;
449
450     TRACE("(%p) : W(%d) H(%d), Lvl(%d) d(%d), Fmt(%u), Pool(%d)\n", This, Width, Height, Levels, Usage, Format,  Pool);
451
452     /* Allocate the storage for the device */
453     object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DTexture8Impl));
454
455     if (NULL == object) {
456         FIXME("Allocation of memory failed\n");
457 /*        *ppTexture = NULL; */
458         return D3DERR_OUTOFVIDEOMEMORY;
459     }
460
461     object->lpVtbl = &Direct3DTexture8_Vtbl;
462     object->ref = 1;
463     EnterCriticalSection(&d3d8_cs);
464     hrc = IWineD3DDevice_CreateTexture(This->WineD3DDevice, Width, Height, Levels, Usage & WINED3DUSAGE_MASK,
465                                  (WINED3DFORMAT)Format, (WINED3DPOOL) Pool, &object->wineD3DTexture, NULL, (IUnknown *)object, D3D8CB_CreateSurface);
466     LeaveCriticalSection(&d3d8_cs);
467
468     if (FAILED(hrc)) {
469         /* free up object */ 
470         FIXME("(%p) call to IWineD3DDevice_CreateTexture failed\n", This);
471         HeapFree(GetProcessHeap(), 0, object);
472 /*      *ppTexture = NULL; */
473    } else {
474         IUnknown_AddRef(iface);
475         object->parentDevice = iface;
476         *ppTexture = (LPDIRECT3DTEXTURE8) object;
477         TRACE("(%p) Created Texture %p, %p\n",This,object,object->wineD3DTexture);
478    }
479
480    return hrc;
481 }
482
483 static HRESULT WINAPI IDirect3DDevice8Impl_CreateVolumeTexture(LPDIRECT3DDEVICE8 iface, 
484                                                           UINT Width, UINT Height, UINT Depth, UINT Levels, DWORD Usage, 
485                                                           D3DFORMAT Format, D3DPOOL Pool, IDirect3DVolumeTexture8** ppVolumeTexture) {
486
487     IDirect3DVolumeTexture8Impl *object;
488     IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
489     HRESULT hrc = D3D_OK;
490
491     TRACE("(%p) Relay\n", This);
492
493     /* Allocate the storage for the device */
494     object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DVolumeTexture8Impl));
495     if (NULL == object) {
496         FIXME("(%p) allocation of memory failed\n", This);
497         *ppVolumeTexture = NULL;
498         return D3DERR_OUTOFVIDEOMEMORY;
499     }
500
501     object->lpVtbl = &Direct3DVolumeTexture8_Vtbl;
502     object->ref = 1;
503     EnterCriticalSection(&d3d8_cs);
504     hrc = IWineD3DDevice_CreateVolumeTexture(This->WineD3DDevice, Width, Height, Depth, Levels, Usage & WINED3DUSAGE_MASK,
505                                  (WINED3DFORMAT)Format, (WINED3DPOOL) Pool, &object->wineD3DVolumeTexture, NULL,
506                                  (IUnknown *)object, D3D8CB_CreateVolume);
507     LeaveCriticalSection(&d3d8_cs);
508
509     if (hrc != D3D_OK) {
510
511         /* free up object */
512         FIXME("(%p) call to IWineD3DDevice_CreateVolumeTexture failed\n", This);
513         HeapFree(GetProcessHeap(), 0, object);
514         *ppVolumeTexture = NULL;
515     } else {
516         IUnknown_AddRef(iface);
517         object->parentDevice = iface;
518         *ppVolumeTexture = (LPDIRECT3DVOLUMETEXTURE8) object;
519     }
520     TRACE("(%p)  returning %p\n", This , *ppVolumeTexture);
521     return hrc;
522 }
523
524 static HRESULT WINAPI IDirect3DDevice8Impl_CreateCubeTexture(LPDIRECT3DDEVICE8 iface, UINT EdgeLength, UINT Levels, DWORD Usage, 
525                                                         D3DFORMAT Format, D3DPOOL Pool, IDirect3DCubeTexture8** ppCubeTexture) {
526
527     IDirect3DCubeTexture8Impl *object;
528     IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
529     HRESULT hr = D3D_OK;
530
531     TRACE("(%p) : ELen(%d) Lvl(%d) Usage(%d) fmt(%u), Pool(%d)\n" , This, EdgeLength, Levels, Usage, Format, Pool);
532
533     /* Allocate the storage for the device */
534     object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
535
536     if (NULL == object) {
537         FIXME("(%p) allocation of CubeTexture failed\n", This);
538         *ppCubeTexture = NULL;
539         return D3DERR_OUTOFVIDEOMEMORY;
540     }
541
542     object->lpVtbl = &Direct3DCubeTexture8_Vtbl;
543     object->ref = 1;
544     EnterCriticalSection(&d3d8_cs);
545     hr = IWineD3DDevice_CreateCubeTexture(This->WineD3DDevice, EdgeLength, Levels, Usage & WINED3DUSAGE_MASK,
546                                  (WINED3DFORMAT)Format, (WINED3DPOOL) Pool, &object->wineD3DCubeTexture, NULL, (IUnknown*)object,
547                                  D3D8CB_CreateSurface);
548     LeaveCriticalSection(&d3d8_cs);
549
550     if (hr != D3D_OK){
551
552         /* free up object */
553         FIXME("(%p) call to IWineD3DDevice_CreateCubeTexture failed\n", This);
554         HeapFree(GetProcessHeap(), 0, object);
555         *ppCubeTexture = NULL;
556     } else {
557         IUnknown_AddRef(iface);
558         object->parentDevice = iface;
559         *ppCubeTexture = (LPDIRECT3DCUBETEXTURE8) object;
560     }
561
562     TRACE("(%p) returning %p\n",This, *ppCubeTexture);
563     return hr;
564 }
565
566 static HRESULT WINAPI IDirect3DDevice8Impl_CreateVertexBuffer(LPDIRECT3DDEVICE8 iface, UINT Size, DWORD Usage, DWORD FVF, D3DPOOL Pool, IDirect3DVertexBuffer8** ppVertexBuffer) {
567     IDirect3DVertexBuffer8Impl *object;
568     IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
569     HRESULT hrc = D3D_OK;
570
571     TRACE("(%p) Relay\n", This);
572     /* Allocate the storage for the device */
573     object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DVertexBuffer8Impl));
574     if (NULL == object) {
575         FIXME("Allocation of memory failed\n");
576         *ppVertexBuffer = NULL;
577         return D3DERR_OUTOFVIDEOMEMORY;
578     }
579
580     object->lpVtbl = &Direct3DVertexBuffer8_Vtbl;
581     object->ref = 1;
582     EnterCriticalSection(&d3d8_cs);
583     hrc = IWineD3DDevice_CreateVertexBuffer(This->WineD3DDevice, Size, Usage & WINED3DUSAGE_MASK, FVF, (WINED3DPOOL) Pool, &(object->wineD3DVertexBuffer), NULL, (IUnknown *)object);
584     LeaveCriticalSection(&d3d8_cs);
585
586     if (D3D_OK != hrc) {
587
588         /* free up object */
589         FIXME("(%p) call to IWineD3DDevice_CreateVertexBuffer failed\n", This);
590         HeapFree(GetProcessHeap(), 0, object);
591         *ppVertexBuffer = NULL;
592     } else {
593         IUnknown_AddRef(iface);
594         object->parentDevice = iface;
595         *ppVertexBuffer = (LPDIRECT3DVERTEXBUFFER8) object;
596     }
597     return hrc;
598 }
599
600 static HRESULT WINAPI IDirect3DDevice8Impl_CreateIndexBuffer(LPDIRECT3DDEVICE8 iface, UINT Length, DWORD Usage, D3DFORMAT Format, D3DPOOL Pool, IDirect3DIndexBuffer8** ppIndexBuffer) {
601     IDirect3DIndexBuffer8Impl *object;
602     IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
603     HRESULT hrc = D3D_OK;
604
605     TRACE("(%p) Relay\n", This);
606     /* Allocate the storage for the device */
607     object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
608     if (NULL == object) {
609         FIXME("Allocation of memory failed\n");
610         *ppIndexBuffer = NULL;
611         return D3DERR_OUTOFVIDEOMEMORY;
612     }
613
614     object->lpVtbl = &Direct3DIndexBuffer8_Vtbl;
615     object->ref = 1;
616     TRACE("Calling wined3d create index buffer\n");
617     EnterCriticalSection(&d3d8_cs);
618     hrc = IWineD3DDevice_CreateIndexBuffer(This->WineD3DDevice, Length, Usage & WINED3DUSAGE_MASK, Format, (WINED3DPOOL) Pool, &object->wineD3DIndexBuffer, NULL, (IUnknown *)object);
619     LeaveCriticalSection(&d3d8_cs);
620
621     if (D3D_OK != hrc) {
622
623         /* free up object */
624         FIXME("(%p) call to IWineD3DDevice_CreateIndexBuffer failed\n", This);
625         HeapFree(GetProcessHeap(), 0, object);
626         *ppIndexBuffer = NULL;
627     } else {
628         IUnknown_AddRef(iface);
629         object->parentDevice = iface;
630         *ppIndexBuffer = (LPDIRECT3DINDEXBUFFER8)object;
631     }
632     return hrc;
633 }
634
635 static HRESULT WINAPI IDirect3DDevice8Impl_CreateSurface(LPDIRECT3DDEVICE8 iface, UINT Width, UINT Height, D3DFORMAT Format, BOOL Lockable, BOOL Discard, UINT Level, IDirect3DSurface8 **ppSurface,D3DRESOURCETYPE Type, UINT Usage,D3DPOOL Pool, D3DMULTISAMPLE_TYPE MultiSample, DWORD MultisampleQuality)  {
636     HRESULT hrc;
637     IDirect3DSurface8Impl *object;
638     IDirect3DDevice8Impl  *This = (IDirect3DDevice8Impl *)iface;
639     TRACE("(%p) Relay\n", This);
640
641     if(MultisampleQuality > 0){
642         FIXME("MultisampleQuality set to %d, substituting 0\n" , MultisampleQuality);
643         /*
644         MultisampleQuality
645         [in] Quality level. The valid range is between zero and one less than the level returned by pQualityLevels used by IDirect3D8::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.
646         */
647         MultisampleQuality=0;
648     }
649     /*FIXME: Check MAX bounds of MultisampleQuality*/
650
651     /* Allocate the storage for the device */
652     object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DSurface8Impl));
653     if (NULL == object) {
654         FIXME("Allocation of memory failed\n");
655         *ppSurface = NULL;
656         return D3DERR_OUTOFVIDEOMEMORY;
657     }
658
659     object->lpVtbl = &Direct3DSurface8_Vtbl;
660     object->ref = 1;
661
662     TRACE("(%p) : w(%d) h(%d) fmt(%d) surf@%p\n", This, Width, Height, Format, *ppSurface);
663
664     /* Not called from the VTable, no locking needed */
665     hrc = IWineD3DDevice_CreateSurface(This->WineD3DDevice, Width, Height, Format, Lockable, Discard, Level,  &object->wineD3DSurface, Type, Usage & WINED3DUSAGE_MASK, (WINED3DPOOL) Pool,MultiSample,MultisampleQuality, NULL, SURFACE_OPENGL, (IUnknown *)object);
666     if (hrc != D3D_OK || NULL == object->wineD3DSurface) {
667        /* free up object */
668         FIXME("(%p) call to IWineD3DDevice_CreateSurface failed\n", This);
669         HeapFree(GetProcessHeap(), 0, object);
670         *ppSurface = NULL;
671     } else {
672         IUnknown_AddRef(iface);
673         object->parentDevice = iface;
674         *ppSurface = (LPDIRECT3DSURFACE8) object;
675     }
676     return hrc;
677 }
678
679 static HRESULT WINAPI IDirect3DDevice8Impl_CreateRenderTarget(LPDIRECT3DDEVICE8 iface, UINT Width, UINT Height, D3DFORMAT Format, D3DMULTISAMPLE_TYPE MultiSample, BOOL Lockable, IDirect3DSurface8** ppSurface) {
680     HRESULT hr;
681     TRACE("Relay\n");
682
683     EnterCriticalSection(&d3d8_cs);
684     hr = IDirect3DDevice8Impl_CreateSurface(iface, Width, Height, Format, Lockable, FALSE /* Discard */, 0 /* Level */ , ppSurface, D3DRTYPE_SURFACE, D3DUSAGE_RENDERTARGET, D3DPOOL_DEFAULT, MultiSample, 0);
685     LeaveCriticalSection(&d3d8_cs);
686     return hr;
687 }
688
689 static HRESULT WINAPI IDirect3DDevice8Impl_CreateDepthStencilSurface(LPDIRECT3DDEVICE8 iface, UINT Width, UINT Height, D3DFORMAT Format, D3DMULTISAMPLE_TYPE MultiSample, IDirect3DSurface8** ppSurface) {
690     HRESULT hr;
691     TRACE("Relay\n");
692
693     /* TODO: Verify that Discard is false */
694     EnterCriticalSection(&d3d8_cs);
695     hr = IDirect3DDevice8Impl_CreateSurface(iface, Width, Height, Format, TRUE /* Lockable */, FALSE, 0 /* Level */
696                                                ,ppSurface, D3DRTYPE_SURFACE, D3DUSAGE_DEPTHSTENCIL,
697                                                 D3DPOOL_DEFAULT, MultiSample, 0);
698     LeaveCriticalSection(&d3d8_cs);
699     return hr;
700 }
701
702 /*  IDirect3DDevice8Impl::CreateImageSurface returns surface with pool type SYSTEMMEM */
703 static HRESULT WINAPI IDirect3DDevice8Impl_CreateImageSurface(LPDIRECT3DDEVICE8 iface, UINT Width, UINT Height, D3DFORMAT Format, IDirect3DSurface8** ppSurface) {
704     HRESULT hr;
705     TRACE("Relay\n");
706
707     EnterCriticalSection(&d3d8_cs);
708     hr = IDirect3DDevice8Impl_CreateSurface(iface, Width, Height, Format, TRUE /* Loackable */ , FALSE /*Discard*/ , 0 /* Level */ , ppSurface,
709                                             D3DRTYPE_SURFACE, 0 /* Usage (undefined/none) */ , D3DPOOL_SYSTEMMEM, D3DMULTISAMPLE_NONE, 0 /* MultisampleQuality */);
710     LeaveCriticalSection(&d3d8_cs);
711     return hr;
712 }
713
714 static HRESULT WINAPI IDirect3DDevice8Impl_CopyRects(LPDIRECT3DDEVICE8 iface, IDirect3DSurface8 *pSourceSurface, CONST RECT *pSourceRects, UINT cRects, IDirect3DSurface8 *pDestinationSurface, CONST POINT *pDestPoints) {
715     IDirect3DSurface8Impl *Source = (IDirect3DSurface8Impl *) pSourceSurface;
716     IDirect3DSurface8Impl *Dest = (IDirect3DSurface8Impl *) pDestinationSurface;
717
718     HRESULT              hr = WINED3D_OK;
719     WINED3DFORMAT        srcFormat, destFormat;
720     UINT                 srcWidth,  destWidth;
721     UINT                 srcHeight, destHeight;
722     UINT                 srcSize;
723     WINED3DSURFACE_DESC  winedesc;
724
725     TRACE("(%p) pSrcSur=%p, pSourceRects=%p, cRects=%d, pDstSur=%p, pDestPtsArr=%p\n", iface,
726           pSourceSurface, pSourceRects, cRects, pDestinationSurface, pDestPoints);
727
728
729     /* Check that the source texture is in WINED3DPOOL_SYSTEMMEM and the destination texture is in WINED3DPOOL_DEFAULT */
730     memset(&winedesc, 0, sizeof(winedesc));
731
732     winedesc.Format = &srcFormat;
733     winedesc.Width  = &srcWidth;
734     winedesc.Height = &srcHeight;
735     winedesc.Size   = &srcSize;
736     IWineD3DSurface_GetDesc(Source->wineD3DSurface, &winedesc);
737
738     winedesc.Format = &destFormat;
739     winedesc.Width  = &destWidth;
740     winedesc.Height = &destHeight;
741     winedesc.Size   = NULL;
742     EnterCriticalSection(&d3d8_cs);
743     IWineD3DSurface_GetDesc(Dest->wineD3DSurface, &winedesc);
744
745     /* Check that the source and destination formats match */
746     if (srcFormat != destFormat && WINED3DFMT_UNKNOWN != destFormat) {
747         WARN("(%p) source %p format must match the dest %p format, returning WINED3DERR_INVALIDCALL\n", iface, pSourceSurface, pDestinationSurface);
748         LeaveCriticalSection(&d3d8_cs);
749         return WINED3DERR_INVALIDCALL;
750     } else if (WINED3DFMT_UNKNOWN == destFormat) {
751         TRACE("(%p) : Converting destination surface from WINED3DFMT_UNKNOWN to the source format\n", iface);
752         IWineD3DSurface_SetFormat(Dest->wineD3DSurface, srcFormat);
753         destFormat = srcFormat;
754     }
755
756     /* Quick if complete copy ... */
757     if (cRects == 0 && pSourceRects == NULL && pDestPoints == NULL) {
758         IWineD3DSurface_BltFast(Dest->wineD3DSurface, 0, 0, Source->wineD3DSurface, NULL, WINEDDBLTFAST_NOCOLORKEY);
759     } else {
760         unsigned int i;
761         /* Copy rect by rect */
762         if (NULL != pSourceRects && NULL != pDestPoints) {
763             for (i = 0; i < cRects; ++i) {
764                 IWineD3DSurface_BltFast(Dest->wineD3DSurface, pDestPoints[i].x, pDestPoints[i].y, Source->wineD3DSurface, (RECT *) &pSourceRects[i], WINEDDBLTFAST_NOCOLORKEY);
765             }
766         } else {
767             for (i = 0; i < cRects; ++i) {
768                 IWineD3DSurface_BltFast(Dest->wineD3DSurface, 0, 0, Source->wineD3DSurface, (RECT *) &pSourceRects[i], WINEDDBLTFAST_NOCOLORKEY);
769             }
770         }
771     }
772     LeaveCriticalSection(&d3d8_cs);
773
774     return hr;
775 }
776
777 static HRESULT WINAPI IDirect3DDevice8Impl_UpdateTexture(LPDIRECT3DDEVICE8 iface, IDirect3DBaseTexture8* pSourceTexture, IDirect3DBaseTexture8* pDestinationTexture) {
778     IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
779     HRESULT hr;
780     TRACE("(%p) Relay\n" , This);
781
782     EnterCriticalSection(&d3d8_cs);
783     hr = IWineD3DDevice_UpdateTexture(This->WineD3DDevice,  ((IDirect3DBaseTexture8Impl *)pSourceTexture)->wineD3DBaseTexture, ((IDirect3DBaseTexture8Impl *)pDestinationTexture)->wineD3DBaseTexture);
784     LeaveCriticalSection(&d3d8_cs);
785     return hr;
786 }
787
788 static HRESULT WINAPI IDirect3DDevice8Impl_GetFrontBuffer(LPDIRECT3DDEVICE8 iface, IDirect3DSurface8* pDestSurface) {
789     IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
790     IDirect3DSurface8Impl *destSurface = (IDirect3DSurface8Impl *)pDestSurface;
791     HRESULT hr;
792
793     TRACE("(%p) Relay\n" , This);
794
795     if (pDestSurface == NULL) {
796         WARN("(%p) : Caller passed NULL as pDestSurface returning D3DERR_INVALIDCALL\n", This);
797         return D3DERR_INVALIDCALL;
798     }
799
800     EnterCriticalSection(&d3d8_cs);
801     hr = IWineD3DDevice_GetFrontBufferData(This->WineD3DDevice, 0, destSurface->wineD3DSurface);
802     LeaveCriticalSection(&d3d8_cs);
803     return hr;
804 }
805
806 static HRESULT WINAPI IDirect3DDevice8Impl_SetRenderTarget(LPDIRECT3DDEVICE8 iface, IDirect3DSurface8* pRenderTarget, IDirect3DSurface8* pNewZStencil) {
807     IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
808     IDirect3DSurface8Impl *pSurface = (IDirect3DSurface8Impl *)pRenderTarget;
809     IDirect3DSurface8Impl *pZSurface = (IDirect3DSurface8Impl *)pNewZStencil;
810     IWineD3DSurface *original_ds = NULL;
811     HRESULT hr;
812     TRACE("(%p) Relay\n" , This);
813
814     EnterCriticalSection(&d3d8_cs);
815
816     hr = IWineD3DDevice_GetDepthStencilSurface(This->WineD3DDevice, &original_ds);
817     if (hr == WINED3D_OK || hr == WINED3DERR_NOTFOUND)
818     {
819         hr = IWineD3DDevice_SetDepthStencilSurface(This->WineD3DDevice, pZSurface ? pZSurface->wineD3DSurface : NULL);
820         if (SUCCEEDED(hr) && pSurface)
821             hr = IWineD3DDevice_SetRenderTarget(This->WineD3DDevice, 0, pSurface->wineD3DSurface);
822         if (FAILED(hr)) IWineD3DDevice_SetDepthStencilSurface(This->WineD3DDevice, original_ds);
823     }
824     if (original_ds) IWineD3DSurface_Release(original_ds);
825
826     LeaveCriticalSection(&d3d8_cs);
827     return hr;
828 }
829
830 static HRESULT  WINAPI  IDirect3DDevice8Impl_GetRenderTarget(LPDIRECT3DDEVICE8 iface, IDirect3DSurface8** ppRenderTarget) {
831     IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
832     HRESULT hr = D3D_OK;
833     IWineD3DSurface *pRenderTarget;
834
835     TRACE("(%p) Relay\n" , This);
836
837     if (ppRenderTarget == NULL) {
838         return D3DERR_INVALIDCALL;
839     }
840     EnterCriticalSection(&d3d8_cs);
841     hr = IWineD3DDevice_GetRenderTarget(This->WineD3DDevice, 0, &pRenderTarget);
842
843     if (hr == D3D_OK && pRenderTarget != NULL) {
844         IWineD3DSurface_GetParent(pRenderTarget,(IUnknown**)ppRenderTarget);
845         IWineD3DSurface_Release(pRenderTarget);
846     } else {
847         FIXME("Call to IWineD3DDevice_GetRenderTarget failed\n");
848         *ppRenderTarget = NULL;
849     }
850     LeaveCriticalSection(&d3d8_cs);
851
852     return hr;
853 }
854
855 static HRESULT  WINAPI  IDirect3DDevice8Impl_GetDepthStencilSurface(LPDIRECT3DDEVICE8 iface, IDirect3DSurface8** ppZStencilSurface) {
856     IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
857     HRESULT hr = D3D_OK;
858     IWineD3DSurface *pZStencilSurface;
859
860     TRACE("(%p) Relay\n" , This);
861     if(ppZStencilSurface == NULL){
862         return D3DERR_INVALIDCALL;
863     }
864
865     EnterCriticalSection(&d3d8_cs);
866     hr=IWineD3DDevice_GetDepthStencilSurface(This->WineD3DDevice,&pZStencilSurface);
867     if (hr == WINED3D_OK) {
868         IWineD3DSurface_GetParent(pZStencilSurface,(IUnknown**)ppZStencilSurface);
869         IWineD3DSurface_Release(pZStencilSurface);
870     }else{
871         if (hr != WINED3DERR_NOTFOUND)
872                 FIXME("Call to IWineD3DDevice_GetDepthStencilSurface failed with 0x%08x\n", hr);
873         *ppZStencilSurface = NULL;
874     }
875     LeaveCriticalSection(&d3d8_cs);
876
877     return hr;
878 }
879
880 static HRESULT WINAPI IDirect3DDevice8Impl_BeginScene(LPDIRECT3DDEVICE8 iface) {
881     IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
882     HRESULT hr;
883     TRACE("(%p) Relay\n" , This);
884
885     EnterCriticalSection(&d3d8_cs);
886     hr = IWineD3DDevice_BeginScene(This->WineD3DDevice);
887     LeaveCriticalSection(&d3d8_cs);
888     return hr;
889 }
890
891 static HRESULT WINAPI IDirect3DDevice8Impl_EndScene(LPDIRECT3DDEVICE8 iface) {
892     IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
893     HRESULT hr;
894     TRACE("(%p) Relay\n" , This);
895
896     EnterCriticalSection(&d3d8_cs);
897     hr = IWineD3DDevice_EndScene(This->WineD3DDevice);
898     LeaveCriticalSection(&d3d8_cs);
899     return hr;
900 }
901
902 static HRESULT WINAPI IDirect3DDevice8Impl_Clear(LPDIRECT3DDEVICE8 iface, DWORD Count, CONST D3DRECT* pRects, DWORD Flags, D3DCOLOR Color, float Z, DWORD Stencil) {
903     IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
904     HRESULT hr;
905     TRACE("(%p) Relay\n" , This);
906
907     /* Note: D3DRECT is compatible with WINED3DRECT */
908     EnterCriticalSection(&d3d8_cs);
909     hr = IWineD3DDevice_Clear(This->WineD3DDevice, Count, (CONST WINED3DRECT*) pRects, Flags, Color, Z, Stencil);
910     LeaveCriticalSection(&d3d8_cs);
911     return hr;
912 }
913
914 static HRESULT WINAPI IDirect3DDevice8Impl_SetTransform(LPDIRECT3DDEVICE8 iface, D3DTRANSFORMSTATETYPE State, CONST D3DMATRIX* lpMatrix) {
915     IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
916     HRESULT hr;
917     TRACE("(%p) Relay\n" , This);
918
919     /* Note: D3DMATRIX is compatible with WINED3DMATRIX */
920     EnterCriticalSection(&d3d8_cs);
921     hr = IWineD3DDevice_SetTransform(This->WineD3DDevice, State, (CONST WINED3DMATRIX*) lpMatrix);
922     LeaveCriticalSection(&d3d8_cs);
923     return hr;
924 }
925
926 static HRESULT WINAPI IDirect3DDevice8Impl_GetTransform(LPDIRECT3DDEVICE8 iface, D3DTRANSFORMSTATETYPE State,D3DMATRIX* pMatrix) {
927     IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
928     HRESULT hr;
929     TRACE("(%p) Relay\n" , This);
930
931     /* Note: D3DMATRIX is compatible with WINED3DMATRIX */
932     EnterCriticalSection(&d3d8_cs);
933     hr = IWineD3DDevice_GetTransform(This->WineD3DDevice, State, (WINED3DMATRIX*) pMatrix);
934     LeaveCriticalSection(&d3d8_cs);
935     return hr;
936 }
937
938 static HRESULT WINAPI IDirect3DDevice8Impl_MultiplyTransform(LPDIRECT3DDEVICE8 iface, D3DTRANSFORMSTATETYPE State, CONST D3DMATRIX* pMatrix) {
939     IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
940     HRESULT hr;
941     TRACE("(%p) Relay\n" , This);
942
943     /* Note: D3DMATRIX is compatible with WINED3DMATRIX */
944     EnterCriticalSection(&d3d8_cs);
945     hr = IWineD3DDevice_MultiplyTransform(This->WineD3DDevice, State, (CONST WINED3DMATRIX*) pMatrix);
946     LeaveCriticalSection(&d3d8_cs);
947     return hr;
948 }
949
950 static HRESULT WINAPI IDirect3DDevice8Impl_SetViewport(LPDIRECT3DDEVICE8 iface, CONST D3DVIEWPORT8* pViewport) {
951     IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
952     HRESULT hr;
953     TRACE("(%p) Relay\n" , This);
954
955     /* Note: D3DVIEWPORT8 is compatible with WINED3DVIEWPORT */
956     EnterCriticalSection(&d3d8_cs);
957     hr = IWineD3DDevice_SetViewport(This->WineD3DDevice, (const WINED3DVIEWPORT *)pViewport);
958     LeaveCriticalSection(&d3d8_cs);
959     return hr;
960 }
961
962 static HRESULT WINAPI IDirect3DDevice8Impl_GetViewport(LPDIRECT3DDEVICE8 iface, D3DVIEWPORT8* pViewport) {
963     IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
964     HRESULT hr;
965     TRACE("(%p) Relay\n" , This);
966
967     /* Note: D3DVIEWPORT8 is compatible with WINED3DVIEWPORT */
968     EnterCriticalSection(&d3d8_cs);
969     hr = IWineD3DDevice_GetViewport(This->WineD3DDevice, (WINED3DVIEWPORT *)pViewport);
970     LeaveCriticalSection(&d3d8_cs);
971     return hr;
972 }
973
974 static HRESULT WINAPI IDirect3DDevice8Impl_SetMaterial(LPDIRECT3DDEVICE8 iface, CONST D3DMATERIAL8* pMaterial) {
975     IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
976     HRESULT hr;
977     TRACE("(%p) Relay\n" , This);
978
979     /* Note: D3DMATERIAL8 is compatible with WINED3DMATERIAL */
980     EnterCriticalSection(&d3d8_cs);
981     hr = IWineD3DDevice_SetMaterial(This->WineD3DDevice, (const WINED3DMATERIAL *)pMaterial);
982     LeaveCriticalSection(&d3d8_cs);
983     return hr;
984 }
985
986 static HRESULT WINAPI IDirect3DDevice8Impl_GetMaterial(LPDIRECT3DDEVICE8 iface, D3DMATERIAL8* pMaterial) {
987     IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
988     HRESULT hr;
989     TRACE("(%p) Relay\n" , This);
990
991     /* Note: D3DMATERIAL8 is compatible with WINED3DMATERIAL */
992     EnterCriticalSection(&d3d8_cs);
993     hr = IWineD3DDevice_GetMaterial(This->WineD3DDevice, (WINED3DMATERIAL *)pMaterial);
994     LeaveCriticalSection(&d3d8_cs);
995     return hr;
996 }
997
998 static HRESULT WINAPI IDirect3DDevice8Impl_SetLight(LPDIRECT3DDEVICE8 iface, DWORD Index, CONST D3DLIGHT8* pLight) {
999     IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
1000     HRESULT hr;
1001     TRACE("(%p) Relay\n" , This);
1002  
1003     /* Note: D3DLIGHT8 is compatible with WINED3DLIGHT */
1004     EnterCriticalSection(&d3d8_cs);
1005     hr = IWineD3DDevice_SetLight(This->WineD3DDevice, Index, (const WINED3DLIGHT *)pLight);
1006     LeaveCriticalSection(&d3d8_cs);
1007     return hr;
1008 }
1009
1010 static HRESULT WINAPI IDirect3DDevice8Impl_GetLight(LPDIRECT3DDEVICE8 iface, DWORD Index,D3DLIGHT8* pLight) {
1011     IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
1012     HRESULT hr;
1013     TRACE("(%p) Relay\n" , This);
1014
1015     /* Note: D3DLIGHT8 is compatible with WINED3DLIGHT */
1016     EnterCriticalSection(&d3d8_cs);
1017     hr = IWineD3DDevice_GetLight(This->WineD3DDevice, Index, (WINED3DLIGHT *)pLight);
1018     LeaveCriticalSection(&d3d8_cs);
1019     return hr;
1020 }
1021
1022 static HRESULT WINAPI IDirect3DDevice8Impl_LightEnable(LPDIRECT3DDEVICE8 iface, DWORD Index,BOOL Enable) {
1023     IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
1024     HRESULT hr;
1025     TRACE("(%p) Relay\n" , This);
1026
1027     EnterCriticalSection(&d3d8_cs);
1028     hr = IWineD3DDevice_SetLightEnable(This->WineD3DDevice, Index, Enable);
1029     LeaveCriticalSection(&d3d8_cs);
1030     return hr;
1031 }
1032
1033 static HRESULT WINAPI IDirect3DDevice8Impl_GetLightEnable(LPDIRECT3DDEVICE8 iface, DWORD Index,BOOL* pEnable) {
1034     IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
1035     HRESULT hr;
1036     TRACE("(%p) Relay\n" , This);
1037
1038     EnterCriticalSection(&d3d8_cs);
1039     hr = IWineD3DDevice_GetLightEnable(This->WineD3DDevice, Index, pEnable);
1040     LeaveCriticalSection(&d3d8_cs);
1041     return hr;
1042 }
1043
1044 static HRESULT WINAPI IDirect3DDevice8Impl_SetClipPlane(LPDIRECT3DDEVICE8 iface, DWORD Index,CONST float* pPlane) {
1045     IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
1046     HRESULT hr;
1047     TRACE("(%p) Relay\n" , This);
1048
1049     EnterCriticalSection(&d3d8_cs);
1050     hr = IWineD3DDevice_SetClipPlane(This->WineD3DDevice, Index, pPlane);
1051     LeaveCriticalSection(&d3d8_cs);
1052     return hr;
1053 }
1054
1055 static HRESULT WINAPI IDirect3DDevice8Impl_GetClipPlane(LPDIRECT3DDEVICE8 iface, DWORD Index,float* pPlane) {
1056     IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
1057     HRESULT hr;
1058     TRACE("(%p) Relay\n" , This);
1059
1060     EnterCriticalSection(&d3d8_cs);
1061     hr = IWineD3DDevice_GetClipPlane(This->WineD3DDevice, Index, pPlane);
1062     LeaveCriticalSection(&d3d8_cs);
1063     return hr;
1064 }
1065
1066 static HRESULT WINAPI IDirect3DDevice8Impl_SetRenderState(LPDIRECT3DDEVICE8 iface, D3DRENDERSTATETYPE State,DWORD Value) {
1067     IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
1068     HRESULT hr;
1069     TRACE("(%p) Relay\n" , This);
1070
1071     EnterCriticalSection(&d3d8_cs);
1072     hr = IWineD3DDevice_SetRenderState(This->WineD3DDevice, State, Value);
1073     LeaveCriticalSection(&d3d8_cs);
1074     return hr;
1075 }
1076
1077 static HRESULT WINAPI IDirect3DDevice8Impl_GetRenderState(LPDIRECT3DDEVICE8 iface, D3DRENDERSTATETYPE State,DWORD* pValue) {
1078     IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
1079     HRESULT hr;
1080     TRACE("(%p) Relay\n" , This);
1081
1082     EnterCriticalSection(&d3d8_cs);
1083     hr = IWineD3DDevice_GetRenderState(This->WineD3DDevice, State, pValue);
1084     LeaveCriticalSection(&d3d8_cs);
1085     return hr;
1086 }
1087
1088 static HRESULT WINAPI IDirect3DDevice8Impl_BeginStateBlock(LPDIRECT3DDEVICE8 iface) {
1089     IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
1090     HRESULT hr;
1091     TRACE("(%p)\n", This);
1092
1093     EnterCriticalSection(&d3d8_cs);
1094     hr = IWineD3DDevice_BeginStateBlock(This->WineD3DDevice);
1095     LeaveCriticalSection(&d3d8_cs);
1096     return hr;
1097 }
1098
1099 static HRESULT WINAPI IDirect3DDevice8Impl_EndStateBlock(LPDIRECT3DDEVICE8 iface, DWORD* pToken) {
1100     IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
1101     HRESULT hr;
1102     IWineD3DStateBlock* wineD3DStateBlock;
1103     IDirect3DStateBlock8Impl* object;
1104
1105     TRACE("(%p) Relay\n", This);
1106
1107     /* Tell wineD3D to endstateblock before anything else (in case we run out
1108      * of memory later and cause locking problems)
1109      */
1110     EnterCriticalSection(&d3d8_cs);
1111     hr = IWineD3DDevice_EndStateBlock(This->WineD3DDevice , &wineD3DStateBlock);
1112     if (hr != D3D_OK) {
1113         FIXME("IWineD3DDevice_EndStateBlock returned an error\n");
1114         LeaveCriticalSection(&d3d8_cs);
1115         return hr;
1116     }
1117
1118     /* allocate a new IDirectD3DStateBlock */
1119     object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY ,sizeof(IDirect3DStateBlock8Impl));
1120     object->ref = 1;
1121     object->lpVtbl = &Direct3DStateBlock8_Vtbl;
1122
1123     object->wineD3DStateBlock = wineD3DStateBlock;
1124
1125     *pToken = (DWORD)object;
1126     TRACE("(%p)Returning %p %p\n", This, object, wineD3DStateBlock);
1127
1128     LeaveCriticalSection(&d3d8_cs);
1129     return hr;
1130 }
1131
1132 static HRESULT WINAPI IDirect3DDevice8Impl_ApplyStateBlock(LPDIRECT3DDEVICE8 iface, DWORD Token) {
1133     IDirect3DStateBlock8Impl *pSB  = (IDirect3DStateBlock8Impl*) Token;
1134     IDirect3DDevice8Impl     *This = (IDirect3DDevice8Impl *)iface;
1135     HRESULT hr;
1136
1137     TRACE("(%p) %p Relay\n", This, pSB);
1138
1139     EnterCriticalSection(&d3d8_cs);
1140     hr = IWineD3DStateBlock_Apply(pSB->wineD3DStateBlock);
1141     LeaveCriticalSection(&d3d8_cs);
1142     return hr;
1143 }
1144
1145 static HRESULT WINAPI IDirect3DDevice8Impl_CaptureStateBlock(LPDIRECT3DDEVICE8 iface, DWORD Token) {
1146     IDirect3DStateBlock8Impl* pSB = (IDirect3DStateBlock8Impl *)Token;
1147     IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
1148     HRESULT hr;
1149
1150     TRACE("(%p) %p Relay\n", This, pSB);
1151
1152     EnterCriticalSection(&d3d8_cs);
1153     hr = IWineD3DStateBlock_Capture(pSB->wineD3DStateBlock);
1154     LeaveCriticalSection(&d3d8_cs);
1155     return hr;
1156 }
1157
1158 static HRESULT WINAPI IDirect3DDevice8Impl_DeleteStateBlock(LPDIRECT3DDEVICE8 iface, DWORD Token) {
1159     IDirect3DStateBlock8Impl* pSB = (IDirect3DStateBlock8Impl *)Token;
1160     IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
1161
1162     TRACE("(%p) Relay\n", This);
1163
1164     EnterCriticalSection(&d3d8_cs);
1165     while(IUnknown_Release((IUnknown *)pSB));
1166     LeaveCriticalSection(&d3d8_cs);
1167
1168     return D3D_OK;
1169 }
1170
1171 static HRESULT WINAPI IDirect3DDevice8Impl_CreateStateBlock(LPDIRECT3DDEVICE8 iface, D3DSTATEBLOCKTYPE Type, DWORD* pToken) {
1172    IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
1173    IDirect3DStateBlock8Impl *object;
1174    HRESULT hrc = D3D_OK;
1175
1176    TRACE("(%p) Relay\n", This);
1177
1178    if(Type != D3DSBT_ALL         && Type != D3DSBT_PIXELSTATE &&
1179       Type != D3DSBT_VERTEXSTATE                              ) {
1180        WARN("Unexpected stateblock type, returning D3DERR_INVALIDCALL\n");
1181        return D3DERR_INVALIDCALL;
1182    }
1183
1184    object  = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DStateBlock8Impl));
1185    if (NULL == object) {
1186       *pToken = 0;
1187       return E_OUTOFMEMORY;
1188    }
1189    object->lpVtbl = &Direct3DStateBlock8_Vtbl;
1190    object->ref = 1;
1191
1192    EnterCriticalSection(&d3d8_cs);
1193    hrc = IWineD3DDevice_CreateStateBlock(This->WineD3DDevice, (WINED3DSTATEBLOCKTYPE)Type, &object->wineD3DStateBlock, (IUnknown *)object);
1194    LeaveCriticalSection(&d3d8_cs);
1195    if(D3D_OK != hrc){
1196        FIXME("(%p) Call to IWineD3DDevice_CreateStateBlock failed.\n", This);
1197        HeapFree(GetProcessHeap(), 0, object);
1198        *pToken = 0;
1199    } else {
1200        *pToken = (DWORD)object;
1201        TRACE("(%p) returning token (ptr to stateblock) of %p\n", This, object);
1202    }
1203
1204    return hrc;
1205 }
1206
1207 static HRESULT WINAPI IDirect3DDevice8Impl_SetClipStatus(LPDIRECT3DDEVICE8 iface, CONST D3DCLIPSTATUS8* pClipStatus) {
1208     IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
1209     HRESULT hr;
1210     TRACE("(%p) Relay\n" , This);
1211 /* FIXME: Verify that D3DCLIPSTATUS8 ~= WINED3DCLIPSTATUS */
1212     EnterCriticalSection(&d3d8_cs);
1213     hr = IWineD3DDevice_SetClipStatus(This->WineD3DDevice, (const WINED3DCLIPSTATUS *)pClipStatus);
1214     LeaveCriticalSection(&d3d8_cs);
1215     return hr;
1216 }
1217
1218 static HRESULT WINAPI IDirect3DDevice8Impl_GetClipStatus(LPDIRECT3DDEVICE8 iface, D3DCLIPSTATUS8* pClipStatus) {
1219     IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
1220     HRESULT hr;
1221     TRACE("(%p) Relay\n" , This);
1222
1223     EnterCriticalSection(&d3d8_cs);
1224     hr = IWineD3DDevice_GetClipStatus(This->WineD3DDevice, (WINED3DCLIPSTATUS *)pClipStatus);
1225     LeaveCriticalSection(&d3d8_cs);
1226     return hr;
1227 }
1228
1229 static HRESULT WINAPI IDirect3DDevice8Impl_GetTexture(LPDIRECT3DDEVICE8 iface, DWORD Stage,IDirect3DBaseTexture8** ppTexture) {
1230     IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
1231     IWineD3DBaseTexture *retTexture = NULL;
1232     HRESULT rc = D3D_OK;
1233
1234     TRACE("(%p) Relay\n" , This);
1235
1236     if(ppTexture == NULL){
1237         return D3DERR_INVALIDCALL;
1238     }
1239
1240     EnterCriticalSection(&d3d8_cs);
1241     rc = IWineD3DDevice_GetTexture(This->WineD3DDevice, Stage, &retTexture);
1242     if (rc == D3D_OK && NULL != retTexture) {
1243         IWineD3DBaseTexture_GetParent(retTexture, (IUnknown **)ppTexture);
1244         IWineD3DBaseTexture_Release(retTexture);
1245     } else {
1246         FIXME("Call to get texture  (%d) failed (%p)\n", Stage, retTexture);
1247         *ppTexture = NULL;
1248     }
1249     LeaveCriticalSection(&d3d8_cs);
1250
1251     return rc;
1252 }
1253
1254 static HRESULT WINAPI IDirect3DDevice8Impl_SetTexture(LPDIRECT3DDEVICE8 iface, DWORD Stage, IDirect3DBaseTexture8* pTexture) {
1255     IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
1256     HRESULT hr;
1257     TRACE("(%p) Relay %d %p\n" , This, Stage, pTexture);
1258
1259     EnterCriticalSection(&d3d8_cs);
1260     hr = IWineD3DDevice_SetTexture(This->WineD3DDevice, Stage,
1261                                    pTexture==NULL ? NULL : ((IDirect3DBaseTexture8Impl *)pTexture)->wineD3DBaseTexture);
1262     LeaveCriticalSection(&d3d8_cs);
1263     return hr;
1264 }
1265
1266 static HRESULT  WINAPI  IDirect3DDevice8Impl_GetTextureStageState(LPDIRECT3DDEVICE8 iface, DWORD Stage,D3DTEXTURESTAGESTATETYPE Type,DWORD* pValue) {
1267     IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
1268     HRESULT hr;
1269     TRACE("(%p) Relay\n" , This);
1270
1271     switch(Type) {
1272     case D3DTSS_ADDRESSU:
1273         Type = WINED3DSAMP_ADDRESSU;
1274         break;
1275     case D3DTSS_ADDRESSV:
1276         Type = WINED3DSAMP_ADDRESSV;
1277         break;
1278     case D3DTSS_ADDRESSW:
1279         Type = WINED3DSAMP_ADDRESSW;
1280         break;
1281     case D3DTSS_BORDERCOLOR:
1282         Type = WINED3DSAMP_BORDERCOLOR;
1283         break;
1284     case D3DTSS_MAGFILTER:
1285         Type = WINED3DSAMP_MAGFILTER;
1286         break;
1287     case D3DTSS_MAXANISOTROPY:
1288         Type = WINED3DSAMP_MAXANISOTROPY;
1289         break;
1290     case D3DTSS_MAXMIPLEVEL:
1291         Type = WINED3DSAMP_MAXMIPLEVEL;
1292         break;
1293     case D3DTSS_MINFILTER:
1294         Type = WINED3DSAMP_MINFILTER;
1295         break;
1296     case D3DTSS_MIPFILTER:
1297         Type = WINED3DSAMP_MIPFILTER;
1298         break;
1299     case D3DTSS_MIPMAPLODBIAS:
1300         Type = WINED3DSAMP_MIPMAPLODBIAS;
1301         break;
1302     default:
1303         EnterCriticalSection(&d3d8_cs);
1304         hr = IWineD3DDevice_GetTextureStageState(This->WineD3DDevice, Stage, Type, pValue);
1305         LeaveCriticalSection(&d3d8_cs);
1306         return hr;
1307     }
1308
1309     EnterCriticalSection(&d3d8_cs);
1310     hr = IWineD3DDevice_GetSamplerState(This->WineD3DDevice, Stage, Type, pValue);
1311     LeaveCriticalSection(&d3d8_cs);
1312     return hr;
1313 }
1314
1315 static HRESULT WINAPI IDirect3DDevice8Impl_SetTextureStageState(LPDIRECT3DDEVICE8 iface, DWORD Stage, D3DTEXTURESTAGESTATETYPE Type, DWORD Value) {
1316     IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
1317     HRESULT hr;
1318     TRACE("(%p) Relay\n" , This);
1319
1320     switch(Type) {
1321     case D3DTSS_ADDRESSU:
1322         Type = WINED3DSAMP_ADDRESSU;
1323         break;
1324     case D3DTSS_ADDRESSV:
1325         Type = WINED3DSAMP_ADDRESSV;
1326         break;
1327     case D3DTSS_ADDRESSW:
1328         Type = WINED3DSAMP_ADDRESSW;
1329         break;
1330     case D3DTSS_BORDERCOLOR:
1331         Type = WINED3DSAMP_BORDERCOLOR;
1332         break;
1333     case D3DTSS_MAGFILTER:
1334         Type = WINED3DSAMP_MAGFILTER;
1335         break;
1336     case D3DTSS_MAXANISOTROPY:
1337         Type = WINED3DSAMP_MAXANISOTROPY;
1338         break;
1339     case D3DTSS_MAXMIPLEVEL:
1340         Type = WINED3DSAMP_MAXMIPLEVEL;
1341         break;
1342     case D3DTSS_MINFILTER:
1343         Type = WINED3DSAMP_MINFILTER;
1344         break;
1345     case D3DTSS_MIPFILTER:
1346         Type = WINED3DSAMP_MIPFILTER;
1347         break;
1348     case D3DTSS_MIPMAPLODBIAS:
1349         Type = WINED3DSAMP_MIPMAPLODBIAS;
1350         break;
1351     default:
1352         EnterCriticalSection(&d3d8_cs);
1353         hr = IWineD3DDevice_SetTextureStageState(This->WineD3DDevice, Stage, Type, Value);
1354         LeaveCriticalSection(&d3d8_cs);
1355         return hr;
1356     }
1357
1358     EnterCriticalSection(&d3d8_cs);
1359     hr = IWineD3DDevice_SetSamplerState(This->WineD3DDevice, Stage, Type, Value);
1360     LeaveCriticalSection(&d3d8_cs);
1361     return hr;
1362 }
1363
1364 static HRESULT WINAPI IDirect3DDevice8Impl_ValidateDevice(LPDIRECT3DDEVICE8 iface, DWORD* pNumPasses) {
1365     IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
1366     HRESULT hr;
1367     TRACE("(%p) Relay\n" , This);
1368
1369     EnterCriticalSection(&d3d8_cs);
1370     hr = IWineD3DDevice_ValidateDevice(This->WineD3DDevice, pNumPasses);
1371     LeaveCriticalSection(&d3d8_cs);
1372     return hr;
1373 }
1374
1375 static HRESULT WINAPI IDirect3DDevice8Impl_GetInfo(LPDIRECT3DDEVICE8 iface, DWORD DevInfoID, void* pDevInfoStruct, DWORD DevInfoStructSize) {
1376     IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
1377     FIXME("(%p) : stub\n", This);
1378     return D3D_OK;
1379 }
1380
1381 static HRESULT WINAPI IDirect3DDevice8Impl_SetPaletteEntries(LPDIRECT3DDEVICE8 iface, UINT PaletteNumber, CONST PALETTEENTRY* pEntries) {
1382     IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
1383     HRESULT hr;
1384     TRACE("(%p) Relay\n" , This);
1385
1386     EnterCriticalSection(&d3d8_cs);
1387     hr = IWineD3DDevice_SetPaletteEntries(This->WineD3DDevice, PaletteNumber, pEntries);
1388     LeaveCriticalSection(&d3d8_cs);
1389     return hr;
1390 }
1391
1392 static HRESULT WINAPI IDirect3DDevice8Impl_GetPaletteEntries(LPDIRECT3DDEVICE8 iface, UINT PaletteNumber, PALETTEENTRY* pEntries) {
1393     IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
1394     HRESULT hr;
1395     TRACE("(%p) Relay\n" , This);
1396
1397     EnterCriticalSection(&d3d8_cs);
1398     hr = IWineD3DDevice_GetPaletteEntries(This->WineD3DDevice, PaletteNumber, pEntries);
1399     LeaveCriticalSection(&d3d8_cs);
1400     return hr;
1401 }
1402
1403 static HRESULT WINAPI IDirect3DDevice8Impl_SetCurrentTexturePalette(LPDIRECT3DDEVICE8 iface, UINT PaletteNumber) {
1404     IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
1405     HRESULT hr;
1406     TRACE("(%p) Relay\n" , This);
1407
1408     EnterCriticalSection(&d3d8_cs);
1409     hr = IWineD3DDevice_SetCurrentTexturePalette(This->WineD3DDevice, PaletteNumber);
1410     LeaveCriticalSection(&d3d8_cs);
1411     return hr;
1412 }
1413
1414 static HRESULT  WINAPI  IDirect3DDevice8Impl_GetCurrentTexturePalette(LPDIRECT3DDEVICE8 iface, UINT *PaletteNumber) {
1415     IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
1416     HRESULT hr;
1417     TRACE("(%p) Relay\n" , This);
1418
1419     EnterCriticalSection(&d3d8_cs);
1420     hr = IWineD3DDevice_GetCurrentTexturePalette(This->WineD3DDevice, PaletteNumber);
1421     LeaveCriticalSection(&d3d8_cs);
1422     return hr;
1423 }
1424
1425 static HRESULT WINAPI IDirect3DDevice8Impl_DrawPrimitive(LPDIRECT3DDEVICE8 iface, D3DPRIMITIVETYPE PrimitiveType, UINT StartVertex, UINT PrimitiveCount) {
1426     IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; 
1427     HRESULT hr;
1428     TRACE("(%p) Relay\n" , This);
1429
1430     EnterCriticalSection(&d3d8_cs);
1431     hr = IWineD3DDevice_DrawPrimitive(This->WineD3DDevice, PrimitiveType, StartVertex, PrimitiveCount);
1432     LeaveCriticalSection(&d3d8_cs);
1433     return hr;
1434 }
1435
1436 static HRESULT WINAPI IDirect3DDevice8Impl_DrawIndexedPrimitive(LPDIRECT3DDEVICE8 iface, D3DPRIMITIVETYPE PrimitiveType,
1437                                                            UINT MinVertexIndex,UINT NumVertices,UINT startIndex,UINT primCount) {
1438     IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
1439     HRESULT hr;
1440     TRACE("(%p) Relay\n" , This);
1441
1442     EnterCriticalSection(&d3d8_cs);
1443     hr = IWineD3DDevice_DrawIndexedPrimitive(This->WineD3DDevice, PrimitiveType, MinVertexIndex, NumVertices, startIndex, primCount);
1444     LeaveCriticalSection(&d3d8_cs);
1445     return hr;
1446 }
1447
1448 static HRESULT WINAPI IDirect3DDevice8Impl_DrawPrimitiveUP(LPDIRECT3DDEVICE8 iface, D3DPRIMITIVETYPE PrimitiveType,UINT PrimitiveCount,CONST void* pVertexStreamZeroData,UINT VertexStreamZeroStride) {
1449     IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
1450     HRESULT hr;
1451     TRACE("(%p) Relay\n" , This);
1452
1453     EnterCriticalSection(&d3d8_cs);
1454     hr = IWineD3DDevice_DrawPrimitiveUP(This->WineD3DDevice, PrimitiveType, PrimitiveCount, pVertexStreamZeroData, VertexStreamZeroStride);
1455     LeaveCriticalSection(&d3d8_cs);
1456     return hr;
1457 }
1458
1459 static HRESULT WINAPI IDirect3DDevice8Impl_DrawIndexedPrimitiveUP(LPDIRECT3DDEVICE8 iface, D3DPRIMITIVETYPE PrimitiveType,UINT MinVertexIndex,
1460                                                              UINT NumVertexIndices,UINT PrimitiveCount,CONST void* pIndexData,
1461                                                              D3DFORMAT IndexDataFormat,CONST void* pVertexStreamZeroData,
1462                                                              UINT VertexStreamZeroStride) {
1463     IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
1464     HRESULT hr;
1465     TRACE("(%p) Relay\n" , This);
1466
1467     EnterCriticalSection(&d3d8_cs);
1468     hr = IWineD3DDevice_DrawIndexedPrimitiveUP(This->WineD3DDevice, PrimitiveType, MinVertexIndex, NumVertexIndices, PrimitiveCount,
1469                                                pIndexData, IndexDataFormat, pVertexStreamZeroData, VertexStreamZeroStride);
1470     LeaveCriticalSection(&d3d8_cs);
1471     return hr;
1472 }
1473
1474 static HRESULT WINAPI IDirect3DDevice8Impl_ProcessVertices(LPDIRECT3DDEVICE8 iface, UINT SrcStartIndex,UINT DestIndex,UINT VertexCount,IDirect3DVertexBuffer8* pDestBuffer,DWORD Flags) {
1475     IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
1476     HRESULT hr;
1477     TRACE("(%p) Relay\n" , This);
1478
1479     EnterCriticalSection(&d3d8_cs);
1480     hr = IWineD3DDevice_ProcessVertices(This->WineD3DDevice,SrcStartIndex, DestIndex, VertexCount, ((IDirect3DVertexBuffer8Impl *)pDestBuffer)->wineD3DVertexBuffer, NULL, Flags);
1481     LeaveCriticalSection(&d3d8_cs);
1482     return hr;
1483 }
1484
1485 static HRESULT WINAPI IDirect3DDevice8Impl_CreateVertexDeclaration(IDirect3DDevice8 *iface, CONST DWORD *declaration, IDirect3DVertexDeclaration8 **decl_ptr) {
1486     IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
1487     IDirect3DVertexDeclaration8Impl *object;
1488     WINED3DVERTEXELEMENT *wined3d_elements;
1489     UINT wined3d_element_count;
1490     HRESULT hr = D3D_OK;
1491
1492     TRACE("(%p) : declaration %p\n", This, declaration);
1493
1494     object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
1495     if (!object) {
1496         ERR("Memory allocation failed\n");
1497         *decl_ptr = NULL;
1498         return D3DERR_OUTOFVIDEOMEMORY;
1499     }
1500
1501     object->ref_count = 1;
1502     object->lpVtbl = &Direct3DVertexDeclaration8_Vtbl;
1503
1504     wined3d_element_count = convert_to_wined3d_declaration(declaration, &object->elements_size, &wined3d_elements);
1505     object->elements = HeapAlloc(GetProcessHeap(), 0, object->elements_size);
1506     if (!object->elements) {
1507         ERR("Memory allocation failed\n");
1508         HeapFree(GetProcessHeap(), 0, wined3d_elements);
1509         HeapFree(GetProcessHeap(), 0, object);
1510         *decl_ptr = NULL;
1511         return D3DERR_OUTOFVIDEOMEMORY;
1512     }
1513
1514     CopyMemory(object->elements, declaration, object->elements_size);
1515
1516     EnterCriticalSection(&d3d8_cs);
1517     hr = IWineD3DDevice_CreateVertexDeclaration(This->WineD3DDevice, &object->wined3d_vertex_declaration,
1518             (IUnknown *)object, wined3d_elements, wined3d_element_count);
1519     LeaveCriticalSection(&d3d8_cs);
1520     HeapFree(GetProcessHeap(), 0, wined3d_elements);
1521
1522     if (FAILED(hr)) {
1523         ERR("(%p) : IWineD3DDevice_CreateVertexDeclaration call failed\n", This);
1524         HeapFree(GetProcessHeap(), 0, object->elements);
1525         HeapFree(GetProcessHeap(), 0, object);
1526     } else {
1527         *decl_ptr = (IDirect3DVertexDeclaration8 *)object;
1528         TRACE("(%p) : Created vertex declaration %p\n", This, object);
1529     }
1530
1531     return hr;
1532 }
1533
1534 static HRESULT WINAPI IDirect3DDevice8Impl_CreateVertexShader(LPDIRECT3DDEVICE8 iface, CONST DWORD* pDeclaration, CONST DWORD* pFunction, DWORD* ppShader, DWORD Usage) {
1535     IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
1536     HRESULT hrc = D3D_OK;
1537     IDirect3DVertexShader8Impl *object;
1538     IWineD3DVertexDeclaration *wined3d_vertex_declaration;
1539     const DWORD *token = pDeclaration;
1540
1541     /* Test if the vertex declaration is valid */
1542     while (D3DVSD_END() != *token) {
1543         D3DVSD_TOKENTYPE token_type = ((*token & D3DVSD_TOKENTYPEMASK) >> D3DVSD_TOKENTYPESHIFT);
1544
1545         if (token_type == D3DVSD_TOKEN_STREAMDATA && !(token_type & 0x10000000)) {
1546             DWORD type = ((*token & D3DVSD_DATATYPEMASK) >> D3DVSD_DATATYPESHIFT);
1547             DWORD reg  = ((*token & D3DVSD_VERTEXREGMASK) >> D3DVSD_VERTEXREGSHIFT);
1548
1549             if(reg == D3DVSDE_NORMAL && type != D3DVSDT_FLOAT3 && !pFunction) {
1550                 WARN("Attempt to use a non-FLOAT3 normal with the fixed function function\n");
1551                 return D3DERR_INVALIDCALL;
1552             }
1553         }
1554         token += parse_token(token);
1555     }
1556
1557     /* Setup a stub object for now */
1558     object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
1559     TRACE("(%p) : pFunction(%p), ppShader(%p)\n", This, pFunction, ppShader);
1560     if (NULL == object) {
1561         FIXME("Allocation of memory failed\n");
1562         *ppShader = 0;
1563         return D3DERR_OUTOFVIDEOMEMORY;
1564     }
1565
1566     object->ref = 1;
1567     object->lpVtbl = &Direct3DVertexShader8_Vtbl;
1568
1569     EnterCriticalSection(&d3d8_cs);
1570     hrc = IDirect3DDevice8Impl_CreateVertexDeclaration(iface, pDeclaration, &object->vertex_declaration);
1571     if (FAILED(hrc)) {
1572         ERR("(%p) : IDirect3DDeviceImpl_CreateVertexDeclaration call failed\n", This);
1573         LeaveCriticalSection(&d3d8_cs);
1574         HeapFree(GetProcessHeap(), 0, object);
1575         *ppShader = 0;
1576         return D3DERR_INVALIDCALL;
1577     }
1578     wined3d_vertex_declaration = ((IDirect3DVertexDeclaration8Impl *)object->vertex_declaration)->wined3d_vertex_declaration;
1579
1580     /* Usage is missing ... Use SetRenderState to set the sw vp render state in SetVertexShader */
1581     hrc = IWineD3DDevice_CreateVertexShader(This->WineD3DDevice, wined3d_vertex_declaration, pFunction, &object->wineD3DVertexShader, (IUnknown *)object);
1582
1583     if (FAILED(hrc)) {
1584         /* free up object */
1585         FIXME("Call to IWineD3DDevice_CreateVertexShader failed\n");
1586         HeapFree(GetProcessHeap(), 0, object);
1587         *ppShader = 0;
1588     } else {
1589         /* TODO: Store the VS declarations locally so that they can be dereferenced with a value higher than VS_HIGHESTFIXEDFXF */
1590         shader_handle *handle = alloc_shader_handle(This);
1591         if (!handle) {
1592             ERR("Failed to allocate shader handle\n");
1593             IDirect3DVertexShader8_Release((IUnknown *)object);
1594             hrc = E_OUTOFMEMORY;
1595         } else {
1596             *handle = object;
1597             object->handle = (handle - This->shader_handles) + VS_HIGHESTFIXEDFXF + 1;
1598             *ppShader = object->handle;
1599
1600             load_local_constants(pDeclaration, object->wineD3DVertexShader);
1601             TRACE("(%p) : returning %p (handle %#x)\n", This, object, *ppShader);
1602         }
1603     }
1604     LeaveCriticalSection(&d3d8_cs);
1605
1606     return hrc;
1607 }
1608
1609 IWineD3DVertexDeclaration *IDirect3DDevice8Impl_FindDecl(IDirect3DDevice8Impl *This, DWORD fvf)
1610 {
1611     HRESULT hr;
1612     IWineD3DVertexDeclaration* pDecl = NULL;
1613     int p, low, high; /* deliberately signed */
1614     struct FvfToDecl *convertedDecls = This->decls;
1615
1616     TRACE("Searching for declaration for fvf %08x... ", fvf);
1617
1618     low = 0;
1619     high = This->numConvertedDecls - 1;
1620     while(low <= high) {
1621         p = (low + high) >> 1;
1622         TRACE("%d ", p);
1623         if(convertedDecls[p].fvf == fvf) {
1624             TRACE("found %p\n", convertedDecls[p].decl);
1625             return convertedDecls[p].decl;
1626         } else if(convertedDecls[p].fvf < fvf) {
1627             low = p + 1;
1628         } else {
1629             high = p - 1;
1630         }
1631     }
1632     TRACE("not found. Creating and inserting at position %d.\n", low);
1633
1634     hr = IWineD3DDevice_CreateVertexDeclarationFromFVF(This->WineD3DDevice,
1635                                                        &pDecl,
1636                                                        (IUnknown *) This,
1637                                                        fvf);
1638     if (FAILED(hr)) return NULL;
1639
1640     if(This->declArraySize == This->numConvertedDecls) {
1641         int grow = This->declArraySize / 2;
1642         convertedDecls = HeapReAlloc(GetProcessHeap(), 0, convertedDecls,
1643                                      sizeof(convertedDecls[0]) * (This->numConvertedDecls + grow));
1644         if(!convertedDecls) {
1645             /* This will destroy it */
1646             IWineD3DVertexDeclaration_Release(pDecl);
1647             return NULL;
1648         }
1649         This->decls = convertedDecls;
1650         This->declArraySize += grow;
1651     }
1652
1653     memmove(convertedDecls + low + 1, convertedDecls + low, sizeof(convertedDecls[0]) * (This->numConvertedDecls - low));
1654     convertedDecls[low].decl = pDecl;
1655     convertedDecls[low].fvf = fvf;
1656     This->numConvertedDecls++;
1657
1658     TRACE("Returning %p. %d decls in array\n", pDecl, This->numConvertedDecls);
1659     return pDecl;
1660 }
1661
1662 static HRESULT WINAPI IDirect3DDevice8Impl_SetVertexShader(LPDIRECT3DDEVICE8 iface, DWORD pShader) {
1663     IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
1664     HRESULT hrc = D3D_OK;
1665
1666     TRACE("(%p) : Relay\n", This);
1667     EnterCriticalSection(&d3d8_cs);
1668     if (VS_HIGHESTFIXEDFXF >= pShader) {
1669         TRACE("Setting FVF, %d %d\n", VS_HIGHESTFIXEDFXF, pShader);
1670         IWineD3DDevice_SetFVF(This->WineD3DDevice, pShader);
1671         IWineD3DDevice_SetVertexDeclaration(This->WineD3DDevice, IDirect3DDevice8Impl_FindDecl(This, pShader));
1672         IWineD3DDevice_SetVertexShader(This->WineD3DDevice, NULL);
1673     } else {
1674         TRACE("Setting shader\n");
1675         if (This->allocated_shader_handles <= pShader - (VS_HIGHESTFIXEDFXF + 1)) {
1676             FIXME("(%p) : Number of shaders exceeds the maximum number of possible shaders\n", This);
1677             hrc = D3DERR_INVALIDCALL;
1678         } else {
1679             IDirect3DVertexShader8Impl *shader = This->shader_handles[pShader - (VS_HIGHESTFIXEDFXF + 1)];
1680             IWineD3DDevice_SetVertexDeclaration(This->WineD3DDevice,
1681                     shader ? ((IDirect3DVertexDeclaration8Impl *)shader->vertex_declaration)->wined3d_vertex_declaration : NULL);
1682             hrc = IWineD3DDevice_SetVertexShader(This->WineD3DDevice, 0 == shader ? NULL : shader->wineD3DVertexShader);
1683         }
1684     }
1685     TRACE("(%p) : returning hr(%u)\n", This, hrc);
1686     LeaveCriticalSection(&d3d8_cs);
1687
1688     return hrc;
1689 }
1690
1691 static HRESULT WINAPI IDirect3DDevice8Impl_GetVertexShader(LPDIRECT3DDEVICE8 iface, DWORD* ppShader) {
1692     IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
1693     IWineD3DVertexShader *pShader;
1694     HRESULT hrc = D3D_OK;
1695
1696     TRACE("(%p) : Relay  device@%p\n", This, This->WineD3DDevice);
1697     EnterCriticalSection(&d3d8_cs);
1698     hrc = IWineD3DDevice_GetVertexShader(This->WineD3DDevice, &pShader);
1699     if (D3D_OK == hrc) {
1700         if(0 != pShader) {
1701             IDirect3DVertexShader8Impl *d3d8_shader;
1702             hrc = IWineD3DVertexShader_GetParent(pShader, (IUnknown **)&d3d8_shader);
1703             IWineD3DVertexShader_Release(pShader);
1704             *ppShader = d3d8_shader->handle;
1705         } else {
1706             *ppShader = 0;
1707             hrc = D3D_OK;
1708         }
1709     } else {
1710         WARN("(%p) : Call to IWineD3DDevice_GetVertexShader failed %u (device %p)\n", This, hrc, This->WineD3DDevice);
1711     }
1712     TRACE("(%p) : returning %#x\n", This, *ppShader);
1713     LeaveCriticalSection(&d3d8_cs);
1714
1715     return hrc;
1716 }
1717
1718 static HRESULT  WINAPI  IDirect3DDevice8Impl_DeleteVertexShader(LPDIRECT3DDEVICE8 iface, DWORD pShader) {
1719     IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
1720
1721     TRACE("(%p) : pShader %#x\n", This, pShader);
1722
1723     EnterCriticalSection(&d3d8_cs);
1724     if (pShader <= VS_HIGHESTFIXEDFXF || This->allocated_shader_handles <= pShader - (VS_HIGHESTFIXEDFXF + 1)) {
1725         ERR("(%p) : Trying to delete an invalid handle\n", This);
1726         LeaveCriticalSection(&d3d8_cs);
1727         return D3DERR_INVALIDCALL;
1728     } else {
1729         IWineD3DVertexShader *cur = NULL;
1730         shader_handle *handle = &This->shader_handles[pShader - (VS_HIGHESTFIXEDFXF + 1)];
1731         IDirect3DVertexShader8Impl *shader = *handle;
1732
1733         IWineD3DDevice_GetVertexShader(This->WineD3DDevice, &cur);
1734         if(cur) {
1735             if(cur == shader->wineD3DVertexShader) IDirect3DDevice8_SetVertexShader(iface, 0);
1736             IWineD3DVertexShader_Release(cur);
1737         }
1738
1739         while(IUnknown_Release((IUnknown *)shader));
1740         free_shader_handle(This, handle);
1741     }
1742     LeaveCriticalSection(&d3d8_cs);
1743
1744     return D3D_OK;
1745 }
1746
1747 static HRESULT WINAPI IDirect3DDevice8Impl_SetVertexShaderConstant(LPDIRECT3DDEVICE8 iface, DWORD Register, CONST void* pConstantData, DWORD ConstantCount) {
1748     IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
1749     HRESULT hr;
1750     TRACE("(%p) : Relay\n", This);
1751
1752     EnterCriticalSection(&d3d8_cs);
1753     hr = IWineD3DDevice_SetVertexShaderConstantF(This->WineD3DDevice, Register, (CONST float *)pConstantData, ConstantCount);
1754     LeaveCriticalSection(&d3d8_cs);
1755     return hr;
1756 }
1757
1758 static HRESULT WINAPI IDirect3DDevice8Impl_GetVertexShaderConstant(LPDIRECT3DDEVICE8 iface, DWORD Register, void* pConstantData, DWORD ConstantCount) {
1759     IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
1760     HRESULT hr;
1761     TRACE("(%p) : Relay\n", This);
1762
1763     EnterCriticalSection(&d3d8_cs);
1764     hr = IWineD3DDevice_GetVertexShaderConstantF(This->WineD3DDevice, Register, (float *)pConstantData, ConstantCount);
1765     LeaveCriticalSection(&d3d8_cs);
1766     return hr;
1767 }
1768
1769 static HRESULT WINAPI IDirect3DDevice8Impl_GetVertexShaderDeclaration(LPDIRECT3DDEVICE8 iface, DWORD pVertexShader, void* pData, DWORD* pSizeOfData) {
1770     IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
1771     IDirect3DVertexDeclaration8Impl *declaration;
1772     IDirect3DVertexShader8Impl *shader = NULL;
1773
1774     TRACE("(%p) : pVertexShader 0x%08x, pData %p, *pSizeOfData %u\n", This, pVertexShader, pData, *pSizeOfData);
1775
1776     EnterCriticalSection(&d3d8_cs);
1777     if (pVertexShader <= VS_HIGHESTFIXEDFXF || This->allocated_shader_handles <= pVertexShader - (VS_HIGHESTFIXEDFXF + 1)) {
1778         ERR("Passed an invalid shader handle.\n");
1779         LeaveCriticalSection(&d3d8_cs);
1780         return D3DERR_INVALIDCALL;
1781     }
1782
1783     shader = This->shader_handles[pVertexShader - (VS_HIGHESTFIXEDFXF + 1)];
1784     declaration = (IDirect3DVertexDeclaration8Impl *)shader->vertex_declaration;
1785
1786     /* If pData is NULL, we just return the required size of the buffer. */
1787     if (!pData) {
1788         *pSizeOfData = declaration->elements_size;
1789         LeaveCriticalSection(&d3d8_cs);
1790         return D3D_OK;
1791     }
1792
1793     /* MSDN claims that if *pSizeOfData is smaller than the required size
1794      * we should write the required size and return D3DERR_MOREDATA.
1795      * That's not actually true. */
1796     if (*pSizeOfData < declaration->elements_size) {
1797         LeaveCriticalSection(&d3d8_cs);
1798         return D3DERR_INVALIDCALL;
1799     }
1800
1801     CopyMemory(pData, declaration->elements, declaration->elements_size);
1802     LeaveCriticalSection(&d3d8_cs);
1803
1804     return D3D_OK;
1805 }
1806
1807 static HRESULT WINAPI IDirect3DDevice8Impl_GetVertexShaderFunction(LPDIRECT3DDEVICE8 iface, DWORD pVertexShader, void* pData, DWORD* pSizeOfData) {
1808     IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
1809     IDirect3DVertexShader8Impl *shader = NULL;
1810     HRESULT hr;
1811
1812     TRACE("(%p) : pVertexShader %#x, pData %p, pSizeOfData %p\n", This, pVertexShader, pData, pSizeOfData);
1813
1814     EnterCriticalSection(&d3d8_cs);
1815     if (pVertexShader <= VS_HIGHESTFIXEDFXF || This->allocated_shader_handles <= pVertexShader - (VS_HIGHESTFIXEDFXF + 1)) {
1816         ERR("Passed an invalid shader handle.\n");
1817         LeaveCriticalSection(&d3d8_cs);
1818         return D3DERR_INVALIDCALL;
1819     }
1820
1821     shader = This->shader_handles[pVertexShader - (VS_HIGHESTFIXEDFXF + 1)];
1822     hr = IWineD3DVertexShader_GetFunction(shader->wineD3DVertexShader, pData, pSizeOfData);
1823     LeaveCriticalSection(&d3d8_cs);
1824     return hr;
1825 }
1826
1827 static HRESULT WINAPI IDirect3DDevice8Impl_SetIndices(LPDIRECT3DDEVICE8 iface, IDirect3DIndexBuffer8* pIndexData, UINT baseVertexIndex) {
1828     IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
1829     HRESULT hr;
1830     TRACE("(%p) Relay\n", This);
1831
1832     EnterCriticalSection(&d3d8_cs);
1833     /* WineD3D takes an INT(due to d3d9), but d3d8 uses UINTs. Do I have to add a check here that
1834      * the UINT doesn't cause an overflow in the INT? It seems rather unlikely because such large
1835      * vertex buffers can't be created to address them with an index that requires the 32nd bit
1836      * (4 Byte minimum vertex size * 2^31-1 -> 8 gb buffer. The index sign would be the least
1837      * problem)
1838      */
1839     IWineD3DDevice_SetBaseVertexIndex(This->WineD3DDevice, baseVertexIndex);
1840     hr = IWineD3DDevice_SetIndices(This->WineD3DDevice,
1841             pIndexData ? ((IDirect3DIndexBuffer8Impl *)pIndexData)->wineD3DIndexBuffer : NULL);
1842     LeaveCriticalSection(&d3d8_cs);
1843     return hr;
1844 }
1845
1846 static HRESULT WINAPI IDirect3DDevice8Impl_GetIndices(LPDIRECT3DDEVICE8 iface, IDirect3DIndexBuffer8** ppIndexData,UINT* pBaseVertexIndex) {
1847     IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
1848     IWineD3DIndexBuffer *retIndexData = NULL;
1849     HRESULT rc = D3D_OK;
1850
1851     TRACE("(%p) Relay\n", This);
1852
1853     if(ppIndexData == NULL){
1854         return D3DERR_INVALIDCALL;
1855     }
1856
1857     EnterCriticalSection(&d3d8_cs);
1858     /* The case from UINT to INT is safe because d3d8 will never set negative values */
1859     IWineD3DDevice_GetBaseVertexIndex(This->WineD3DDevice, (INT *) pBaseVertexIndex);
1860     rc = IWineD3DDevice_GetIndices(This->WineD3DDevice, &retIndexData);
1861     if (SUCCEEDED(rc) && retIndexData) {
1862         IWineD3DIndexBuffer_GetParent(retIndexData, (IUnknown **)ppIndexData);
1863         IWineD3DIndexBuffer_Release(retIndexData);
1864     } else {
1865         if (FAILED(rc)) FIXME("Call to GetIndices failed\n");
1866         *ppIndexData = NULL;
1867     }
1868     LeaveCriticalSection(&d3d8_cs);
1869
1870     return rc;
1871 }
1872 static HRESULT WINAPI IDirect3DDevice8Impl_CreatePixelShader(LPDIRECT3DDEVICE8 iface, CONST DWORD* pFunction, DWORD* ppShader) {
1873     IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
1874     IDirect3DPixelShader8Impl *object;
1875     HRESULT hrc = D3D_OK;
1876
1877     TRACE("(%p) : pFunction(%p), ppShader(%p)\n", This, pFunction, ppShader);
1878
1879     if (NULL == ppShader) {
1880         TRACE("(%p) Invalid call\n", This);
1881         return D3DERR_INVALIDCALL;
1882     }
1883     object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
1884
1885     if (NULL == object) {
1886         return E_OUTOFMEMORY;
1887     } else {
1888         EnterCriticalSection(&d3d8_cs);
1889
1890         object->ref    = 1;
1891         object->lpVtbl = &Direct3DPixelShader8_Vtbl;
1892         hrc = IWineD3DDevice_CreatePixelShader(This->WineD3DDevice, pFunction, &object->wineD3DPixelShader , (IUnknown *)object);
1893         if (D3D_OK != hrc) {
1894             FIXME("(%p) call to IWineD3DDevice_CreatePixelShader failed\n", This);
1895             HeapFree(GetProcessHeap(), 0 , object);
1896             *ppShader = 0;
1897         } else {
1898             shader_handle *handle = alloc_shader_handle(This);
1899             if (!handle) {
1900                 ERR("Failed to allocate shader handle\n");
1901                 IDirect3DVertexShader8_Release((IUnknown *)object);
1902                 hrc = E_OUTOFMEMORY;
1903             } else {
1904                 *handle = object;
1905                 object->handle = (handle - This->shader_handles) + VS_HIGHESTFIXEDFXF + 1;
1906                 *ppShader = object->handle;
1907                 TRACE("(%p) : returning %p (handle %#x)\n", This, object, *ppShader);
1908             }
1909         }
1910         LeaveCriticalSection(&d3d8_cs);
1911     }
1912
1913     return hrc;
1914 }
1915
1916 static HRESULT WINAPI IDirect3DDevice8Impl_SetPixelShader(LPDIRECT3DDEVICE8 iface, DWORD pShader) {
1917     IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
1918     IDirect3DPixelShader8Impl *shader = NULL;
1919     HRESULT hr;
1920
1921     TRACE("(%p) : pShader %#x\n", This, pShader);
1922
1923     EnterCriticalSection(&d3d8_cs);
1924     if (pShader > VS_HIGHESTFIXEDFXF && This->allocated_shader_handles > pShader - (VS_HIGHESTFIXEDFXF + 1)) {
1925         shader = This->shader_handles[pShader - (VS_HIGHESTFIXEDFXF + 1)];
1926     } else if (pShader) {
1927         ERR("Trying to set an invalid handle.\n");
1928     }
1929
1930     TRACE("(%p) : Setting shader %p\n", This, shader);
1931     hr = IWineD3DDevice_SetPixelShader(This->WineD3DDevice, shader == NULL ? NULL :shader->wineD3DPixelShader);
1932     LeaveCriticalSection(&d3d8_cs);
1933     return hr;
1934 }
1935
1936 static HRESULT WINAPI IDirect3DDevice8Impl_GetPixelShader(LPDIRECT3DDEVICE8 iface, DWORD* ppShader) {
1937     IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
1938     IWineD3DPixelShader *object;
1939
1940     HRESULT hrc = D3D_OK;
1941     TRACE("(%p) Relay\n", This);
1942     if (NULL == ppShader) {
1943         TRACE("(%p) Invalid call\n", This);
1944         return D3DERR_INVALIDCALL;
1945     }
1946
1947     EnterCriticalSection(&d3d8_cs);
1948     hrc = IWineD3DDevice_GetPixelShader(This->WineD3DDevice, &object);
1949     if (D3D_OK == hrc && NULL != object) {
1950         IDirect3DPixelShader8Impl *d3d8_shader;
1951         hrc = IWineD3DPixelShader_GetParent(object, (IUnknown **)&d3d8_shader);
1952         IWineD3DPixelShader_Release(object);
1953         *ppShader = d3d8_shader->handle;
1954     } else {
1955         *ppShader = 0;
1956     }
1957
1958     TRACE("(%p) : returning %#x\n", This, *ppShader);
1959     LeaveCriticalSection(&d3d8_cs);
1960     return hrc;
1961 }
1962
1963 static HRESULT WINAPI IDirect3DDevice8Impl_DeletePixelShader(LPDIRECT3DDEVICE8 iface, DWORD pShader) {
1964     IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
1965
1966     TRACE("(%p) : pShader %#x\n", This, pShader);
1967
1968     EnterCriticalSection(&d3d8_cs);
1969     if (pShader <= VS_HIGHESTFIXEDFXF || This->allocated_shader_handles <= pShader - (VS_HIGHESTFIXEDFXF + 1)) {
1970         ERR("(%p) : Trying to delete an invalid handle\n", This);
1971         LeaveCriticalSection(&d3d8_cs);
1972         return D3DERR_INVALIDCALL;
1973     } else {
1974         IWineD3DPixelShader *cur = NULL;
1975         shader_handle *handle = &This->shader_handles[pShader - (VS_HIGHESTFIXEDFXF + 1)];
1976         IDirect3DPixelShader8Impl *shader = *handle;
1977
1978         IWineD3DDevice_GetPixelShader(This->WineD3DDevice, &cur);
1979         if(cur) {
1980             if(cur == shader->wineD3DPixelShader) IDirect3DDevice8_SetPixelShader(iface, 0);
1981             IWineD3DPixelShader_Release(cur);
1982         }
1983
1984         while(IUnknown_Release((IUnknown *)shader));
1985         free_shader_handle(This, handle);
1986     }
1987     LeaveCriticalSection(&d3d8_cs);
1988
1989     return D3D_OK;
1990 }
1991
1992 static HRESULT  WINAPI  IDirect3DDevice8Impl_SetPixelShaderConstant(LPDIRECT3DDEVICE8 iface, DWORD Register, CONST void* pConstantData, DWORD ConstantCount) {
1993     IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
1994     HRESULT hr;
1995     TRACE("(%p) Relay\n", This);
1996
1997     EnterCriticalSection(&d3d8_cs);
1998     hr = IWineD3DDevice_SetPixelShaderConstantF(This->WineD3DDevice, Register, (CONST float *)pConstantData, ConstantCount);
1999     LeaveCriticalSection(&d3d8_cs);
2000     return hr;
2001 }
2002
2003 static HRESULT WINAPI IDirect3DDevice8Impl_GetPixelShaderConstant(LPDIRECT3DDEVICE8 iface, DWORD Register, void* pConstantData, DWORD ConstantCount) {
2004     IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
2005     HRESULT hr;
2006     TRACE("(%p) Relay\n", This);
2007
2008     EnterCriticalSection(&d3d8_cs);
2009     hr = IWineD3DDevice_GetPixelShaderConstantF(This->WineD3DDevice, Register, (float *)pConstantData, ConstantCount);
2010     LeaveCriticalSection(&d3d8_cs);
2011     return hr;
2012 }
2013
2014 static HRESULT WINAPI IDirect3DDevice8Impl_GetPixelShaderFunction(LPDIRECT3DDEVICE8 iface, DWORD pPixelShader, void* pData, DWORD* pSizeOfData) {
2015     IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
2016     IDirect3DPixelShader8Impl *shader = NULL;
2017     HRESULT hr;
2018
2019     TRACE("(%p) : pPixelShader %#x, pData %p, pSizeOfData %p\n", This, pPixelShader, pData, pSizeOfData);
2020
2021     EnterCriticalSection(&d3d8_cs);
2022     if (pPixelShader <= VS_HIGHESTFIXEDFXF || This->allocated_shader_handles <= pPixelShader - (VS_HIGHESTFIXEDFXF + 1)) {
2023         ERR("Passed an invalid shader handle.\n");
2024         LeaveCriticalSection(&d3d8_cs);
2025         return D3DERR_INVALIDCALL;
2026     }
2027
2028     shader = This->shader_handles[pPixelShader - (VS_HIGHESTFIXEDFXF + 1)];
2029     hr = IWineD3DPixelShader_GetFunction(shader->wineD3DPixelShader, pData, pSizeOfData);
2030     LeaveCriticalSection(&d3d8_cs);
2031     return hr;
2032 }
2033
2034 static HRESULT WINAPI IDirect3DDevice8Impl_DrawRectPatch(LPDIRECT3DDEVICE8 iface, UINT Handle,CONST float* pNumSegs,CONST D3DRECTPATCH_INFO* pRectPatchInfo) {
2035     IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
2036     HRESULT hr;
2037     TRACE("(%p) Relay\n", This);
2038
2039     EnterCriticalSection(&d3d8_cs);
2040     hr = IWineD3DDevice_DrawRectPatch(This->WineD3DDevice, Handle, pNumSegs, (CONST WINED3DRECTPATCH_INFO *)pRectPatchInfo);
2041     LeaveCriticalSection(&d3d8_cs);
2042     return hr;
2043 }
2044
2045 static HRESULT WINAPI IDirect3DDevice8Impl_DrawTriPatch(LPDIRECT3DDEVICE8 iface, UINT Handle,CONST float* pNumSegs,CONST D3DTRIPATCH_INFO* pTriPatchInfo) {
2046     IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
2047     HRESULT hr;
2048     TRACE("(%p) Relay\n", This);
2049
2050     EnterCriticalSection(&d3d8_cs);
2051     hr = IWineD3DDevice_DrawTriPatch(This->WineD3DDevice, Handle, pNumSegs, (CONST WINED3DTRIPATCH_INFO *)pTriPatchInfo);
2052     LeaveCriticalSection(&d3d8_cs);
2053     return hr;
2054 }
2055
2056 static HRESULT WINAPI IDirect3DDevice8Impl_DeletePatch(LPDIRECT3DDEVICE8 iface, UINT Handle) {
2057     IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
2058     HRESULT hr;
2059     TRACE("(%p) Relay\n", This);
2060
2061     EnterCriticalSection(&d3d8_cs);
2062     hr = IWineD3DDevice_DeletePatch(This->WineD3DDevice, Handle);
2063     LeaveCriticalSection(&d3d8_cs);
2064     return hr;
2065 }
2066
2067 static HRESULT WINAPI IDirect3DDevice8Impl_SetStreamSource(LPDIRECT3DDEVICE8 iface, UINT StreamNumber,IDirect3DVertexBuffer8* pStreamData,UINT Stride) {
2068     IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
2069     HRESULT hr;
2070     TRACE("(%p) Relay\n" , This);
2071
2072     EnterCriticalSection(&d3d8_cs);
2073     hr = IWineD3DDevice_SetStreamSource(This->WineD3DDevice, StreamNumber,
2074                                         NULL == pStreamData ? NULL : ((IDirect3DVertexBuffer8Impl *)pStreamData)->wineD3DVertexBuffer,
2075                                         0/* Offset in bytes */, Stride);
2076     LeaveCriticalSection(&d3d8_cs);
2077     return hr;
2078 }
2079
2080 static HRESULT WINAPI IDirect3DDevice8Impl_GetStreamSource(LPDIRECT3DDEVICE8 iface, UINT StreamNumber,IDirect3DVertexBuffer8** pStream,UINT* pStride) {
2081     IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
2082     IWineD3DVertexBuffer *retStream = NULL;
2083     HRESULT rc = D3D_OK;
2084
2085     TRACE("(%p) Relay\n" , This);
2086
2087     if(pStream == NULL){
2088         return D3DERR_INVALIDCALL;
2089     }
2090
2091     EnterCriticalSection(&d3d8_cs);
2092     rc = IWineD3DDevice_GetStreamSource(This->WineD3DDevice, StreamNumber, &retStream, 0 /* Offset in bytes */, pStride);
2093     if (rc == D3D_OK  && NULL != retStream) {
2094         IWineD3DVertexBuffer_GetParent(retStream, (IUnknown **)pStream);
2095         IWineD3DVertexBuffer_Release(retStream);
2096     }else{
2097         if (rc != D3D_OK){
2098             FIXME("Call to GetStreamSource failed %p\n",  pStride);
2099         }
2100         *pStream = NULL;
2101     }
2102     LeaveCriticalSection(&d3d8_cs);
2103
2104     return rc;
2105 }
2106
2107
2108 const IDirect3DDevice8Vtbl Direct3DDevice8_Vtbl =
2109 {
2110     IDirect3DDevice8Impl_QueryInterface,
2111     IDirect3DDevice8Impl_AddRef,
2112     IDirect3DDevice8Impl_Release,
2113     IDirect3DDevice8Impl_TestCooperativeLevel,
2114     IDirect3DDevice8Impl_GetAvailableTextureMem,
2115     IDirect3DDevice8Impl_ResourceManagerDiscardBytes,
2116     IDirect3DDevice8Impl_GetDirect3D,
2117     IDirect3DDevice8Impl_GetDeviceCaps,
2118     IDirect3DDevice8Impl_GetDisplayMode,
2119     IDirect3DDevice8Impl_GetCreationParameters,
2120     IDirect3DDevice8Impl_SetCursorProperties,
2121     IDirect3DDevice8Impl_SetCursorPosition,
2122     IDirect3DDevice8Impl_ShowCursor,
2123     IDirect3DDevice8Impl_CreateAdditionalSwapChain,
2124     IDirect3DDevice8Impl_Reset,
2125     IDirect3DDevice8Impl_Present,
2126     IDirect3DDevice8Impl_GetBackBuffer,
2127     IDirect3DDevice8Impl_GetRasterStatus,
2128     IDirect3DDevice8Impl_SetGammaRamp,
2129     IDirect3DDevice8Impl_GetGammaRamp,
2130     IDirect3DDevice8Impl_CreateTexture,
2131     IDirect3DDevice8Impl_CreateVolumeTexture,
2132     IDirect3DDevice8Impl_CreateCubeTexture,
2133     IDirect3DDevice8Impl_CreateVertexBuffer,
2134     IDirect3DDevice8Impl_CreateIndexBuffer,
2135     IDirect3DDevice8Impl_CreateRenderTarget,
2136     IDirect3DDevice8Impl_CreateDepthStencilSurface,
2137     IDirect3DDevice8Impl_CreateImageSurface,
2138     IDirect3DDevice8Impl_CopyRects,
2139     IDirect3DDevice8Impl_UpdateTexture,
2140     IDirect3DDevice8Impl_GetFrontBuffer,
2141     IDirect3DDevice8Impl_SetRenderTarget,
2142     IDirect3DDevice8Impl_GetRenderTarget,
2143     IDirect3DDevice8Impl_GetDepthStencilSurface,
2144     IDirect3DDevice8Impl_BeginScene,
2145     IDirect3DDevice8Impl_EndScene,
2146     IDirect3DDevice8Impl_Clear,
2147     IDirect3DDevice8Impl_SetTransform,
2148     IDirect3DDevice8Impl_GetTransform,
2149     IDirect3DDevice8Impl_MultiplyTransform,
2150     IDirect3DDevice8Impl_SetViewport,
2151     IDirect3DDevice8Impl_GetViewport,
2152     IDirect3DDevice8Impl_SetMaterial,
2153     IDirect3DDevice8Impl_GetMaterial,
2154     IDirect3DDevice8Impl_SetLight,
2155     IDirect3DDevice8Impl_GetLight,
2156     IDirect3DDevice8Impl_LightEnable,
2157     IDirect3DDevice8Impl_GetLightEnable,
2158     IDirect3DDevice8Impl_SetClipPlane,
2159     IDirect3DDevice8Impl_GetClipPlane,
2160     IDirect3DDevice8Impl_SetRenderState,
2161     IDirect3DDevice8Impl_GetRenderState,
2162     IDirect3DDevice8Impl_BeginStateBlock,
2163     IDirect3DDevice8Impl_EndStateBlock,
2164     IDirect3DDevice8Impl_ApplyStateBlock,
2165     IDirect3DDevice8Impl_CaptureStateBlock,
2166     IDirect3DDevice8Impl_DeleteStateBlock,
2167     IDirect3DDevice8Impl_CreateStateBlock,
2168     IDirect3DDevice8Impl_SetClipStatus,
2169     IDirect3DDevice8Impl_GetClipStatus,
2170     IDirect3DDevice8Impl_GetTexture,
2171     IDirect3DDevice8Impl_SetTexture,
2172     IDirect3DDevice8Impl_GetTextureStageState,
2173     IDirect3DDevice8Impl_SetTextureStageState,
2174     IDirect3DDevice8Impl_ValidateDevice,
2175     IDirect3DDevice8Impl_GetInfo,
2176     IDirect3DDevice8Impl_SetPaletteEntries,
2177     IDirect3DDevice8Impl_GetPaletteEntries,
2178     IDirect3DDevice8Impl_SetCurrentTexturePalette,
2179     IDirect3DDevice8Impl_GetCurrentTexturePalette,
2180     IDirect3DDevice8Impl_DrawPrimitive,
2181     IDirect3DDevice8Impl_DrawIndexedPrimitive,
2182     IDirect3DDevice8Impl_DrawPrimitiveUP,
2183     IDirect3DDevice8Impl_DrawIndexedPrimitiveUP,
2184     IDirect3DDevice8Impl_ProcessVertices,
2185     IDirect3DDevice8Impl_CreateVertexShader,
2186     IDirect3DDevice8Impl_SetVertexShader,
2187     IDirect3DDevice8Impl_GetVertexShader,
2188     IDirect3DDevice8Impl_DeleteVertexShader,
2189     IDirect3DDevice8Impl_SetVertexShaderConstant,
2190     IDirect3DDevice8Impl_GetVertexShaderConstant,
2191     IDirect3DDevice8Impl_GetVertexShaderDeclaration,
2192     IDirect3DDevice8Impl_GetVertexShaderFunction,
2193     IDirect3DDevice8Impl_SetStreamSource,
2194     IDirect3DDevice8Impl_GetStreamSource,
2195     IDirect3DDevice8Impl_SetIndices,
2196     IDirect3DDevice8Impl_GetIndices,
2197     IDirect3DDevice8Impl_CreatePixelShader,
2198     IDirect3DDevice8Impl_SetPixelShader,
2199     IDirect3DDevice8Impl_GetPixelShader,
2200     IDirect3DDevice8Impl_DeletePixelShader,
2201     IDirect3DDevice8Impl_SetPixelShaderConstant,
2202     IDirect3DDevice8Impl_GetPixelShaderConstant,
2203     IDirect3DDevice8Impl_GetPixelShaderFunction,
2204     IDirect3DDevice8Impl_DrawRectPatch,
2205     IDirect3DDevice8Impl_DrawTriPatch,
2206     IDirect3DDevice8Impl_DeletePatch
2207 };
2208
2209 /* Internal function called back during the CreateDevice to create a render target  */
2210 HRESULT WINAPI D3D8CB_CreateSurface(IUnknown *device, IUnknown *pSuperior, UINT Width, UINT Height,
2211                                          WINED3DFORMAT Format, DWORD Usage, WINED3DPOOL Pool, UINT Level,
2212                                          WINED3DCUBEMAP_FACES Face, IWineD3DSurface **ppSurface,
2213                                          HANDLE *pSharedHandle) {
2214
2215     HRESULT res = D3D_OK;
2216     IDirect3DSurface8Impl *d3dSurface = NULL;
2217     BOOL Lockable = TRUE;
2218
2219     if((WINED3DPOOL_DEFAULT == Pool && WINED3DUSAGE_DYNAMIC != Usage))
2220         Lockable = FALSE;
2221
2222     TRACE("relay\n");
2223     res = IDirect3DDevice8Impl_CreateSurface((IDirect3DDevice8 *)device, Width, Height, (D3DFORMAT)Format, Lockable, FALSE/*Discard*/, Level,  (IDirect3DSurface8 **)&d3dSurface, D3DRTYPE_SURFACE, Usage, Pool, D3DMULTISAMPLE_NONE, 0 /* MultisampleQuality */);
2224
2225     if (SUCCEEDED(res)) {
2226         *ppSurface = d3dSurface->wineD3DSurface;
2227         d3dSurface->container = pSuperior;
2228         IUnknown_Release(d3dSurface->parentDevice);
2229         d3dSurface->parentDevice = NULL;
2230         d3dSurface->forwardReference = pSuperior;
2231     } else {
2232         FIXME("(%p) IDirect3DDevice8_CreateSurface failed\n", device);
2233     }
2234     return res;
2235 }
2236
2237 ULONG WINAPI D3D8CB_DestroySurface(IWineD3DSurface *pSurface) {
2238     IDirect3DSurface8Impl* surfaceParent;
2239     TRACE("(%p) call back\n", pSurface);
2240
2241     IWineD3DSurface_GetParent(pSurface, (IUnknown **) &surfaceParent);
2242     /* GetParent's AddRef was forwarded to an object in destruction.
2243      * Releasing it here again would cause an endless recursion. */
2244     surfaceParent->forwardReference = NULL;
2245     return IDirect3DSurface8_Release((IDirect3DSurface8*) surfaceParent);
2246 }