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