kernel32: Check the 64-bit flag when starting a process.
[wine] / dlls / d3d8 / directx.c
1 /*
2  * IDirect3D8 implementation
3  *
4  * Copyright 2002-2004 Jason Edmeades
5  * Copyright 2003-2004 Raphael Junqueira
6  * Copyright 2004 Christian Costa
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with this library; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21  */
22
23 #include "config.h"
24
25 #include <stdarg.h>
26
27 #define NONAMELESSUNION
28 #define NONAMELESSSTRUCT
29 #include "windef.h"
30 #include "winbase.h"
31 #include "wingdi.h"
32 #include "winuser.h"
33 #include "wine/debug.h"
34 #include "wine/unicode.h"
35
36 #include "d3d8_private.h"
37
38 WINE_DEFAULT_DEBUG_CHANNEL(d3d8);
39
40 /* IDirect3D IUnknown parts follow: */
41 static HRESULT WINAPI IDirect3D8Impl_QueryInterface(LPDIRECT3D8 iface, REFIID riid,LPVOID *ppobj)
42 {
43     IDirect3D8Impl *This = (IDirect3D8Impl *)iface;
44
45     if (IsEqualGUID(riid, &IID_IUnknown)
46         || IsEqualGUID(riid, &IID_IDirect3D8)) {
47         IUnknown_AddRef(iface);
48         *ppobj = This;
49         return S_OK;
50     }
51
52     WARN("(%p)->(%s,%p),not found\n", This, debugstr_guid(riid),ppobj);
53     *ppobj = NULL;
54     return E_NOINTERFACE;
55 }
56
57 static ULONG WINAPI IDirect3D8Impl_AddRef(LPDIRECT3D8 iface) {
58     IDirect3D8Impl *This = (IDirect3D8Impl *)iface;
59     ULONG ref = InterlockedIncrement(&This->ref);
60
61     TRACE("(%p) : AddRef from %d\n", This, ref - 1);
62
63     return ref;
64 }
65
66 static ULONG WINAPI IDirect3D8Impl_Release(LPDIRECT3D8 iface) {
67     IDirect3D8Impl *This = (IDirect3D8Impl *)iface;
68     ULONG ref = InterlockedDecrement(&This->ref);
69
70     TRACE("(%p) : ReleaseRef to %d\n", This, ref);
71
72     if (ref == 0) {
73         TRACE("Releasing wined3d %p\n", This->WineD3D);
74         EnterCriticalSection(&d3d8_cs);
75         IWineD3D_Release(This->WineD3D);
76         LeaveCriticalSection(&d3d8_cs);
77         HeapFree(GetProcessHeap(), 0, This);
78     }
79
80     return ref;
81 }
82
83 /* IDirect3D8 Interface follow: */
84 static HRESULT WINAPI IDirect3D8Impl_RegisterSoftwareDevice (LPDIRECT3D8 iface, void* pInitializeFunction) {
85     IDirect3D8Impl *This = (IDirect3D8Impl *)iface;
86     HRESULT hr;
87     TRACE("(%p)->(%p)\n", This, pInitializeFunction);
88
89     EnterCriticalSection(&d3d8_cs);
90     hr = IWineD3D_RegisterSoftwareDevice(This->WineD3D, pInitializeFunction);
91     LeaveCriticalSection(&d3d8_cs);
92     return hr;
93 }
94
95 static UINT WINAPI IDirect3D8Impl_GetAdapterCount (LPDIRECT3D8 iface) {
96     IDirect3D8Impl *This = (IDirect3D8Impl *)iface;
97     HRESULT hr;
98     TRACE("(%p)\n", This);
99
100     EnterCriticalSection(&d3d8_cs);
101     hr = IWineD3D_GetAdapterCount(This->WineD3D);
102     LeaveCriticalSection(&d3d8_cs);
103     return hr;
104 }
105
106 static HRESULT WINAPI IDirect3D8Impl_GetAdapterIdentifier(LPDIRECT3D8 iface,
107         UINT Adapter, DWORD Flags, D3DADAPTER_IDENTIFIER8 *pIdentifier)
108 {
109     IDirect3D8Impl *This = (IDirect3D8Impl *)iface;
110     WINED3DADAPTER_IDENTIFIER adapter_id;
111     HRESULT hr;
112
113     TRACE("(%p)->(%d,%08x, %p\n", This, Adapter, Flags, pIdentifier);
114
115     adapter_id.driver = pIdentifier->Driver;
116     adapter_id.driver_size = sizeof(pIdentifier->Driver);
117     adapter_id.description = pIdentifier->Description;
118     adapter_id.description_size = sizeof(pIdentifier->Description);
119     adapter_id.device_name = NULL; /* d3d9 only */
120     adapter_id.device_name_size = 0; /* d3d9 only */
121
122     EnterCriticalSection(&d3d8_cs);
123     hr = IWineD3D_GetAdapterIdentifier(This->WineD3D, Adapter, Flags, &adapter_id);
124     LeaveCriticalSection(&d3d8_cs);
125
126     pIdentifier->DriverVersion = adapter_id.driver_version;
127     pIdentifier->VendorId = adapter_id.vendor_id;
128     pIdentifier->DeviceId = adapter_id.device_id;
129     pIdentifier->SubSysId = adapter_id.subsystem_id;
130     pIdentifier->Revision = adapter_id.revision;
131     memcpy(&pIdentifier->DeviceIdentifier, &adapter_id.device_identifier, sizeof(pIdentifier->DeviceIdentifier));
132     pIdentifier->WHQLLevel = adapter_id.whql_level;
133
134     return hr;
135 }
136
137 static UINT WINAPI IDirect3D8Impl_GetAdapterModeCount (LPDIRECT3D8 iface,UINT Adapter) {
138     IDirect3D8Impl *This = (IDirect3D8Impl *)iface;
139     HRESULT hr;
140     TRACE("(%p)->(%d)\n", This, Adapter);
141
142     EnterCriticalSection(&d3d8_cs);
143     hr = IWineD3D_GetAdapterModeCount(This->WineD3D, Adapter, 0 /* format */);
144     LeaveCriticalSection(&d3d8_cs);
145     return hr;
146 }
147
148 static HRESULT WINAPI IDirect3D8Impl_EnumAdapterModes (LPDIRECT3D8 iface, UINT Adapter, UINT Mode, D3DDISPLAYMODE* pMode) {
149     IDirect3D8Impl *This = (IDirect3D8Impl *)iface;
150     HRESULT hr;
151     TRACE("(%p)->(%d, %d, %p)\n", This, Adapter, Mode, pMode);
152
153     EnterCriticalSection(&d3d8_cs);
154     hr = IWineD3D_EnumAdapterModes(This->WineD3D, Adapter, WINED3DFMT_UNKNOWN, Mode, (WINED3DDISPLAYMODE *) pMode);
155     LeaveCriticalSection(&d3d8_cs);
156
157     if (SUCCEEDED(hr)) pMode->Format = d3dformat_from_wined3dformat(pMode->Format);
158
159     return hr;
160 }
161
162 static HRESULT WINAPI IDirect3D8Impl_GetAdapterDisplayMode (LPDIRECT3D8 iface, UINT Adapter, D3DDISPLAYMODE* pMode) {
163     IDirect3D8Impl *This = (IDirect3D8Impl *)iface;
164     HRESULT hr;
165     TRACE("(%p)->(%d,%p)\n", This, Adapter, pMode);
166
167     EnterCriticalSection(&d3d8_cs);
168     hr = IWineD3D_GetAdapterDisplayMode(This->WineD3D, Adapter, (WINED3DDISPLAYMODE *) pMode);
169     LeaveCriticalSection(&d3d8_cs);
170
171     if (SUCCEEDED(hr)) pMode->Format = d3dformat_from_wined3dformat(pMode->Format);
172
173     return hr;
174 }
175
176 static HRESULT  WINAPI  IDirect3D8Impl_CheckDeviceType            (LPDIRECT3D8 iface,
177                                                             UINT Adapter, D3DDEVTYPE CheckType, D3DFORMAT DisplayFormat,
178                                                             D3DFORMAT BackBufferFormat, BOOL Windowed) {
179     IDirect3D8Impl *This = (IDirect3D8Impl *)iface;
180     HRESULT hr;
181     TRACE("(%p)->(%d, %d, %d, %d, %s)\n", This, Adapter, CheckType, DisplayFormat, BackBufferFormat, Windowed ? "true" : "false");
182
183     EnterCriticalSection(&d3d8_cs);
184     hr = IWineD3D_CheckDeviceType(This->WineD3D, Adapter, CheckType, wined3dformat_from_d3dformat(DisplayFormat),
185             wined3dformat_from_d3dformat(BackBufferFormat), Windowed);
186     LeaveCriticalSection(&d3d8_cs);
187     return hr;
188 }
189
190 static HRESULT  WINAPI  IDirect3D8Impl_CheckDeviceFormat          (LPDIRECT3D8 iface,
191                                                             UINT Adapter, D3DDEVTYPE DeviceType, D3DFORMAT AdapterFormat,
192                                                             DWORD Usage, D3DRESOURCETYPE RType, D3DFORMAT CheckFormat) {
193     IDirect3D8Impl *This = (IDirect3D8Impl *)iface;
194     HRESULT hr;
195     WINED3DRESOURCETYPE WineD3DRType;
196     TRACE("(%p)->(%d, %d, %d, %08x, %d, %d)\n", This, Adapter, DeviceType, AdapterFormat, Usage, RType, CheckFormat);
197
198     if(CheckFormat == D3DFMT_R8G8B8)
199     {
200         /* See comment in dlls/d3d9/directx.c, IDirect3D9Impl_CheckDeviceFormat for details */
201         WARN("D3DFMT_R8G8B8 is not available on windows, returning D3DERR_NOTAVAILABLE\n");
202         return D3DERR_NOTAVAILABLE;
203     }
204
205
206     switch(RType) {
207         case D3DRTYPE_VERTEXBUFFER:
208         case D3DRTYPE_INDEXBUFFER:
209             WineD3DRType = WINED3DRTYPE_BUFFER;
210             break;
211
212         default:
213             WineD3DRType = RType;
214             break;
215     }
216
217     EnterCriticalSection(&d3d8_cs);
218     hr = IWineD3D_CheckDeviceFormat(This->WineD3D, Adapter, DeviceType, wined3dformat_from_d3dformat(AdapterFormat),
219             Usage, WineD3DRType, wined3dformat_from_d3dformat(CheckFormat), SURFACE_OPENGL);
220     LeaveCriticalSection(&d3d8_cs);
221     return hr;
222 }
223
224 static HRESULT  WINAPI  IDirect3D8Impl_CheckDeviceMultiSampleType(LPDIRECT3D8 iface,
225                                                            UINT Adapter, D3DDEVTYPE DeviceType, D3DFORMAT SurfaceFormat,
226                                                            BOOL Windowed, D3DMULTISAMPLE_TYPE MultiSampleType) {
227     IDirect3D8Impl *This = (IDirect3D8Impl *)iface;
228     HRESULT hr;
229     TRACE("(%p)-<(%d, %d, %d, %s, %d)\n", This, Adapter, DeviceType, SurfaceFormat, Windowed ? "true" : "false", MultiSampleType);
230
231     EnterCriticalSection(&d3d8_cs);
232     hr = IWineD3D_CheckDeviceMultiSampleType(This->WineD3D, Adapter, DeviceType,
233             wined3dformat_from_d3dformat(SurfaceFormat), Windowed, (WINED3DMULTISAMPLE_TYPE) MultiSampleType, NULL);
234     LeaveCriticalSection(&d3d8_cs);
235     return hr;
236 }
237
238 static HRESULT  WINAPI  IDirect3D8Impl_CheckDepthStencilMatch(LPDIRECT3D8 iface, 
239                                                        UINT Adapter, D3DDEVTYPE DeviceType, D3DFORMAT AdapterFormat,
240                                                        D3DFORMAT RenderTargetFormat, D3DFORMAT DepthStencilFormat) {
241     IDirect3D8Impl *This = (IDirect3D8Impl *)iface;
242     HRESULT hr;
243     TRACE("(%p)-<(%d, %d, %d, %d, %d)\n", This, Adapter, DeviceType, AdapterFormat, RenderTargetFormat, DepthStencilFormat);
244
245     EnterCriticalSection(&d3d8_cs);
246     hr = IWineD3D_CheckDepthStencilMatch(This->WineD3D, Adapter, DeviceType,
247             wined3dformat_from_d3dformat(AdapterFormat), wined3dformat_from_d3dformat(RenderTargetFormat),
248             wined3dformat_from_d3dformat(DepthStencilFormat));
249     LeaveCriticalSection(&d3d8_cs);
250     return hr;
251 }
252
253 void fixup_caps(WINED3DCAPS *caps)
254 {
255     /* D3D8 doesn't support SM 2.0 or higher, so clamp to 1.x */
256     if (caps->PixelShaderVersion > D3DPS_VERSION(1,4)) {
257         caps->PixelShaderVersion = D3DPS_VERSION(1,4);
258     }
259     if (caps->VertexShaderVersion > D3DVS_VERSION(1,1)) {
260         caps->VertexShaderVersion = D3DVS_VERSION(1,1);
261     }
262     caps->MaxVertexShaderConst = min(D3D8_MAX_VERTEX_SHADER_CONSTANTF, caps->MaxVertexShaderConst);
263
264     caps->StencilCaps &= ~WINED3DSTENCILCAPS_TWOSIDED;
265 }
266
267 static HRESULT  WINAPI  IDirect3D8Impl_GetDeviceCaps(LPDIRECT3D8 iface, UINT Adapter, D3DDEVTYPE DeviceType, D3DCAPS8* pCaps) {
268     IDirect3D8Impl *This = (IDirect3D8Impl *)iface;
269     HRESULT hrc = D3D_OK;
270     WINED3DCAPS *pWineCaps;
271
272     TRACE("(%p) Relay %d %u %p\n", This, Adapter, DeviceType, pCaps);
273
274     if(NULL == pCaps){
275         return D3DERR_INVALIDCALL;
276     }
277     pWineCaps = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(WINED3DCAPS));
278     if(pWineCaps == NULL){
279         return D3DERR_INVALIDCALL; /*well this is what MSDN says to return*/
280     }
281     EnterCriticalSection(&d3d8_cs);
282     hrc = IWineD3D_GetDeviceCaps(This->WineD3D, Adapter, DeviceType, pWineCaps);
283     LeaveCriticalSection(&d3d8_cs);
284     fixup_caps(pWineCaps);
285     WINECAPSTOD3D8CAPS(pCaps, pWineCaps)
286     HeapFree(GetProcessHeap(), 0, pWineCaps);
287
288     TRACE("(%p) returning %p\n", This, pCaps);
289     return hrc;
290 }
291
292 static HMONITOR WINAPI  IDirect3D8Impl_GetAdapterMonitor(LPDIRECT3D8 iface, UINT Adapter) {
293     IDirect3D8Impl *This = (IDirect3D8Impl *)iface;
294     HMONITOR ret;
295     TRACE("(%p)->(%d)\n", This, Adapter);
296
297     EnterCriticalSection(&d3d8_cs);
298     ret = IWineD3D_GetAdapterMonitor(This->WineD3D, Adapter);
299     LeaveCriticalSection(&d3d8_cs);
300     return ret;
301 }
302
303 ULONG WINAPI D3D8CB_DestroyRenderTarget(IWineD3DSurface *pSurface) {
304     IDirect3DSurface8Impl* surfaceParent;
305     TRACE("(%p) call back\n", pSurface);
306
307     IWineD3DSurface_GetParent(pSurface, (IUnknown **) &surfaceParent);
308     surfaceParent->isImplicit = FALSE;
309     /* Surface had refcount of 0 GetParent addrefed to 1, so 1 Release is enough */
310     return IDirect3DSurface8_Release((IDirect3DSurface8*) surfaceParent);
311 }
312
313 ULONG WINAPI D3D8CB_DestroySwapChain(IWineD3DSwapChain *pSwapChain) {
314     IUnknown* swapChainParent;
315     TRACE("(%p) call back\n", pSwapChain);
316
317     IWineD3DSwapChain_GetParent(pSwapChain, &swapChainParent);
318     IUnknown_Release(swapChainParent);
319     return IUnknown_Release(swapChainParent);
320 }
321
322 ULONG WINAPI D3D8CB_DestroyDepthStencilSurface(IWineD3DSurface *pSurface) {
323     IDirect3DSurface8Impl* surfaceParent;
324     TRACE("(%p) call back\n", pSurface);
325
326     IWineD3DSurface_GetParent(pSurface, (IUnknown **) &surfaceParent);
327     surfaceParent->isImplicit = FALSE;
328     /* Surface had refcount of 0 GetParent addrefed to 1, so 1 Release is enough */
329     return IDirect3DSurface8_Release((IDirect3DSurface8*) surfaceParent);
330 }
331
332 static HRESULT WINAPI IDirect3D8Impl_CreateDevice(LPDIRECT3D8 iface, UINT Adapter, D3DDEVTYPE DeviceType, HWND hFocusWindow,
333                                             DWORD BehaviourFlags, D3DPRESENT_PARAMETERS* pPresentationParameters,
334                                             IDirect3DDevice8** ppReturnedDeviceInterface) {
335
336     IDirect3D8Impl       *This   = (IDirect3D8Impl *)iface;
337     IDirect3DDevice8Impl *object = NULL;
338     WINED3DPRESENT_PARAMETERS localParameters;
339     HRESULT hr;
340     TRACE("(%p) Relay\n", This);
341
342     /* Check the validity range of the adapter parameter */
343     if (Adapter >= IDirect3D8Impl_GetAdapterCount(iface)) {
344         *ppReturnedDeviceInterface = NULL;
345         return D3DERR_INVALIDCALL;
346     }
347
348     /* Allocate the storage for the device object */
349     object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DDevice8Impl));
350     if (NULL == object) {
351         FIXME("Allocation of memory failed\n");
352         *ppReturnedDeviceInterface = NULL;
353         return D3DERR_OUTOFVIDEOMEMORY;
354     }
355
356     object->lpVtbl = &Direct3DDevice8_Vtbl;
357     object->device_parent_vtbl = &d3d8_wined3d_device_parent_vtbl;
358     object->ref = 1;
359     object->handle_table.entries = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
360             D3D8_INITIAL_HANDLE_TABLE_SIZE * sizeof(*object->handle_table.entries));
361     object->handle_table.table_size = D3D8_INITIAL_HANDLE_TABLE_SIZE;
362     *ppReturnedDeviceInterface = (IDirect3DDevice8 *)object;
363
364     /* Allocate an associated WineD3DDevice object */
365     EnterCriticalSection(&d3d8_cs);
366     hr = IWineD3D_CreateDevice(This->WineD3D, Adapter, DeviceType, hFocusWindow, BehaviourFlags,
367             (IUnknown *)object, (IWineD3DDeviceParent *)&object->device_parent_vtbl, &object->WineD3DDevice);
368
369     if (hr != D3D_OK) {
370         HeapFree(GetProcessHeap(), 0, object);
371         *ppReturnedDeviceInterface = NULL;
372         LeaveCriticalSection(&d3d8_cs);
373         return hr;
374     }
375
376     TRACE("(%p) : Created Device %p\n", This, object);
377
378     localParameters.BackBufferWidth                             = pPresentationParameters->BackBufferWidth;
379     localParameters.BackBufferHeight                            = pPresentationParameters->BackBufferHeight;
380     localParameters.BackBufferFormat                            = wined3dformat_from_d3dformat(pPresentationParameters->BackBufferFormat);
381     localParameters.BackBufferCount                             = pPresentationParameters->BackBufferCount;
382     localParameters.MultiSampleType                             = pPresentationParameters->MultiSampleType;
383     localParameters.MultiSampleQuality                          = 0; /* d3d9 only */
384     localParameters.SwapEffect                                  = pPresentationParameters->SwapEffect;
385     localParameters.hDeviceWindow                               = pPresentationParameters->hDeviceWindow;
386     localParameters.Windowed                                    = pPresentationParameters->Windowed;
387     localParameters.EnableAutoDepthStencil                      = pPresentationParameters->EnableAutoDepthStencil;
388     localParameters.AutoDepthStencilFormat                      = wined3dformat_from_d3dformat(pPresentationParameters->AutoDepthStencilFormat);
389     localParameters.Flags                                       = pPresentationParameters->Flags;
390     localParameters.FullScreen_RefreshRateInHz                  = pPresentationParameters->FullScreen_RefreshRateInHz;
391     localParameters.PresentationInterval                        = pPresentationParameters->FullScreen_PresentationInterval;
392     localParameters.AutoRestoreDisplayMode                      = TRUE;
393
394     if(BehaviourFlags & D3DCREATE_MULTITHREADED) {
395         IWineD3DDevice_SetMultithreaded(object->WineD3DDevice);
396     }
397
398     hr = IWineD3DDevice_Init3D(object->WineD3DDevice, &localParameters);
399     LeaveCriticalSection(&d3d8_cs);
400
401     pPresentationParameters->BackBufferWidth                    = localParameters.BackBufferWidth;
402     pPresentationParameters->BackBufferHeight                   = localParameters.BackBufferHeight;
403     pPresentationParameters->BackBufferFormat                   = d3dformat_from_wined3dformat(localParameters.BackBufferFormat);
404     pPresentationParameters->BackBufferCount                    = localParameters.BackBufferCount;
405     pPresentationParameters->MultiSampleType                    = localParameters.MultiSampleType;
406     pPresentationParameters->SwapEffect                         = localParameters.SwapEffect;
407     pPresentationParameters->hDeviceWindow                      = localParameters.hDeviceWindow;
408     pPresentationParameters->Windowed                           = localParameters.Windowed;
409     pPresentationParameters->EnableAutoDepthStencil             = localParameters.EnableAutoDepthStencil;
410     pPresentationParameters->AutoDepthStencilFormat             = d3dformat_from_wined3dformat(localParameters.AutoDepthStencilFormat);
411     pPresentationParameters->Flags                              = localParameters.Flags;
412     pPresentationParameters->FullScreen_RefreshRateInHz         = localParameters.FullScreen_RefreshRateInHz;
413     pPresentationParameters->FullScreen_PresentationInterval    = localParameters.PresentationInterval;
414
415     if (hr != D3D_OK) {
416         FIXME("(%p) D3D Initialization failed for WineD3DDevice %p\n", This, object->WineD3DDevice);
417         HeapFree(GetProcessHeap(), 0, object);
418         *ppReturnedDeviceInterface = NULL;
419     }
420
421     object->declArraySize = 16;
422     object->decls = HeapAlloc(GetProcessHeap(), 0, object->declArraySize * sizeof(*object->decls));
423     if(!object->decls) {
424         ERR("Out of memory\n");
425         EnterCriticalSection(&d3d8_cs);
426         IWineD3DDevice_Release(object->WineD3DDevice);
427         LeaveCriticalSection(&d3d8_cs);
428         HeapFree(GetProcessHeap(), 0, object);
429         *ppReturnedDeviceInterface = NULL;
430         hr = E_OUTOFMEMORY;
431     }
432     return hr;
433 }
434
435 const IDirect3D8Vtbl Direct3D8_Vtbl =
436 {
437     /* IUnknown */
438     IDirect3D8Impl_QueryInterface,
439     IDirect3D8Impl_AddRef,
440     IDirect3D8Impl_Release,
441     /* IDirect3D8 */
442     IDirect3D8Impl_RegisterSoftwareDevice,
443     IDirect3D8Impl_GetAdapterCount,
444     IDirect3D8Impl_GetAdapterIdentifier,
445     IDirect3D8Impl_GetAdapterModeCount,
446     IDirect3D8Impl_EnumAdapterModes,
447     IDirect3D8Impl_GetAdapterDisplayMode,
448     IDirect3D8Impl_CheckDeviceType,
449     IDirect3D8Impl_CheckDeviceFormat,
450     IDirect3D8Impl_CheckDeviceMultiSampleType,
451     IDirect3D8Impl_CheckDepthStencilMatch,
452     IDirect3D8Impl_GetDeviceCaps,
453     IDirect3D8Impl_GetAdapterMonitor,
454     IDirect3D8Impl_CreateDevice
455 };