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