wined3d: Move over to WGL.
[wine] / dlls / wined3d / directx.c
1 /*
2  * IWineD3D implementation
3  *
4  * Copyright 2002-2004 Jason Edmeades
5  * Copyright 2003-2004 Raphael Junqueira
6  * Copyright 2004 Christian Costa
7  * Copyright 2005 Oliver Stieber
8  *
9  * This library is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License as published by the Free Software Foundation; either
12  * version 2.1 of the License, or (at your option) any later version.
13  *
14  * This library is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with this library; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22  */
23
24 /* Compile time diagnostics: */
25
26 #ifndef DEBUG_SINGLE_MODE
27 /* Set to 1 to force only a single display mode to be exposed: */
28 #define DEBUG_SINGLE_MODE 0
29 #endif
30
31
32 #include "config.h"
33 #include <assert.h>
34 #include "wined3d_private.h"
35
36 WINE_DEFAULT_DEBUG_CHANNEL(d3d);
37 WINE_DECLARE_DEBUG_CHANNEL(d3d_caps);
38
39 /* Extension detection */
40 static const struct {
41     const char *extension_string;
42     GL_SupportedExt extension;
43 } EXTENSION_MAP[] = {
44     /* APPLE */
45     {"GL_APPLE_client_storage",             APPLE_CLIENT_STORAGE},
46     {"GL_APPLE_fence",                      APPLE_FENCE},
47
48     /* ATI */
49     {"GL_ATI_separate_stencil",             ATI_SEPARATE_STENCIL},
50     {"GL_ATI_texture_env_combine3",         ATI_TEXTURE_ENV_COMBINE3},
51     {"GL_ATI_texture_mirror_once",          ATI_TEXTURE_MIRROR_ONCE},
52     {"GL_ATI_envmap_bumpmap",               ATI_ENVMAP_BUMPMAP},
53
54     /* ARB */
55     {"GL_ARB_draw_buffers",                 ARB_DRAW_BUFFERS},
56     {"GL_ARB_fragment_program",             ARB_FRAGMENT_PROGRAM},
57     {"GL_ARB_fragment_shader",              ARB_FRAGMENT_SHADER},
58     {"GL_ARB_half_float_pixel",             ARB_HALF_FLOAT_PIXEL},
59     {"GL_ARB_imaging",                      ARB_IMAGING},
60     {"GL_ARB_multisample",                  ARB_MULTISAMPLE}, /* needs GLX_ARB_MULTISAMPLE as well */
61     {"GL_ARB_multitexture",                 ARB_MULTITEXTURE},
62     {"GL_ARB_occlusion_query",              ARB_OCCLUSION_QUERY},
63     {"GL_ARB_pixel_buffer_object",          ARB_PIXEL_BUFFER_OBJECT},
64     {"GL_ARB_point_parameters",             ARB_POINT_PARAMETERS},
65     {"GL_ARB_point_sprite",                 ARB_POINT_SPRITE},
66     {"GL_ARB_texture_border_clamp",         ARB_TEXTURE_BORDER_CLAMP},
67     {"GL_ARB_texture_compression",          ARB_TEXTURE_COMPRESSION},
68     {"GL_ARB_texture_cube_map",             ARB_TEXTURE_CUBE_MAP},
69     {"GL_ARB_texture_env_add",              ARB_TEXTURE_ENV_ADD},
70     {"GL_ARB_texture_env_combine",          ARB_TEXTURE_ENV_COMBINE},
71     {"GL_ARB_texture_env_dot3",             ARB_TEXTURE_ENV_DOT3},
72     {"GL_ARB_texture_float",                ARB_TEXTURE_FLOAT},
73     {"GL_ARB_texture_mirrored_repeat",      ARB_TEXTURE_MIRRORED_REPEAT},
74     {"GL_ARB_texture_non_power_of_two",     ARB_TEXTURE_NON_POWER_OF_TWO},
75     {"GL_ARB_vertex_blend",                 ARB_VERTEX_BLEND},
76     {"GL_ARB_vertex_buffer_object",         ARB_VERTEX_BUFFER_OBJECT},
77     {"GL_ARB_vertex_program",               ARB_VERTEX_PROGRAM},
78     {"GL_ARB_vertex_shader",                ARB_VERTEX_SHADER},
79
80     /* EXT */
81     {"GL_EXT_blend_minmax",                 EXT_BLEND_MINMAX},
82     {"GL_EXT_fog_coord",                    EXT_FOG_COORD},
83     {"GL_EXT_framebuffer_blit",             EXT_FRAMEBUFFER_BLIT},
84     {"GL_EXT_framebuffer_object",           EXT_FRAMEBUFFER_OBJECT},
85     {"GL_EXT_paletted_texture",             EXT_PALETTED_TEXTURE},
86     {"GL_EXT_point_parameters",             EXT_POINT_PARAMETERS},
87     {"GL_EXT_secondary_color",              EXT_SECONDARY_COLOR},
88     {"GL_EXT_stencil_two_side",             EXT_STENCIL_TWO_SIDE},
89     {"GL_EXT_stencil_wrap",                 EXT_STENCIL_WRAP},
90     {"GL_EXT_texture3D",                    EXT_TEXTURE3D},
91     {"GL_EXT_texture_compression_s3tc",     EXT_TEXTURE_COMPRESSION_S3TC},
92     {"GL_EXT_texture_env_add",              EXT_TEXTURE_ENV_ADD},
93     {"GL_EXT_texture_env_combine",          EXT_TEXTURE_ENV_COMBINE},
94     {"GL_EXT_texture_env_dot3",             EXT_TEXTURE_ENV_DOT3},
95     {"GL_EXT_texture_sRGB",                 EXT_TEXTURE_SRGB},
96     {"GL_EXT_texture_filter_anisotropic",   EXT_TEXTURE_FILTER_ANISOTROPIC},
97     {"GL_EXT_texture_lod",                  EXT_TEXTURE_LOD},
98     {"GL_EXT_texture_lod_bias",             EXT_TEXTURE_LOD_BIAS},
99     {"GL_EXT_vertex_shader",                EXT_VERTEX_SHADER},
100     {"GL_EXT_vertex_weighting",             EXT_VERTEX_WEIGHTING},
101
102     /* NV */
103     {"GL_NV_half_float",                    NV_HALF_FLOAT},
104     {"GL_NV_fence",                         NV_FENCE},
105     {"GL_NV_fog_distance",                  NV_FOG_DISTANCE},
106     {"GL_NV_fragment_program",              NV_FRAGMENT_PROGRAM},
107     {"GL_NV_fragment_program2",             NV_FRAGMENT_PROGRAM2},
108     {"GL_NV_register_combiners",            NV_REGISTER_COMBINERS},
109     {"GL_NV_register_combiners2",           NV_REGISTER_COMBINERS2},
110     {"GL_NV_texgen_reflection",             NV_TEXGEN_REFLECTION},
111     {"GL_NV_texture_env_combine4",          NV_TEXTURE_ENV_COMBINE4},
112     {"GL_NV_texture_shader",                NV_TEXTURE_SHADER},
113     {"GL_NV_texture_shader2",               NV_TEXTURE_SHADER2},
114     {"GL_NV_texture_shader3",               NV_TEXTURE_SHADER3},
115     {"GL_NV_occlusion_query",               NV_OCCLUSION_QUERY},
116     {"GL_NV_vertex_program",                NV_VERTEX_PROGRAM},
117     {"GL_NV_vertex_program1_1",             NV_VERTEX_PROGRAM1_1},
118     {"GL_NV_vertex_program2",               NV_VERTEX_PROGRAM2},
119     {"GL_NV_vertex_program3",               NV_VERTEX_PROGRAM3},
120 };
121
122 /**********************************************************
123  * Utility functions follow
124  **********************************************************/
125
126 /* Adapters */
127 static int numAdapters = 0;
128 static struct WineD3DAdapter Adapters[1];
129
130 /* lookup tables */
131 int minLookup[MAX_LOOKUPS];
132 int maxLookup[MAX_LOOKUPS];
133 DWORD *stateLookup[MAX_LOOKUPS];
134
135 DWORD minMipLookup[WINED3DTEXF_ANISOTROPIC + 1][WINED3DTEXF_LINEAR + 1];
136
137
138 /**
139  * Note: GL seems to trap if GetDeviceCaps is called before any HWND's created
140  * ie there is no GL Context - Get a default rendering context to enable the
141  * function query some info from GL
142  */
143
144 static int             wined3d_fake_gl_context_ref = 0;
145 static BOOL            wined3d_fake_gl_context_foreign;
146 static BOOL            wined3d_fake_gl_context_available = FALSE;
147 static HDC             wined3d_fake_gl_context_hdc = NULL;
148 static HWND            wined3d_fake_gl_context_hwnd = NULL;
149
150 static CRITICAL_SECTION wined3d_fake_gl_context_cs;
151 static CRITICAL_SECTION_DEBUG wined3d_fake_gl_context_cs_debug =
152 {
153     0, 0, &wined3d_fake_gl_context_cs,
154     { &wined3d_fake_gl_context_cs_debug.ProcessLocksList,
155       &wined3d_fake_gl_context_cs_debug.ProcessLocksList },
156     0, 0, { (DWORD_PTR)(__FILE__ ": wined3d_fake_gl_context_cs") }
157 };
158 static CRITICAL_SECTION wined3d_fake_gl_context_cs = { &wined3d_fake_gl_context_cs_debug, -1, 0, 0, 0, 0 };
159
160 static void WineD3D_ReleaseFakeGLContext(void) {
161     HGLRC glCtx;
162
163     EnterCriticalSection(&wined3d_fake_gl_context_cs);
164
165     if(!wined3d_fake_gl_context_available) {
166         TRACE_(d3d_caps)("context not available\n");
167         LeaveCriticalSection(&wined3d_fake_gl_context_cs);
168         return;
169     }
170
171     glCtx = wglGetCurrentContext();
172
173     TRACE_(d3d_caps)("decrementing ref from %i\n", wined3d_fake_gl_context_ref);
174     if (0 == (--wined3d_fake_gl_context_ref) ) {
175         if(!wined3d_fake_gl_context_foreign && glCtx) {
176             TRACE_(d3d_caps)("destroying fake GL context\n");
177             wglMakeCurrent(NULL, NULL);
178             wglDeleteContext(glCtx);
179         }
180         if(wined3d_fake_gl_context_hdc)
181             ReleaseDC(wined3d_fake_gl_context_hwnd, wined3d_fake_gl_context_hdc);
182         wined3d_fake_gl_context_hdc = NULL; /* Make sure we don't think that it is still around */
183         if(wined3d_fake_gl_context_hwnd)
184             DestroyWindow(wined3d_fake_gl_context_hwnd);
185         wined3d_fake_gl_context_hwnd = NULL;
186         wined3d_fake_gl_context_available = FALSE;
187     }
188     assert(wined3d_fake_gl_context_ref >= 0);
189
190     LeaveCriticalSection(&wined3d_fake_gl_context_cs);
191     LEAVE_GL();
192 }
193
194 static BOOL WineD3D_CreateFakeGLContext(void) {
195     HGLRC glCtx = NULL;
196
197     ENTER_GL();
198     EnterCriticalSection(&wined3d_fake_gl_context_cs);
199
200     TRACE("getting context...\n");
201     if(wined3d_fake_gl_context_ref > 0) goto ret;
202     assert(0 == wined3d_fake_gl_context_ref);
203
204     wined3d_fake_gl_context_foreign = TRUE;
205
206     glCtx = wglGetCurrentContext();
207     if (!glCtx) {
208         PIXELFORMATDESCRIPTOR pfd;
209         int iPixelFormat;
210
211         wined3d_fake_gl_context_foreign = FALSE;
212
213         /* We need a fake window as a hdc retrieved using GetDC(0) can't be used for much GL purposes */
214         wined3d_fake_gl_context_hwnd = CreateWindowA("WineD3D_OpenGL", "WineD3D fake window", WS_OVERLAPPEDWINDOW,        10, 10, 10, 10, NULL, NULL, NULL, NULL);
215         if(!wined3d_fake_gl_context_hwnd) {
216             ERR("HWND creation failed!\n");
217             goto fail;
218         }
219         wined3d_fake_gl_context_hdc = GetDC(wined3d_fake_gl_context_hwnd);
220         if(!wined3d_fake_gl_context_hdc) {
221             ERR("GetDC failed!\n");
222             goto fail;
223         }
224
225         /* PixelFormat selection */
226         ZeroMemory(&pfd, sizeof(pfd));
227         pfd.nSize      = sizeof(pfd);
228         pfd.nVersion   = 1;
229         pfd.dwFlags    = PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER | PFD_DRAW_TO_WINDOW;/*PFD_GENERIC_ACCELERATED*/
230         pfd.iPixelType = PFD_TYPE_RGBA;
231         pfd.cColorBits = 32;
232         pfd.iLayerType = PFD_MAIN_PLANE;
233
234         iPixelFormat = ChoosePixelFormat(wined3d_fake_gl_context_hdc, &pfd);
235         if(!iPixelFormat) {
236             /* If this happens something is very wrong as ChoosePixelFormat barely fails */
237             ERR("Can't find a suitable iPixelFormat\n");
238             goto fail;
239         }
240         DescribePixelFormat(wined3d_fake_gl_context_hdc, iPixelFormat, sizeof(pfd), &pfd);
241         SetPixelFormat(wined3d_fake_gl_context_hdc, iPixelFormat, &pfd);
242
243         /* Create a GL context */
244         glCtx = wglCreateContext(wined3d_fake_gl_context_hdc);
245         if (!glCtx) {
246             WARN_(d3d_caps)("Error creating default context for capabilities initialization\n");
247             goto fail;
248         }
249
250         /* Make it the current GL context */
251         if (!wglMakeCurrent(wined3d_fake_gl_context_hdc, glCtx)) {
252             WARN_(d3d_caps)("Error setting default context as current for capabilities initialization\n");
253             goto fail;
254         }
255     }
256
257   ret:
258     TRACE("incrementing ref from %i\n", wined3d_fake_gl_context_ref);
259     wined3d_fake_gl_context_ref++;
260     wined3d_fake_gl_context_available = TRUE;
261     LeaveCriticalSection(&wined3d_fake_gl_context_cs);
262     return TRUE;
263   fail:
264     if(wined3d_fake_gl_context_hdc)
265         ReleaseDC(wined3d_fake_gl_context_hwnd, wined3d_fake_gl_context_hdc);
266     wined3d_fake_gl_context_hdc = NULL;
267     if(wined3d_fake_gl_context_hwnd)
268         DestroyWindow(wined3d_fake_gl_context_hwnd);
269     wined3d_fake_gl_context_hwnd = NULL;
270     if(glCtx) wglDeleteContext(glCtx);
271     LeaveCriticalSection(&wined3d_fake_gl_context_cs);
272     LEAVE_GL();
273     return FALSE;
274 }
275
276
277 /**********************************************************
278  * IUnknown parts follows
279  **********************************************************/
280
281 static HRESULT WINAPI IWineD3DImpl_QueryInterface(IWineD3D *iface,REFIID riid,LPVOID *ppobj)
282 {
283     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
284
285     TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(riid),ppobj);
286     if (IsEqualGUID(riid, &IID_IUnknown)
287         || IsEqualGUID(riid, &IID_IWineD3DBase)
288         || IsEqualGUID(riid, &IID_IWineD3DDevice)) {
289         IUnknown_AddRef(iface);
290         *ppobj = This;
291         return S_OK;
292     }
293     *ppobj = NULL;
294     return E_NOINTERFACE;
295 }
296
297 static ULONG WINAPI IWineD3DImpl_AddRef(IWineD3D *iface) {
298     IWineD3DImpl *This = (IWineD3DImpl *)iface;
299     ULONG refCount = InterlockedIncrement(&This->ref);
300
301     TRACE("(%p) : AddRef increasing from %d\n", This, refCount - 1);
302     return refCount;
303 }
304
305 static ULONG WINAPI IWineD3DImpl_Release(IWineD3D *iface) {
306     IWineD3DImpl *This = (IWineD3DImpl *)iface;
307     ULONG ref;
308     TRACE("(%p) : Releasing from %d\n", This, This->ref);
309     ref = InterlockedDecrement(&This->ref);
310     if (ref == 0) {
311         HeapFree(GetProcessHeap(), 0, This);
312     }
313
314     return ref;
315 }
316
317 /* Set the shader type for this device, depending on the given capabilities,
318  * the device type, and the user preferences in wined3d_settings */
319
320 static void select_shader_mode(
321     WineD3D_GL_Info *gl_info,
322     WINED3DDEVTYPE DeviceType,
323     int* ps_selected,
324     int* vs_selected) {
325
326     if (wined3d_settings.vs_mode == VS_NONE) {
327         *vs_selected = SHADER_NONE;
328     } else if (gl_info->supported[ARB_VERTEX_SHADER] && wined3d_settings.glslRequested) {
329         *vs_selected = SHADER_GLSL;
330     } else if (gl_info->supported[ARB_VERTEX_PROGRAM]) {
331         *vs_selected = SHADER_ARB;
332     } else {
333         *vs_selected = SHADER_NONE;
334     }
335
336     if (wined3d_settings.ps_mode == PS_NONE) {
337         *ps_selected = SHADER_NONE;
338     } else if (gl_info->supported[ARB_FRAGMENT_SHADER] && wined3d_settings.glslRequested) {
339         *ps_selected = SHADER_GLSL;
340     } else if (gl_info->supported[ARB_FRAGMENT_PROGRAM]) {
341         *ps_selected = SHADER_ARB;
342     } else {
343         *ps_selected = SHADER_NONE;
344     }
345 }
346
347 /** Select the number of report maximum shader constants based on the selected shader modes */
348 static void select_shader_max_constants(
349     int ps_selected_mode,
350     int vs_selected_mode,
351     WineD3D_GL_Info *gl_info) {
352
353     switch (vs_selected_mode) {
354         case SHADER_GLSL:
355             /* Subtract the other potential uniforms from the max available (bools, ints, and 1 row of projection matrix) */
356             gl_info->max_vshader_constantsF = gl_info->vs_glsl_constantsF - (MAX_CONST_B / 4) - MAX_CONST_I - 1;
357             break;
358         case SHADER_ARB:
359             /* We have to subtract any other PARAMs that we might use in our shader programs.
360              * ATI seems to count 2 implicit PARAMs when we use fog and NVIDIA counts 1,
361              * and we reference one row of the PROJECTION matrix which counts as 1 PARAM. */
362             gl_info->max_vshader_constantsF = gl_info->vs_arb_constantsF - 3;
363             break;
364         default:
365             gl_info->max_vshader_constantsF = 0;
366             break;
367     }
368
369     switch (ps_selected_mode) {
370         case SHADER_GLSL:
371             /* Subtract the other potential uniforms from the max available (bools & ints), and 2 states for fog.
372              * In theory the texbem instruction may need one more shader constant too. But lets assume
373              * that a sm <= 1.3 shader does not need all the uniforms provided by a glsl-capable card,
374              * and lets not take away a uniform needlessly from all other shaders.
375              */
376             gl_info->max_pshader_constantsF = gl_info->ps_glsl_constantsF - (MAX_CONST_B / 4) - MAX_CONST_I - 2;
377             break;
378         case SHADER_ARB:
379             /* The arb shader only loads the bump mapping environment matrix into the shader if it finds
380              * a free constant to do that, so only reduce the number of available constants by 2 for the fog states.
381              */
382             gl_info->max_pshader_constantsF = gl_info->ps_arb_constantsF - 2;
383             break;
384         default:
385             gl_info->max_pshader_constantsF = 0;
386             break;
387     }
388 }
389
390 /**********************************************************
391  * IWineD3D parts follows
392  **********************************************************/
393
394 #define GLINFO_LOCATION (*gl_info)
395 BOOL IWineD3DImpl_FillGLCaps(WineD3D_GL_Info *gl_info) {
396     const char *GL_Extensions    = NULL;
397     const char *WGL_Extensions   = NULL;
398     const char *gl_string        = NULL;
399     const char *gl_string_cursor = NULL;
400     GLint       gl_max;
401     GLfloat     gl_floatv[2];
402     int         major = 1, minor = 0;
403     BOOL        return_value = TRUE;
404     int         i;
405     HDC         hdc;
406     HMODULE     mod_gl;
407     PROC        (WINAPI *p_wglGetProcAddress)(LPCSTR  lpszProc);
408
409     /* Make sure that we've got a context */
410     /* TODO: CreateFakeGLContext should really take a display as a parameter  */
411     /* Only save the values obtained when a display is provided */
412     if (!WineD3D_CreateFakeGLContext() || wined3d_fake_gl_context_foreign)
413         return_value = FALSE;
414
415     TRACE_(d3d_caps)("(%p)\n", gl_info);
416
417     gl_string = (const char *) glGetString(GL_RENDERER);
418     if (NULL == gl_string)
419         gl_string = "None";
420     strcpy(gl_info->gl_renderer, gl_string);
421
422     gl_string = (const char *) glGetString(GL_VENDOR);
423     TRACE_(d3d_caps)("Filling vendor string %s\n", gl_string);
424     if (gl_string != NULL) {
425         /* Fill in the GL vendor */
426         if (strstr(gl_string, "NVIDIA")) {
427             gl_info->gl_vendor = VENDOR_NVIDIA;
428         } else if (strstr(gl_string, "ATI")) {
429             gl_info->gl_vendor = VENDOR_ATI;
430         } else if (strstr(gl_string, "Intel(R)") || 
431                    strstr(gl_info->gl_renderer, "Intel(R)")) {
432             gl_info->gl_vendor = VENDOR_INTEL;
433         } else if (strstr(gl_string, "Mesa")) {
434             gl_info->gl_vendor = VENDOR_MESA;
435         } else {
436             gl_info->gl_vendor = VENDOR_WINE;
437         }
438     } else {
439         gl_info->gl_vendor = VENDOR_WINE;
440     }
441
442
443     TRACE_(d3d_caps)("found GL_VENDOR (%s)->(0x%04x)\n", debugstr_a(gl_string), gl_info->gl_vendor);
444
445     /* Parse the GL_VERSION field into major and minor information */
446     gl_string = (const char *) glGetString(GL_VERSION);
447     if (gl_string != NULL) {
448
449         switch (gl_info->gl_vendor) {
450         case VENDOR_NVIDIA:
451             gl_string_cursor = strstr(gl_string, "NVIDIA");
452             if (!gl_string_cursor) {
453                 ERR_(d3d_caps)("Invalid nVidia version string: %s\n", debugstr_a(gl_string));
454                 break;
455             }
456
457             gl_string_cursor = strstr(gl_string_cursor, " ");
458             if (!gl_string_cursor) {
459                 ERR_(d3d_caps)("Invalid nVidia version string: %s\n", debugstr_a(gl_string));
460                 break;
461             }
462
463             while (*gl_string_cursor == ' ') {
464                 ++gl_string_cursor;
465             }
466
467             if (!*gl_string_cursor) {
468                 ERR_(d3d_caps)("Invalid nVidia version string: %s\n", debugstr_a(gl_string));
469                 break;
470             }
471
472             major = atoi(gl_string_cursor);
473             while (*gl_string_cursor <= '9' && *gl_string_cursor >= '0') {
474                 ++gl_string_cursor;
475             }
476
477             if (*gl_string_cursor++ != '.') {
478                 ERR_(d3d_caps)("Invalid nVidia version string: %s\n", debugstr_a(gl_string));
479                 break;
480             }
481
482             minor = atoi(gl_string_cursor);
483             minor = major*100+minor;
484             major = 10;
485
486             break;
487
488         case VENDOR_ATI:
489             major = minor = 0;
490             gl_string_cursor = strchr(gl_string, '-');
491             if (gl_string_cursor) {
492                 int error = 0;
493                 gl_string_cursor++;
494
495                 /* Check if version number is of the form x.y.z */
496                 if (*gl_string_cursor > '9' && *gl_string_cursor < '0')
497                     error = 1;
498                 if (!error && *(gl_string_cursor+2) > '9' && *(gl_string_cursor+2) < '0')
499                     error = 1;
500                 if (!error && *(gl_string_cursor+4) > '9' && *(gl_string_cursor+4) < '0')
501                     error = 1;
502                 if (!error && *(gl_string_cursor+1) != '.' && *(gl_string_cursor+3) != '.')
503                     error = 1;
504
505                 /* Mark version number as malformed */
506                 if (error)
507                     gl_string_cursor = 0;
508             }
509
510             if (!gl_string_cursor)
511                 WARN_(d3d_caps)("malformed GL_VERSION (%s)\n", debugstr_a(gl_string));
512             else {
513                 major = *gl_string_cursor - '0';
514                 minor = (*(gl_string_cursor+2) - '0') * 256 + (*(gl_string_cursor+4) - '0');
515             }
516             break;
517
518         case VENDOR_INTEL:
519         case VENDOR_MESA:
520             gl_string_cursor = strstr(gl_string, "Mesa");
521             gl_string_cursor = strstr(gl_string_cursor, " ");
522             while (*gl_string_cursor && ' ' == *gl_string_cursor) ++gl_string_cursor;
523             if (*gl_string_cursor) {
524                 char tmp[16];
525                 int cursor = 0;
526
527                 while (*gl_string_cursor <= '9' && *gl_string_cursor >= '0') {
528                     tmp[cursor++] = *gl_string_cursor;
529                     ++gl_string_cursor;
530                 }
531                 tmp[cursor] = 0;
532                 major = atoi(tmp);
533
534                 if (*gl_string_cursor != '.') WARN_(d3d_caps)("malformed GL_VERSION (%s)\n", debugstr_a(gl_string));
535                 ++gl_string_cursor;
536
537                 cursor = 0;
538                 while (*gl_string_cursor <= '9' && *gl_string_cursor >= '0') {
539                     tmp[cursor++] = *gl_string_cursor;
540                     ++gl_string_cursor;
541                 }
542                 tmp[cursor] = 0;
543                 minor = atoi(tmp);
544             }
545             break;
546
547         default:
548             major = 0;
549             minor = 9;
550         }
551         gl_info->gl_driver_version = MAKEDWORD_VERSION(major, minor);
552         TRACE_(d3d_caps)("found GL_VERSION  (%s)->%i.%i->(0x%08x)\n", debugstr_a(gl_string), major, minor, gl_info->gl_driver_version);
553     }
554
555     TRACE_(d3d_caps)("found GL_RENDERER (%s)->(0x%04x)\n", debugstr_a(gl_info->gl_renderer), gl_info->gl_card);
556
557     /*
558      * Initialize openGL extension related variables
559      *  with Default values
560      */
561     memset(&gl_info->supported, 0, sizeof(gl_info->supported));
562     gl_info->max_buffers        = 1;
563     gl_info->max_textures       = 1;
564     gl_info->max_texture_stages = 1;
565     gl_info->max_fragment_samplers = 1;
566     gl_info->max_vertex_samplers = 0;
567     gl_info->max_combined_samplers = 0;
568     gl_info->max_sampler_stages = 1;
569     gl_info->ps_arb_version = PS_VERSION_NOT_SUPPORTED;
570     gl_info->ps_arb_max_temps = 0;
571     gl_info->ps_arb_max_instructions = 0;
572     gl_info->vs_arb_version = VS_VERSION_NOT_SUPPORTED;
573     gl_info->vs_arb_max_temps = 0;
574     gl_info->vs_arb_max_instructions = 0;
575     gl_info->vs_nv_version  = VS_VERSION_NOT_SUPPORTED;
576     gl_info->vs_ati_version = VS_VERSION_NOT_SUPPORTED;
577     gl_info->vs_glsl_constantsF = 0;
578     gl_info->ps_glsl_constantsF = 0;
579     gl_info->vs_arb_constantsF = 0;
580     gl_info->ps_arb_constantsF = 0;
581
582     /* To bypass the opengl32 thunks load wglGetProcAddress from gdi32 (glXGetProcAddress wrapper) instead of opengl32's */
583     mod_gl = LoadLibraryA("gdi32.dll");
584     if(!mod_gl) {
585         ERR("Can't load gdi32.dll!\n");
586         return FALSE;
587     }
588
589     p_wglGetProcAddress = (void*)GetProcAddress(mod_gl, "wglGetProcAddress");
590     if(!p_wglGetProcAddress) {
591         ERR("Unable to load wglGetProcAddress!\n");
592         return FALSE;
593     }
594
595     /* Now work out what GL support this card really has */
596 #define USE_GL_FUNC(type, pfn) gl_info->pfn = (type) p_wglGetProcAddress( (const char *) #pfn);
597     GL_EXT_FUNCS_GEN;
598     WGL_EXT_FUNCS_GEN;
599 #undef USE_GL_FUNC
600
601     /* Retrieve opengl defaults */
602     glGetIntegerv(GL_MAX_CLIP_PLANES, &gl_max);
603     gl_info->max_clipplanes = min(WINED3DMAXUSERCLIPPLANES, gl_max);
604     TRACE_(d3d_caps)("ClipPlanes support - num Planes=%d\n", gl_max);
605
606     glGetIntegerv(GL_MAX_LIGHTS, &gl_max);
607     gl_info->max_lights = gl_max;
608     TRACE_(d3d_caps)("Lights support - max lights=%d\n", gl_max);
609
610     glGetIntegerv(GL_MAX_TEXTURE_SIZE, &gl_max);
611     gl_info->max_texture_size = gl_max;
612     TRACE_(d3d_caps)("Maximum texture size support - max texture size=%d\n", gl_max);
613
614     glGetFloatv(GL_POINT_SIZE_RANGE, gl_floatv);
615     gl_info->max_pointsize = gl_floatv[1];
616     TRACE_(d3d_caps)("Maximum point size support - max point size=%f\n", gl_floatv[1]);
617
618     glGetIntegerv(GL_AUX_BUFFERS, &gl_max);
619     gl_info->max_aux_buffers = gl_max;
620     TRACE_(d3d_caps)("Offscreen rendering support - number of aux buffers=%d\n", gl_max);
621
622     /* Parse the gl supported features, in theory enabling parts of our code appropriately */
623     GL_Extensions = (const char *) glGetString(GL_EXTENSIONS);
624     TRACE_(d3d_caps)("GL_Extensions reported:\n");
625
626     if (NULL == GL_Extensions) {
627         ERR("   GL_Extensions returns NULL\n");
628     } else {
629         while (*GL_Extensions != 0x00) {
630             const char *Start = GL_Extensions;
631             char        ThisExtn[256];
632
633             memset(ThisExtn, 0x00, sizeof(ThisExtn));
634             while (*GL_Extensions != ' ' && *GL_Extensions != 0x00) {
635                 GL_Extensions++;
636             }
637             memcpy(ThisExtn, Start, (GL_Extensions - Start));
638             TRACE_(d3d_caps)("- %s\n", ThisExtn);
639
640             for (i = 0; i < (sizeof(EXTENSION_MAP) / sizeof(*EXTENSION_MAP)); ++i) {
641                 if (!strcmp(ThisExtn, EXTENSION_MAP[i].extension_string)) {
642                     TRACE_(d3d_caps)(" FOUND: %s support\n", EXTENSION_MAP[i].extension_string);
643                     gl_info->supported[EXTENSION_MAP[i].extension] = TRUE;
644                     break;
645                 }
646             }
647
648             if (*GL_Extensions == ' ') GL_Extensions++;
649         }
650
651         if (gl_info->supported[APPLE_FENCE]) {
652             /* GL_NV_fence and GL_APPLE_fence provide the same functionality basically.
653              * The apple extension interacts with some other apple exts. Disable the NV
654              * extension if the apple one is support to prevent confusion in other parts
655              * of the code
656              */
657             gl_info->supported[NV_FENCE] = FALSE;
658         }
659         if (gl_info->supported[ARB_TEXTURE_CUBE_MAP]) {
660             TRACE_(d3d_caps)(" IMPLIED: NVIDIA (NV) Texture Gen Reflection support\n");
661             gl_info->supported[NV_TEXGEN_REFLECTION] = TRUE;
662         }
663         if (gl_info->supported[NV_TEXTURE_SHADER2]) {
664             /* GL_ATI_envmap_bumpmap won't play nice with texture shaders, so disable it
665              * Won't occur in any real world situation though
666              */
667             gl_info->supported[ATI_ENVMAP_BUMPMAP] = FALSE;
668         }
669         if (gl_info->supported[ARB_DRAW_BUFFERS]) {
670             glGetIntegerv(GL_MAX_DRAW_BUFFERS_ARB, &gl_max);
671             gl_info->max_buffers = gl_max;
672             TRACE_(d3d_caps)("Max draw buffers: %u\n", gl_max);
673         }
674         if (gl_info->supported[ARB_MULTITEXTURE]) {
675             glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, &gl_max);
676             gl_info->max_textures = min(MAX_TEXTURES, gl_max);
677             TRACE_(d3d_caps)("Max textures: %d\n", gl_info->max_textures);
678
679             if (gl_info->supported[NV_REGISTER_COMBINERS]) {
680                 GLint tmp;
681                 glGetIntegerv(GL_MAX_GENERAL_COMBINERS_NV, &tmp);
682                 gl_info->max_texture_stages = min(MAX_TEXTURES, tmp);
683             } else {
684                 gl_info->max_texture_stages = min(MAX_TEXTURES, gl_max);
685             }
686             TRACE_(d3d_caps)("Max texture stages: %d\n", gl_info->max_texture_stages);
687
688             if (gl_info->supported[ARB_FRAGMENT_PROGRAM]) {
689                 GLint tmp;
690                 glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS_ARB, &tmp);
691                 gl_info->max_fragment_samplers = min(MAX_FRAGMENT_SAMPLERS, tmp);
692             } else {
693                 gl_info->max_fragment_samplers = max(gl_info->max_fragment_samplers, gl_max);
694             }
695             TRACE_(d3d_caps)("Max fragment samplers: %d\n", gl_info->max_fragment_samplers);
696
697             if (gl_info->supported[ARB_VERTEX_SHADER]) {
698                 GLint tmp;
699                 glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB, &tmp);
700                 gl_info->max_vertex_samplers = tmp;
701                 glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB, &tmp);
702                 gl_info->max_combined_samplers = tmp;
703             } else {
704                 gl_info->max_combined_samplers = gl_info->max_fragment_samplers;
705             }
706             TRACE_(d3d_caps)("Max vertex samplers: %u\n", gl_info->max_vertex_samplers);
707             TRACE_(d3d_caps)("Max combined samplers: %u\n", gl_info->max_combined_samplers);
708         }
709         if (gl_info->supported[ARB_VERTEX_BLEND]) {
710             glGetIntegerv(GL_MAX_VERTEX_UNITS_ARB, &gl_max);
711             gl_info->max_blends = gl_max;
712             TRACE_(d3d_caps)("Max blends: %u\n", gl_info->max_blends);
713         }
714         if (gl_info->supported[EXT_TEXTURE3D]) {
715             glGetIntegerv(GL_MAX_3D_TEXTURE_SIZE_EXT, &gl_max);
716             gl_info->max_texture3d_size = gl_max;
717             TRACE_(d3d_caps)("Max texture3D size: %d\n", gl_info->max_texture3d_size);
718         }
719         if (gl_info->supported[EXT_TEXTURE_FILTER_ANISOTROPIC]) {
720             glGetIntegerv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &gl_max);
721             gl_info->max_anisotropy = gl_max;
722             TRACE_(d3d_caps)("Max anisotropy: %d\n", gl_info->max_anisotropy);
723         }
724         if (gl_info->supported[ARB_FRAGMENT_PROGRAM]) {
725             gl_info->ps_arb_version = PS_VERSION_11;
726             GL_EXTCALL(glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_ENV_PARAMETERS_ARB, &gl_max));
727             gl_info->ps_arb_constantsF = gl_max;
728             TRACE_(d3d_caps)("Max ARB_FRAGMENT_PROGRAM float constants: %d\n", gl_info->ps_arb_constantsF);
729             GL_EXTCALL(glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_TEMPORARIES_ARB, &gl_max));
730             gl_info->ps_arb_max_temps = gl_max;
731             TRACE_(d3d_caps)("Max ARB_FRAGMENT_PROGRAM temporaries: %d\n", gl_info->ps_arb_max_temps);
732             GL_EXTCALL(glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_INSTRUCTIONS_ARB, &gl_max));
733             gl_info->ps_arb_max_instructions = gl_max;
734             TRACE_(d3d_caps)("Max ARB_FRAGMENT_PROGRAM instructions: %d\n", gl_info->ps_arb_max_instructions);
735         }
736         if (gl_info->supported[ARB_VERTEX_PROGRAM]) {
737             gl_info->vs_arb_version = VS_VERSION_11;
738             GL_EXTCALL(glGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_MAX_PROGRAM_ENV_PARAMETERS_ARB, &gl_max));
739             gl_info->vs_arb_constantsF = gl_max;
740             TRACE_(d3d_caps)("Max ARB_VERTEX_PROGRAM float constants: %d\n", gl_info->vs_arb_constantsF);
741             GL_EXTCALL(glGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_MAX_PROGRAM_TEMPORARIES_ARB, &gl_max));
742             gl_info->vs_arb_max_temps = gl_max;
743             TRACE_(d3d_caps)("Max ARB_VERTEX_PROGRAM temporaries: %d\n", gl_info->vs_arb_max_temps);
744             GL_EXTCALL(glGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_MAX_PROGRAM_INSTRUCTIONS_ARB, &gl_max));
745             gl_info->vs_arb_max_instructions = gl_max;
746             TRACE_(d3d_caps)("Max ARB_VERTEX_PROGRAM instructions: %d\n", gl_info->vs_arb_max_instructions);
747         }
748         if (gl_info->supported[ARB_VERTEX_SHADER]) {
749             glGetIntegerv(GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB, &gl_max);
750             gl_info->vs_glsl_constantsF = gl_max / 4;
751             TRACE_(d3d_caps)("Max ARB_VERTEX_SHADER float constants: %u\n", gl_info->vs_glsl_constantsF);
752         }
753         if (gl_info->supported[ARB_FRAGMENT_SHADER]) {
754             glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB, &gl_max);
755             gl_info->ps_glsl_constantsF = gl_max / 4;
756             TRACE_(d3d_caps)("Max ARB_FRAGMENT_SHADER float constants: %u\n", gl_info->ps_glsl_constantsF);
757         }
758         if (gl_info->supported[EXT_VERTEX_SHADER]) {
759             gl_info->vs_ati_version = VS_VERSION_11;
760         }
761         if (gl_info->supported[NV_VERTEX_PROGRAM3]) {
762             gl_info->vs_nv_version = VS_VERSION_30;
763         } else if (gl_info->supported[NV_VERTEX_PROGRAM2]) {
764             gl_info->vs_nv_version = VS_VERSION_20;
765         } else if (gl_info->supported[NV_VERTEX_PROGRAM1_1]) {
766             gl_info->vs_nv_version = VS_VERSION_11;
767         } else if (gl_info->supported[NV_VERTEX_PROGRAM]) {
768             gl_info->vs_nv_version = VS_VERSION_10;
769         }
770         if (gl_info->supported[NV_FRAGMENT_PROGRAM2]) {
771             gl_info->ps_nv_version = PS_VERSION_30;
772         } else if (gl_info->supported[NV_FRAGMENT_PROGRAM]) {
773             gl_info->ps_nv_version = PS_VERSION_20;
774         }
775
776     }
777     checkGLcall("extension detection\n");
778
779     /* In some cases the number of texture stages can be larger than the number
780      * of samplers. The GF4 for example can use only 2 samplers (no fragment
781      * shaders), but 8 texture stages (register combiners). */
782     gl_info->max_sampler_stages = max(gl_info->max_fragment_samplers, gl_info->max_texture_stages);
783
784     /* We can only use ORM_FBO when the hardware supports it. */
785     if (wined3d_settings.offscreen_rendering_mode == ORM_FBO && !gl_info->supported[EXT_FRAMEBUFFER_OBJECT]) {
786         WARN_(d3d_caps)("GL_EXT_framebuffer_object not supported, falling back to PBuffer offscreen rendering mode.\n");
787         wined3d_settings.offscreen_rendering_mode = ORM_PBUFFER;
788     }
789
790     /* MRTs are currently only supported when FBOs are used. */
791     if (wined3d_settings.offscreen_rendering_mode != ORM_FBO) {
792         gl_info->max_buffers = 1;
793     }
794
795     /* Below is a list of Nvidia and ATI GPUs. Both vendors have dozens of different GPUs with roughly the same
796      * features. In most cases GPUs from a certain family differ in clockspeeds, the amount of video memory and
797      * in case of the latest videocards in the number of pixel/vertex pipelines.
798      *
799      * A Direct3D device object contains the PCI id (vendor + device) of the videocard which is used for
800      * rendering. Various games use this information to get a rough estimation of the features of the card
801      * and some might use it for enabling 3d effects only on certain types of videocards. In some cases
802      * games might even use it to work around bugs which happen on certain videocards/driver combinations.
803      * The problem is that OpenGL only exposes a rendering string containing the name of the videocard and
804      * not the PCI id.
805      *
806      * Various games depend on the PCI id, so somehow we need to provide one. A simple option is to parse
807      * the renderer string and translate this to the right PCI id. This is a lot of work because there are more
808      * than 200 GPUs just for Nvidia. Various cards share the same renderer string, so the amount of code might
809      * be 'small' but there are quite a number of exceptions which would make this a pain to maintain.
810      * Another way would be to query the PCI id from the operating system (assuming this is the videocard which
811      * is used for rendering which is not always the case). This would work but it is not very portable. Second
812      * it would not work well in, let's say, a remote X situation in which the amount of 3d features which can be used
813      * is limited.
814      *
815      * As said most games only use the PCI id to get an indication of the capabilities of the card.
816      * It doesn't really matter if the given id is the correct one if we return the id of a card with
817      * similar 3d features.
818      *
819      * The code below checks the OpenGL capabilities of a videocard and matches that to a certain level of
820      * Direct3D functionality. Once a card passes the Direct3D9 check, we know that the card (in case of Nvidia)
821      * is at least a GeforceFX. To give a better estimate we do a basic check on the renderer string but if that
822      * won't pass we return a default card. This way is better than maintaining a full card database as even
823      * without a full database we can return a card with similar features. Second the size of the database
824      * can be made quite small because when you know what type of 3d functionality a card has, you know to which
825      * GPU family the GPU must belong. Because of this you only have to check a small part of the renderer string
826      * to distinguishes between different models from that family. 
827      */
828     switch (gl_info->gl_vendor) {
829         case VENDOR_NVIDIA:
830             /* Both the GeforceFX, 6xxx and 7xxx series support D3D9. The last two types have more
831              * shader capabilities, so we use the shader capabilities to distinguish between FX and 6xxx/7xxx.
832              */
833             if(WINE_D3D9_CAPABLE(gl_info) && (gl_info->vs_nv_version == VS_VERSION_30)) {
834                 if (strstr(gl_info->gl_renderer, "7800") ||
835                     strstr(gl_info->gl_renderer, "7900") ||
836                     strstr(gl_info->gl_renderer, "7950") ||
837                     strstr(gl_info->gl_renderer, "Quadro FX 4") ||
838                     strstr(gl_info->gl_renderer, "Quadro FX 5"))
839                         gl_info->gl_card = CARD_NVIDIA_GEFORCE_7800GT;
840                 else if(strstr(gl_info->gl_renderer, "6800") ||
841                         strstr(gl_info->gl_renderer, "7600"))
842                             gl_info->gl_card = CARD_NVIDIA_GEFORCE_6800;
843                 else if(strstr(gl_info->gl_renderer, "6600") ||
844                         strstr(gl_info->gl_renderer, "6610") ||
845                         strstr(gl_info->gl_renderer, "6700"))
846                             gl_info->gl_card = CARD_NVIDIA_GEFORCE_6600GT;
847                 else
848                     gl_info->gl_card = CARD_NVIDIA_GEFORCE_6200; /* Geforce 6100/6150/6200/7300/7400 */
849             } else if(WINE_D3D9_CAPABLE(gl_info)) {
850                 if (strstr(gl_info->gl_renderer, "5800") ||
851                     strstr(gl_info->gl_renderer, "5900") ||
852                     strstr(gl_info->gl_renderer, "5950") ||
853                     strstr(gl_info->gl_renderer, "Quadro FX"))
854                         gl_info->gl_card = CARD_NVIDIA_GEFORCEFX_5800;
855                 else if(strstr(gl_info->gl_renderer, "5600") ||
856                         strstr(gl_info->gl_renderer, "5650") ||
857                         strstr(gl_info->gl_renderer, "5700") ||
858                         strstr(gl_info->gl_renderer, "5750"))
859                             gl_info->gl_card = CARD_NVIDIA_GEFORCEFX_5600;
860                 else
861                     gl_info->gl_card = CARD_NVIDIA_GEFORCEFX_5200; /* GeforceFX 5100/5200/5250/5300/5500 */
862             } else if(WINE_D3D8_CAPABLE(gl_info)) {
863                 if (strstr(gl_info->gl_renderer, "GeForce4 Ti") || strstr(gl_info->gl_renderer, "Quadro4"))
864                     gl_info->gl_card = CARD_NVIDIA_GEFORCE4_TI4200; /* Geforce4 Ti4200/Ti4400/Ti4600/Ti4800, Quadro4 */
865                 else
866                     gl_info->gl_card = CARD_NVIDIA_GEFORCE3; /* Geforce3 standard/Ti200/Ti500, Quadro DCC */
867             } else if(WINE_D3D7_CAPABLE(gl_info)) {
868                 if (strstr(gl_info->gl_renderer, "GeForce4 MX"))
869                     gl_info->gl_card = CARD_NVIDIA_GEFORCE4_MX; /* MX420/MX440/MX460/MX4000 */
870                 else if(strstr(gl_info->gl_renderer, "GeForce2 MX") || strstr(gl_info->gl_renderer, "Quadro2 MXR"))
871                     gl_info->gl_card = CARD_NVIDIA_GEFORCE2_MX; /* Geforce2 standard/MX100/MX200/MX400, Quadro2 MXR */
872                 else if(strstr(gl_info->gl_renderer, "GeForce2") || strstr(gl_info->gl_renderer, "Quadro2"))
873                     gl_info->gl_card = CARD_NVIDIA_GEFORCE2; /* Geforce2 GTS/Pro/Ti/Ultra, Quadro2 */
874                 else
875                     gl_info->gl_card = CARD_NVIDIA_GEFORCE; /* Geforce 256/DDR, Quadro */
876             } else {
877                 if (strstr(gl_info->gl_renderer, "TNT2"))
878                     gl_info->gl_card = CARD_NVIDIA_RIVA_TNT2; /* Riva TNT2 standard/M64/Pro/Ultra */
879                 else
880                     gl_info->gl_card = CARD_NVIDIA_RIVA_TNT; /* Riva TNT, Vanta */
881             }
882             break;
883         case VENDOR_ATI:
884             if(WINE_D3D9_CAPABLE(gl_info)) {
885                 /* Radeon R5xx */
886                 if (strstr(gl_info->gl_renderer, "X1600") ||
887                     strstr(gl_info->gl_renderer, "X1800") ||
888                     strstr(gl_info->gl_renderer, "X1900") ||
889                     strstr(gl_info->gl_renderer, "X1950"))
890                         gl_info->gl_card = CARD_ATI_RADEON_X1600;
891                 /* Radeon R4xx + X1300/X1400 (lowend R5xx) */
892                 else if(strstr(gl_info->gl_renderer, "X700") ||
893                         strstr(gl_info->gl_renderer, "X800") ||
894                         strstr(gl_info->gl_renderer, "X850") ||
895                         strstr(gl_info->gl_renderer, "X1300") ||
896                         strstr(gl_info->gl_renderer, "X1400"))
897                             gl_info->gl_card = CARD_ATI_RADEON_X700;
898                 /* Radeon R3xx */ 
899                 else
900                     gl_info->gl_card = CARD_ATI_RADEON_9500; /* Radeon 9500/9550/9600/9700/9800/X300/X550/X600 */
901             } else if(WINE_D3D8_CAPABLE(gl_info)) {
902                     gl_info->gl_card = CARD_ATI_RADEON_8500; /* Radeon 8500/9000/9100/9200/9300 */
903             } else if(WINE_D3D7_CAPABLE(gl_info)) {
904                     gl_info->gl_card = CARD_ATI_RADEON_7200; /* Radeon 7000/7100/7200/7500 */
905             } else
906                 gl_info->gl_card = CARD_ATI_RAGE_128PRO;
907             break;
908         case VENDOR_INTEL:
909             if (strstr(gl_info->gl_renderer, "915GM")) {
910                 gl_info->gl_card = CARD_INTEL_I915GM;
911             } else if (strstr(gl_info->gl_renderer, "915G")) {
912                 gl_info->gl_card = CARD_INTEL_I915G;
913             } else if (strstr(gl_info->gl_renderer, "865G")) {
914                 gl_info->gl_card = CARD_INTEL_I865G;
915             } else if (strstr(gl_info->gl_renderer, "855G")) {
916                 gl_info->gl_card = CARD_INTEL_I855G;
917             } else if (strstr(gl_info->gl_renderer, "830G")) {
918                 gl_info->gl_card = CARD_INTEL_I830G;
919             } else {
920                 gl_info->gl_card = CARD_INTEL_I915G;
921             }
922             break;
923         case VENDOR_MESA:
924         case VENDOR_WINE:
925         default:
926             /* Default to generic Nvidia hardware based on the supported OpenGL extensions. The choice 
927              * for Nvidia was because the hardware and drivers they make are of good quality. This makes
928              * them a good generic choice.
929              */
930             gl_info->gl_vendor = VENDOR_NVIDIA;
931             if(WINE_D3D9_CAPABLE(gl_info))
932                 gl_info->gl_card = CARD_NVIDIA_GEFORCEFX_5600;
933             else if(WINE_D3D8_CAPABLE(gl_info))
934                 gl_info->gl_card = CARD_NVIDIA_GEFORCE3;            
935             else if(WINE_D3D7_CAPABLE(gl_info))
936                 gl_info->gl_card = CARD_NVIDIA_GEFORCE;
937             else if(WINE_D3D6_CAPABLE(gl_info))
938                 gl_info->gl_card = CARD_NVIDIA_RIVA_TNT;
939             else
940                 gl_info->gl_card = CARD_NVIDIA_RIVA_128;
941     }
942     TRACE("FOUND (fake) card: 0x%x (vendor id), 0x%x (device id)\n", gl_info->gl_vendor, gl_info->gl_card);
943
944     /* Load all the lookup tables
945     TODO: It may be a good idea to make minLookup and maxLookup const and populate them in wined3d_private.h where they are declared */
946     minLookup[WINELOOKUP_WARPPARAM] = WINED3DTADDRESS_WRAP;
947     maxLookup[WINELOOKUP_WARPPARAM] = WINED3DTADDRESS_MIRRORONCE;
948
949     minLookup[WINELOOKUP_MAGFILTER] = WINED3DTEXF_NONE;
950     maxLookup[WINELOOKUP_MAGFILTER] = WINED3DTEXF_ANISOTROPIC;
951
952
953     for (i = 0; i < MAX_LOOKUPS; i++) {
954         stateLookup[i] = HeapAlloc(GetProcessHeap(), 0, sizeof(*stateLookup[i]) * (1 + maxLookup[i] - minLookup[i]) );
955     }
956
957     stateLookup[WINELOOKUP_WARPPARAM][WINED3DTADDRESS_WRAP   - minLookup[WINELOOKUP_WARPPARAM]] = GL_REPEAT;
958     stateLookup[WINELOOKUP_WARPPARAM][WINED3DTADDRESS_CLAMP  - minLookup[WINELOOKUP_WARPPARAM]] = GL_CLAMP_TO_EDGE;
959     stateLookup[WINELOOKUP_WARPPARAM][WINED3DTADDRESS_BORDER - minLookup[WINELOOKUP_WARPPARAM]] =
960              gl_info->supported[ARB_TEXTURE_BORDER_CLAMP] ? GL_CLAMP_TO_BORDER_ARB : GL_REPEAT;
961     stateLookup[WINELOOKUP_WARPPARAM][WINED3DTADDRESS_BORDER - minLookup[WINELOOKUP_WARPPARAM]] =
962              gl_info->supported[ARB_TEXTURE_BORDER_CLAMP] ? GL_CLAMP_TO_BORDER_ARB : GL_REPEAT;
963     stateLookup[WINELOOKUP_WARPPARAM][WINED3DTADDRESS_MIRROR - minLookup[WINELOOKUP_WARPPARAM]] =
964              gl_info->supported[ARB_TEXTURE_MIRRORED_REPEAT] ? GL_MIRRORED_REPEAT_ARB : GL_REPEAT;
965     stateLookup[WINELOOKUP_WARPPARAM][WINED3DTADDRESS_MIRRORONCE - minLookup[WINELOOKUP_WARPPARAM]] =
966              gl_info->supported[ATI_TEXTURE_MIRROR_ONCE] ? GL_MIRROR_CLAMP_TO_EDGE_ATI : GL_REPEAT;
967
968     stateLookup[WINELOOKUP_MAGFILTER][WINED3DTEXF_NONE        - minLookup[WINELOOKUP_MAGFILTER]]  = GL_NEAREST;
969     stateLookup[WINELOOKUP_MAGFILTER][WINED3DTEXF_POINT       - minLookup[WINELOOKUP_MAGFILTER]] = GL_NEAREST;
970     stateLookup[WINELOOKUP_MAGFILTER][WINED3DTEXF_LINEAR      - minLookup[WINELOOKUP_MAGFILTER]] = GL_LINEAR;
971     stateLookup[WINELOOKUP_MAGFILTER][WINED3DTEXF_ANISOTROPIC - minLookup[WINELOOKUP_MAGFILTER]] =
972              gl_info->supported[EXT_TEXTURE_FILTER_ANISOTROPIC] ? GL_LINEAR : GL_NEAREST;
973
974
975     minMipLookup[WINED3DTEXF_NONE][WINED3DTEXF_NONE]     = GL_LINEAR;
976     minMipLookup[WINED3DTEXF_NONE][WINED3DTEXF_POINT]    = GL_LINEAR;
977     minMipLookup[WINED3DTEXF_NONE][WINED3DTEXF_LINEAR]   = GL_LINEAR;
978     minMipLookup[WINED3DTEXF_POINT][WINED3DTEXF_NONE]    = GL_NEAREST;
979     minMipLookup[WINED3DTEXF_POINT][WINED3DTEXF_POINT]   = GL_NEAREST_MIPMAP_NEAREST;
980     minMipLookup[WINED3DTEXF_POINT][WINED3DTEXF_LINEAR]  = GL_NEAREST_MIPMAP_LINEAR;
981     minMipLookup[WINED3DTEXF_LINEAR][WINED3DTEXF_NONE]   = GL_LINEAR;
982     minMipLookup[WINED3DTEXF_LINEAR][WINED3DTEXF_POINT]  = GL_LINEAR_MIPMAP_NEAREST;
983     minMipLookup[WINED3DTEXF_LINEAR][WINED3DTEXF_LINEAR] = GL_LINEAR_MIPMAP_LINEAR;
984     minMipLookup[WINED3DTEXF_ANISOTROPIC][WINED3DTEXF_NONE]   = gl_info->supported[EXT_TEXTURE_FILTER_ANISOTROPIC] ?
985     GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR;
986     minMipLookup[WINED3DTEXF_ANISOTROPIC][WINED3DTEXF_POINT]  = gl_info->supported[EXT_TEXTURE_FILTER_ANISOTROPIC] ? GL_LINEAR_MIPMAP_NEAREST : GL_LINEAR;
987     minMipLookup[WINED3DTEXF_ANISOTROPIC][WINED3DTEXF_LINEAR] = gl_info->supported[EXT_TEXTURE_FILTER_ANISOTROPIC] ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR;
988
989 /* TODO: config lookups */
990
991     /* Make sure there's an active HDC else the WGL extensions will fail */
992     hdc = wglGetCurrentDC();
993     if (hdc) {
994         WGL_Extensions = GL_EXTCALL(wglGetExtensionsStringARB(hdc));
995         TRACE_(d3d_caps)("WGL_Extensions reported:\n");
996
997         if (NULL == WGL_Extensions) {
998             ERR("   WGL_Extensions returns NULL\n");
999         } else {
1000             while (*WGL_Extensions != 0x00) {
1001                 const char *Start = WGL_Extensions;
1002                 char ThisExtn[256];
1003
1004                 memset(ThisExtn, 0x00, sizeof(ThisExtn));
1005                 while (*WGL_Extensions != ' ' && *WGL_Extensions != 0x00) {
1006                     WGL_Extensions++;
1007                 }
1008                 memcpy(ThisExtn, Start, (WGL_Extensions - Start));
1009                 TRACE_(d3d_caps)("- %s\n", ThisExtn);
1010
1011                 if (strstr(ThisExtn, "WGL_ARB_pbuffer")) {
1012                     gl_info->supported[WGL_ARB_PBUFFER] = TRUE;
1013                     TRACE_(d3d_caps)("FOUND: WGL_ARB_pbuffer support\n");
1014                 }
1015
1016                 if (*WGL_Extensions == ' ') WGL_Extensions++;
1017             }
1018         }
1019     }
1020
1021
1022     WineD3D_ReleaseFakeGLContext();
1023     return return_value;
1024 }
1025 #undef GLINFO_LOCATION
1026
1027 /**********************************************************
1028  * IWineD3D implementation follows
1029  **********************************************************/
1030
1031 static UINT     WINAPI IWineD3DImpl_GetAdapterCount (IWineD3D *iface) {
1032     IWineD3DImpl *This = (IWineD3DImpl *)iface;
1033
1034     TRACE_(d3d_caps)("(%p): Reporting %d adapters\n", This, numAdapters);
1035     return numAdapters;
1036 }
1037
1038 static HRESULT  WINAPI IWineD3DImpl_RegisterSoftwareDevice(IWineD3D *iface, void* pInitializeFunction) {
1039     IWineD3DImpl *This = (IWineD3DImpl *)iface;
1040     FIXME("(%p)->(%p): stub\n", This, pInitializeFunction);
1041     return WINED3D_OK;
1042 }
1043
1044 static HMONITOR WINAPI IWineD3DImpl_GetAdapterMonitor(IWineD3D *iface, UINT Adapter) {
1045     IWineD3DImpl *This = (IWineD3DImpl *)iface;
1046
1047     if (Adapter >= IWineD3DImpl_GetAdapterCount(iface)) {
1048         return NULL;
1049     }
1050
1051     TRACE_(d3d_caps)("(%p)->(%d)\n", This, Adapter);
1052     return MonitorFromPoint(Adapters[Adapter].monitorPoint, MONITOR_DEFAULTTOPRIMARY);
1053 }
1054
1055 /* FIXME: GetAdapterModeCount and EnumAdapterModes currently only returns modes
1056      of the same bpp but different resolutions                                  */
1057
1058 /* Note: dx9 supplies a format. Calls from d3d8 supply WINED3DFMT_UNKNOWN */
1059 static UINT     WINAPI IWineD3DImpl_GetAdapterModeCount(IWineD3D *iface, UINT Adapter, WINED3DFORMAT Format) {
1060     IWineD3DImpl *This = (IWineD3DImpl *)iface;
1061     TRACE_(d3d_caps)("(%p}->(Adapter: %d, Format: %s)\n", This, Adapter, debug_d3dformat(Format));
1062
1063     if (Adapter >= IWineD3D_GetAdapterCount(iface)) {
1064         return 0;
1065     }
1066
1067     /* TODO: Store modes per adapter and read it from the adapter structure */
1068     if (Adapter == 0) { /* Display */
1069         int i = 0;
1070         int j = 0;
1071
1072         if (!DEBUG_SINGLE_MODE) {
1073             DEVMODEW DevModeW;
1074
1075             ZeroMemory(&DevModeW, sizeof(DevModeW));
1076             DevModeW.dmSize = sizeof(DevModeW);
1077             while (EnumDisplaySettingsExW(NULL, j, &DevModeW, 0)) {
1078                 j++;
1079                 switch (Format)
1080                 {
1081                     case WINED3DFMT_UNKNOWN:
1082                         /* This is for D3D8, do not enumerate P8 here */
1083                         if (DevModeW.dmBitsPerPel == 32 ||
1084                             DevModeW.dmBitsPerPel == 16) i++;
1085                         break;
1086                     case WINED3DFMT_X8R8G8B8:
1087                         if (DevModeW.dmBitsPerPel == 32) i++;
1088                         break;
1089                     case WINED3DFMT_R5G6B5:
1090                         if (DevModeW.dmBitsPerPel == 16) i++;
1091                         break;
1092                     case WINED3DFMT_P8:
1093                         if (DevModeW.dmBitsPerPel == 8) i++;
1094                         break;
1095                     default:
1096                         /* Skip other modes as they do not match the requested format */
1097                         break;
1098                 }
1099             }
1100         } else {
1101             i = 1;
1102             j = 1;
1103         }
1104
1105         TRACE_(d3d_caps)("(%p}->(Adapter: %d) => %d (out of %d)\n", This, Adapter, i, j);
1106         return i;
1107     } else {
1108         FIXME_(d3d_caps)("Adapter not primary display\n");
1109     }
1110     return 0;
1111 }
1112
1113 /* Note: dx9 supplies a format. Calls from d3d8 supply WINED3DFMT_UNKNOWN */
1114 static HRESULT WINAPI IWineD3DImpl_EnumAdapterModes(IWineD3D *iface, UINT Adapter, WINED3DFORMAT Format, UINT Mode, WINED3DDISPLAYMODE* pMode) {
1115     IWineD3DImpl *This = (IWineD3DImpl *)iface;
1116     TRACE_(d3d_caps)("(%p}->(Adapter:%d, mode:%d, pMode:%p, format:%s)\n", This, Adapter, Mode, pMode, debug_d3dformat(Format));
1117
1118     /* Validate the parameters as much as possible */
1119     if (NULL == pMode ||
1120         Adapter >= IWineD3DImpl_GetAdapterCount(iface) ||
1121         Mode    >= IWineD3DImpl_GetAdapterModeCount(iface, Adapter, Format)) {
1122         return WINED3DERR_INVALIDCALL;
1123     }
1124
1125     /* TODO: Store modes per adapter and read it from the adapter structure */
1126     if (Adapter == 0 && !DEBUG_SINGLE_MODE) { /* Display */
1127         DEVMODEW DevModeW;
1128         int ModeIdx = 0;
1129         int i = 0;
1130         int j = 0;
1131
1132         ZeroMemory(&DevModeW, sizeof(DevModeW));
1133         DevModeW.dmSize = sizeof(DevModeW);
1134
1135         /* If we are filtering to a specific format (D3D9), then need to skip
1136            all unrelated modes, but if mode is irrelevant (D3D8), then we can
1137            just count through the ones with valid bit depths */
1138         while ((i<=Mode) && EnumDisplaySettingsExW(NULL, j++, &DevModeW, 0)) {
1139             switch (Format)
1140             {
1141                 case WINED3DFMT_UNKNOWN:
1142                     /* This is D3D8. Do not enumerate P8 here */
1143                     if (DevModeW.dmBitsPerPel == 32 ||
1144                         DevModeW.dmBitsPerPel == 16) i++;
1145                     break;
1146                 case WINED3DFMT_X8R8G8B8:
1147                     if (DevModeW.dmBitsPerPel == 32) i++;
1148                     break;
1149                 case WINED3DFMT_R5G6B5:
1150                     if (DevModeW.dmBitsPerPel == 16) i++;
1151                     break;
1152                 case WINED3DFMT_P8:
1153                     if (DevModeW.dmBitsPerPel == 8) i++;
1154                     break;
1155                 default:
1156                     /* Modes that don't match what we support can get an early-out */
1157                     TRACE_(d3d_caps)("Searching for %s, returning D3DERR_INVALIDCALL\n", debug_d3dformat(Format));
1158                     return WINED3DERR_INVALIDCALL;
1159             }
1160         }
1161
1162         if (i == 0) {
1163             TRACE_(d3d_caps)("No modes found for format (%x - %s)\n", Format, debug_d3dformat(Format));
1164             return WINED3DERR_INVALIDCALL;
1165         }
1166         ModeIdx = j - 1;
1167
1168         /* Now get the display mode via the calculated index */
1169         if (EnumDisplaySettingsExW(NULL, ModeIdx, &DevModeW, 0)) {
1170             pMode->Width        = DevModeW.dmPelsWidth;
1171             pMode->Height       = DevModeW.dmPelsHeight;
1172             pMode->RefreshRate  = WINED3DADAPTER_DEFAULT;
1173             if (DevModeW.dmFields & DM_DISPLAYFREQUENCY)
1174                 pMode->RefreshRate = DevModeW.dmDisplayFrequency;
1175
1176             if (Format == WINED3DFMT_UNKNOWN)
1177             {
1178                 switch (DevModeW.dmBitsPerPel)
1179                 {
1180                     case 8:
1181                         pMode->Format = WINED3DFMT_P8;
1182                         break;
1183                     case 16:
1184                         pMode->Format = WINED3DFMT_R5G6B5;
1185                         break;
1186                     case 32:
1187                         pMode->Format = WINED3DFMT_X8R8G8B8;
1188                         break;
1189                     default:
1190                         pMode->Format = WINED3DFMT_UNKNOWN;
1191                         ERR("Unhandled bit depth (%u) in mode list!\n", DevModeW.dmBitsPerPel);
1192                 }
1193             } else {
1194                 pMode->Format = Format;
1195             }
1196         } else {
1197             TRACE_(d3d_caps)("Requested mode out of range %d\n", Mode);
1198             return WINED3DERR_INVALIDCALL;
1199         }
1200
1201         TRACE_(d3d_caps)("W %d H %d rr %d fmt (%x - %s) bpp %u\n", pMode->Width, pMode->Height,
1202                 pMode->RefreshRate, pMode->Format, debug_d3dformat(pMode->Format),
1203                 DevModeW.dmBitsPerPel);
1204
1205     } else if (DEBUG_SINGLE_MODE) {
1206         /* Return one setting of the format requested */
1207         if (Mode > 0) return WINED3DERR_INVALIDCALL;
1208         pMode->Width        = 800;
1209         pMode->Height       = 600;
1210         pMode->RefreshRate  = 60;
1211         pMode->Format       = (Format == WINED3DFMT_UNKNOWN) ? WINED3DFMT_X8R8G8B8 : Format;
1212     } else {
1213         FIXME_(d3d_caps)("Adapter not primary display\n");
1214     }
1215
1216     return WINED3D_OK;
1217 }
1218
1219 static HRESULT WINAPI IWineD3DImpl_GetAdapterDisplayMode(IWineD3D *iface, UINT Adapter, WINED3DDISPLAYMODE* pMode) {
1220     IWineD3DImpl *This = (IWineD3DImpl *)iface;
1221     TRACE_(d3d_caps)("(%p}->(Adapter: %d, pMode: %p)\n", This, Adapter, pMode);
1222
1223     if (NULL == pMode ||
1224         Adapter >= IWineD3D_GetAdapterCount(iface)) {
1225         return WINED3DERR_INVALIDCALL;
1226     }
1227
1228     if (Adapter == 0) { /* Display */
1229         int bpp = 0;
1230         DEVMODEW DevModeW;
1231
1232         ZeroMemory(&DevModeW, sizeof(DevModeW));
1233         DevModeW.dmSize = sizeof(DevModeW);
1234
1235         EnumDisplaySettingsExW(NULL, ENUM_CURRENT_SETTINGS, &DevModeW, 0);
1236         pMode->Width        = DevModeW.dmPelsWidth;
1237         pMode->Height       = DevModeW.dmPelsHeight;
1238         bpp                 = DevModeW.dmBitsPerPel;
1239         pMode->RefreshRate  = WINED3DADAPTER_DEFAULT;
1240         if (DevModeW.dmFields&DM_DISPLAYFREQUENCY)
1241         {
1242             pMode->RefreshRate = DevModeW.dmDisplayFrequency;
1243         }
1244
1245         switch (bpp) {
1246         case  8: pMode->Format       = WINED3DFMT_R3G3B2;   break;
1247         case 16: pMode->Format       = WINED3DFMT_R5G6B5;   break;
1248         case 24: pMode->Format       = WINED3DFMT_X8R8G8B8; break; /* Robots needs 24bit to be X8R8G8B8 */
1249         case 32: pMode->Format       = WINED3DFMT_X8R8G8B8; break; /* EVE online and the Fur demo need 32bit AdapterDisplatMode to return X8R8G8B8 */
1250         default: pMode->Format       = WINED3DFMT_UNKNOWN;
1251         }
1252
1253     } else {
1254         FIXME_(d3d_caps)("Adapter not primary display\n");
1255     }
1256
1257     TRACE_(d3d_caps)("returning w:%d, h:%d, ref:%d, fmt:%s\n", pMode->Width,
1258           pMode->Height, pMode->RefreshRate, debug_d3dformat(pMode->Format));
1259     return WINED3D_OK;
1260 }
1261
1262 /* NOTE: due to structure differences between dx8 and dx9 D3DADAPTER_IDENTIFIER,
1263    and fields being inserted in the middle, a new structure is used in place    */
1264 static HRESULT WINAPI IWineD3DImpl_GetAdapterIdentifier(IWineD3D *iface, UINT Adapter, DWORD Flags,
1265                                                    WINED3DADAPTER_IDENTIFIER* pIdentifier) {
1266     IWineD3DImpl *This = (IWineD3DImpl *)iface;
1267
1268     TRACE_(d3d_caps)("(%p}->(Adapter: %d, Flags: %x, pId=%p)\n", This, Adapter, Flags, pIdentifier);
1269
1270     if (Adapter >= IWineD3D_GetAdapterCount(iface)) {
1271         return WINED3DERR_INVALIDCALL;
1272     }
1273
1274     /* Return the information requested */
1275     TRACE_(d3d_caps)("device/Vendor Name and Version detection using FillGLCaps\n");
1276     strcpy(pIdentifier->Driver, Adapters[Adapter].driver);
1277     strcpy(pIdentifier->Description, Adapters[Adapter].description);
1278
1279     /* Note dx8 doesn't supply a DeviceName */
1280     if (NULL != pIdentifier->DeviceName) strcpy(pIdentifier->DeviceName, "\\\\.\\DISPLAY"); /* FIXME: May depend on desktop? */
1281     /* Current Windows drivers have versions like 6.14.... (some older have an earlier version) */
1282     pIdentifier->DriverVersion->u.HighPart = MAKEDWORD_VERSION(6, 14);
1283     pIdentifier->DriverVersion->u.LowPart = Adapters[Adapter].gl_info.gl_driver_version;
1284     *(pIdentifier->VendorId) = Adapters[Adapter].gl_info.gl_vendor;
1285     *(pIdentifier->DeviceId) = Adapters[Adapter].gl_info.gl_card;
1286     *(pIdentifier->SubSysId) = 0;
1287     *(pIdentifier->Revision) = 0;
1288
1289     /*FIXME: memcpy(&pIdentifier->DeviceIdentifier, ??, sizeof(??GUID)); */
1290     if (Flags & WINED3DENUM_NO_WHQL_LEVEL) {
1291         *(pIdentifier->WHQLLevel) = 0;
1292     } else {
1293         *(pIdentifier->WHQLLevel) = 1;
1294     }
1295
1296     return WINED3D_OK;
1297 }
1298
1299 static BOOL IWineD3DImpl_IsGLXFBConfigCompatibleWithRenderFmt(int iPixelFormat, WINED3DFORMAT Format) {
1300 #if 0 /* This code performs a strict test between the format and the current X11  buffer depth, which may give the best performance */
1301   int gl_test;
1302   int rb, gb, bb, ab, type, buf_sz;
1303
1304   gl_test = glXGetFBConfigAttrib(display, cfgs, GLX_RED_SIZE,   &rb);
1305   gl_test = glXGetFBConfigAttrib(display, cfgs, GLX_GREEN_SIZE, &gb);
1306   gl_test = glXGetFBConfigAttrib(display, cfgs, GLX_BLUE_SIZE,  &bb);
1307   gl_test = glXGetFBConfigAttrib(display, cfgs, GLX_ALPHA_SIZE, &ab);
1308   gl_test = glXGetFBConfigAttrib(display, cfgs, GLX_RENDER_TYPE, &type);
1309   gl_test = glXGetFBConfigAttrib(display, cfgs, GLX_BUFFER_SIZE, &buf_sz);
1310
1311   switch (Format) {
1312   case WINED3DFMT_X8R8G8B8:
1313   case WINED3DFMT_R8G8B8:
1314     if (8 == rb && 8 == gb && 8 == bb) return TRUE;
1315     break;
1316   case WINED3DFMT_A8R8G8B8:
1317     if (8 == rb && 8 == gb && 8 == bb && 8 == ab) return TRUE;
1318     break;
1319   case WINED3DFMT_A2R10G10B10:
1320     if (10 == rb && 10 == gb && 10 == bb && 2 == ab) return TRUE;
1321     break;
1322   case WINED3DFMT_X1R5G5B5:
1323     if (5 == rb && 5 == gb && 5 == bb) return TRUE;
1324     break;
1325   case WINED3DFMT_A1R5G5B5:
1326     if (5 == rb && 5 == gb && 5 == bb && 1 == ab) return TRUE;
1327     break;
1328   case WINED3DFMT_X4R4G4B4:
1329     if (16 == buf_sz && 4 == rb && 4 == gb && 4 == bb) return TRUE;
1330     break;
1331   case WINED3DFMT_R5G6B5:
1332     if (5 == rb && 6 == gb && 5 == bb) return TRUE;
1333     break;
1334   case WINED3DFMT_R3G3B2:
1335     if (3 == rb && 3 == gb && 2 == bb) return TRUE;
1336     break;
1337   case WINED3DFMT_A8P8:
1338     if (type & GLX_COLOR_INDEX_BIT && 8 == buf_sz && 8 == ab) return TRUE;
1339     break;
1340   case WINED3DFMT_P8:
1341     if (type & GLX_COLOR_INDEX_BIT && 8 == buf_sz) return TRUE;
1342     break;
1343   default:
1344     break;
1345   }
1346   return FALSE;
1347 #else /* Most of the time performance is less of an issue than compatibility, this code allows for most common opengl/d3d formats */
1348 switch (Format) {
1349   case WINED3DFMT_X8R8G8B8:
1350   case WINED3DFMT_R8G8B8:
1351   case WINED3DFMT_A8R8G8B8:
1352   case WINED3DFMT_A2R10G10B10:
1353   case WINED3DFMT_X1R5G5B5:
1354   case WINED3DFMT_A1R5G5B5:
1355   case WINED3DFMT_R5G6B5:
1356   case WINED3DFMT_R3G3B2:
1357   case WINED3DFMT_A8P8:
1358   case WINED3DFMT_P8:
1359 return TRUE;
1360   default:
1361     break;
1362   }
1363 return FALSE;
1364 #endif
1365 }
1366
1367 static BOOL IWineD3DImpl_IsGLXFBConfigCompatibleWithDepthFmt(int iPixelFormat, WINED3DFORMAT Format) {
1368 #if 0/* This code performs a strict test between the format and the current X11  buffer depth, which may give the best performance */
1369   int gl_test;
1370   int db, sb;
1371
1372   gl_test = glXGetFBConfigAttrib(display, cfgs, GLX_DEPTH_SIZE, &db);
1373   gl_test = glXGetFBConfigAttrib(display, cfgs, GLX_STENCIL_SIZE, &sb);
1374
1375   switch (Format) {
1376   case WINED3DFMT_D16:
1377   case WINED3DFMT_D16_LOCKABLE:
1378     if (16 == db) return TRUE;
1379     break;
1380   case WINED3DFMT_D32:
1381     if (32 == db) return TRUE;
1382     break;
1383   case WINED3DFMT_D15S1:
1384     if (15 == db) return TRUE;
1385     break;
1386   case WINED3DFMT_D24S8:
1387     if (24 == db && 8 == sb) return TRUE;
1388     break;
1389   case WINED3DFMT_D24FS8:
1390     if (24 == db && 8 == sb) return TRUE;
1391     break;
1392   case WINED3DFMT_D24X8:
1393     if (24 == db) return TRUE;
1394     break;
1395   case WINED3DFMT_D24X4S4:
1396     if (24 == db && 4 == sb) return TRUE;
1397     break;
1398   case WINED3DFMT_D32F_LOCKABLE:
1399     if (32 == db) return TRUE;
1400     break;
1401   default:
1402     break;
1403   }
1404   return FALSE;
1405 #else /* Most of the time performance is less of an issue than compatibility, this code allows for most common opengl/d3d formats */
1406   switch (Format) {
1407   case WINED3DFMT_D16:
1408   case WINED3DFMT_D16_LOCKABLE:
1409   case WINED3DFMT_D32:
1410   case WINED3DFMT_D15S1:
1411   case WINED3DFMT_D24S8:
1412   case WINED3DFMT_D24FS8:
1413   case WINED3DFMT_D24X8:
1414   case WINED3DFMT_D24X4S4:
1415   case WINED3DFMT_D32F_LOCKABLE:
1416     return TRUE;
1417   default:
1418     break;
1419   }
1420   return FALSE;
1421 #endif
1422 }
1423
1424 static HRESULT WINAPI IWineD3DImpl_CheckDepthStencilMatch(IWineD3D *iface, UINT Adapter, WINED3DDEVTYPE DeviceType,
1425                                                    WINED3DFORMAT AdapterFormat,
1426                                                    WINED3DFORMAT RenderTargetFormat,
1427                                                    WINED3DFORMAT DepthStencilFormat) {
1428     IWineD3DImpl *This = (IWineD3DImpl *)iface;
1429     int it;
1430
1431     WARN_(d3d_caps)("(%p)-> (STUB) (Adptr:%d, DevType:(%x,%s), AdptFmt:(%x,%s), RendrTgtFmt:(%x,%s), DepthStencilFmt:(%x,%s))\n",
1432            This, Adapter,
1433            DeviceType, debug_d3ddevicetype(DeviceType),
1434            AdapterFormat, debug_d3dformat(AdapterFormat),
1435            RenderTargetFormat, debug_d3dformat(RenderTargetFormat),
1436            DepthStencilFormat, debug_d3dformat(DepthStencilFormat));
1437
1438     if (Adapter >= IWineD3D_GetAdapterCount(iface)) {
1439         TRACE("(%p) Failed: Atapter (%u) higher than supported adapters (%u) returning WINED3DERR_INVALIDCALL\n", This, Adapter, IWineD3D_GetAdapterCount(iface));
1440         return WINED3DERR_INVALIDCALL;
1441     }
1442
1443     for (it = 0; it < Adapters[Adapter].nCfgs; ++it) {
1444         if (IWineD3DImpl_IsGLXFBConfigCompatibleWithRenderFmt(it, RenderTargetFormat)) {
1445             if (IWineD3DImpl_IsGLXFBConfigCompatibleWithDepthFmt(it, DepthStencilFormat)) {
1446                 TRACE_(d3d_caps)("(%p) : Formats matched\n", This);
1447                 return WINED3D_OK;
1448             }
1449         }
1450     }
1451     WARN_(d3d_caps)("unsupported format pair: %s and %s\n", debug_d3dformat(RenderTargetFormat), debug_d3dformat(DepthStencilFormat));
1452
1453     return WINED3DERR_NOTAVAILABLE;
1454 }
1455
1456 static HRESULT WINAPI IWineD3DImpl_CheckDeviceMultiSampleType(IWineD3D *iface, UINT Adapter, WINED3DDEVTYPE DeviceType, 
1457                                                        WINED3DFORMAT SurfaceFormat,
1458                                                        BOOL Windowed, WINED3DMULTISAMPLE_TYPE MultiSampleType, DWORD*   pQualityLevels) {
1459
1460     IWineD3DImpl *This = (IWineD3DImpl *)iface;
1461     TRACE_(d3d_caps)("(%p)-> (STUB) (Adptr:%d, DevType:(%x,%s), SurfFmt:(%x,%s), Win?%d, MultiSamp:%x, pQual:%p)\n",
1462           This,
1463           Adapter,
1464           DeviceType, debug_d3ddevicetype(DeviceType),
1465           SurfaceFormat, debug_d3dformat(SurfaceFormat),
1466           Windowed,
1467           MultiSampleType,
1468           pQualityLevels);
1469
1470     if (Adapter >= IWineD3D_GetAdapterCount(iface)) {
1471         return WINED3DERR_INVALIDCALL;
1472     }
1473
1474     /* TODO: Store in Adapter structure */
1475     if (pQualityLevels != NULL) {
1476         static int s_single_shot = 0;
1477         if (!s_single_shot) {
1478             FIXME("Quality levels unsupported at present\n");
1479             s_single_shot = 1;
1480         }
1481         *pQualityLevels = 1; /* Guess at a value! */
1482     }
1483
1484     if (WINED3DMULTISAMPLE_NONE == MultiSampleType) return WINED3D_OK;
1485     return WINED3DERR_NOTAVAILABLE;
1486 }
1487
1488 static HRESULT WINAPI IWineD3DImpl_CheckDeviceType(IWineD3D *iface, UINT Adapter, WINED3DDEVTYPE CheckType,
1489                                             WINED3DFORMAT DisplayFormat, WINED3DFORMAT BackBufferFormat, BOOL Windowed) {
1490
1491     IWineD3DImpl *This = (IWineD3DImpl *)iface;
1492     int nCfgs = 0;
1493     int it;
1494     HRESULT hr = WINED3DERR_NOTAVAILABLE;
1495
1496     TRACE_(d3d_caps)("(%p)-> (STUB) (Adptr:%d, CheckType:(%x,%s), DispFmt:(%x,%s), BackBuf:(%x,%s), Win?%d): stub\n",
1497           This,
1498           Adapter,
1499           CheckType, debug_d3ddevicetype(CheckType),
1500           DisplayFormat, debug_d3dformat(DisplayFormat),
1501           BackBufferFormat, debug_d3dformat(BackBufferFormat),
1502           Windowed);
1503
1504     if (Adapter >= IWineD3D_GetAdapterCount(iface)) {
1505         WARN_(d3d_caps)("Adapter >= IWineD3D_GetAdapterCount(iface), returning WINED3DERR_INVALIDCALL\n");
1506         return WINED3DERR_INVALIDCALL;
1507     }
1508
1509     /* TODO: Store in adapter structure */
1510     if (WineD3D_CreateFakeGLContext()) {
1511         nCfgs = DescribePixelFormat(wined3d_fake_gl_context_hdc, 0, 0, NULL);
1512         for (it = 0; it < nCfgs; ++it) {
1513             if (IWineD3DImpl_IsGLXFBConfigCompatibleWithRenderFmt(it, DisplayFormat)) {
1514                 hr = WINED3D_OK;
1515                 TRACE_(d3d_caps)("OK\n");
1516                 break ;
1517             }
1518         }
1519
1520         if(hr != WINED3D_OK)
1521             ERR("unsupported format %s\n", debug_d3dformat(DisplayFormat));
1522         WineD3D_ReleaseFakeGLContext();
1523     }
1524
1525     if(hr != WINED3D_OK)
1526         TRACE_(d3d_caps)("returning something different from WINED3D_OK\n");
1527
1528     return hr;
1529 }
1530
1531 #define GLINFO_LOCATION Adapters[Adapter].gl_info
1532 static HRESULT WINAPI IWineD3DImpl_CheckDeviceFormat(IWineD3D *iface, UINT Adapter, WINED3DDEVTYPE DeviceType, 
1533                                               WINED3DFORMAT AdapterFormat, DWORD Usage, WINED3DRESOURCETYPE RType, WINED3DFORMAT CheckFormat) {
1534     IWineD3DImpl *This = (IWineD3DImpl *)iface;
1535     TRACE_(d3d_caps)("(%p)-> (STUB) (Adptr:%d, DevType:(%u,%s), AdptFmt:(%u,%s), Use:(%u,%s,%s), ResTyp:(%x,%s), CheckFmt:(%u,%s))\n",
1536           This,
1537           Adapter,
1538           DeviceType, debug_d3ddevicetype(DeviceType),
1539           AdapterFormat, debug_d3dformat(AdapterFormat),
1540           Usage, debug_d3dusage(Usage), debug_d3dusagequery(Usage),
1541           RType, debug_d3dresourcetype(RType),
1542           CheckFormat, debug_d3dformat(CheckFormat));
1543
1544     if (Adapter >= IWineD3D_GetAdapterCount(iface)) {
1545         return WINED3DERR_INVALIDCALL;
1546     }
1547
1548     if (Usage & WINED3DUSAGE_QUERY_FILTER) {
1549         switch (CheckFormat) {
1550             /* Filtering not supported */
1551             case WINED3DFMT_A32B32G32R32F:
1552                 TRACE_(d3d_caps)("[FAILED]\n");
1553                 return WINED3DERR_NOTAVAILABLE;
1554             default:
1555                 break;
1556         }
1557     }
1558
1559     /* TODO: Check support against more of the WINED3DUSAGE_QUERY_* constants
1560      * See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/directx9_c/IDirect3D9__CheckDeviceFormat.asp
1561      * and http://msdn.microsoft.com/library/default.asp?url=/library/en-us/directx9_c/D3DUSAGE_QUERY.asp */
1562     if (Usage & WINED3DUSAGE_QUERY_VERTEXTEXTURE) {
1563         if (!GL_LIMITS(vertex_samplers)) {
1564             TRACE_(d3d_caps)("[FAILED]\n");
1565             return WINED3DERR_NOTAVAILABLE;
1566         }
1567
1568         switch (CheckFormat) {
1569             case WINED3DFMT_A32B32G32R32F:
1570                 if (!GL_SUPPORT(ARB_TEXTURE_FLOAT)) {
1571                     TRACE_(d3d_caps)("[FAILED]\n");
1572                     return WINED3DERR_NOTAVAILABLE;
1573                 }
1574                 TRACE_(d3d_caps)("[OK]\n");
1575                 return WINED3D_OK;
1576
1577             default:
1578                 TRACE_(d3d_caps)("[FAILED]\n");
1579                 return WINED3DERR_NOTAVAILABLE;
1580         }
1581     }
1582
1583     if(Usage & WINED3DUSAGE_DEPTHSTENCIL) {
1584         switch (CheckFormat) {
1585             /* In theory we could do all formats, just fetch them accordingly should the buffer be locked.
1586              * Windows supports only those 3, and enumerating the other formats confuses applications
1587              */
1588             case WINED3DFMT_D24S8:
1589             case WINED3DFMT_D24X8:
1590             case WINED3DFMT_D16:
1591                 TRACE_(d3d_caps)("[OK]\n");
1592                 return WINED3D_OK;
1593             case WINED3DFMT_D16_LOCKABLE:
1594             case WINED3DFMT_D24FS8:
1595             case WINED3DFMT_D32F_LOCKABLE:
1596             case WINED3DFMT_D24X4S4:
1597             case WINED3DFMT_D15S1:
1598             case WINED3DFMT_D32:
1599                 TRACE_(d3d_caps)("[FAILED]. Disabled because not enumerated on windows\n");
1600                 return WINED3DERR_NOTAVAILABLE;
1601             default:
1602                 TRACE_(d3d_caps)("[FAILED]\n");
1603                 return WINED3DERR_NOTAVAILABLE;
1604         }
1605     } else if(Usage & WINED3DUSAGE_RENDERTARGET) {
1606         switch (CheckFormat) {
1607             case WINED3DFMT_R8G8B8:
1608             case WINED3DFMT_A8R8G8B8:
1609             case WINED3DFMT_X8R8G8B8:
1610             case WINED3DFMT_R5G6B5:
1611             case WINED3DFMT_X1R5G5B5:
1612             case WINED3DFMT_A1R5G5B5:
1613             case WINED3DFMT_A4R4G4B4:
1614             case WINED3DFMT_R3G3B2:
1615             case WINED3DFMT_X4R4G4B4:
1616             case WINED3DFMT_A8B8G8R8:
1617             case WINED3DFMT_X8B8G8R8:
1618             case WINED3DFMT_P8:
1619                 TRACE_(d3d_caps)("[OK]\n");
1620                 return WINED3D_OK;
1621             case WINED3DFMT_R16F:
1622             case WINED3DFMT_A16B16G16R16F:
1623                 if (!GL_SUPPORT(ARB_HALF_FLOAT_PIXEL) || !GL_SUPPORT(ARB_TEXTURE_FLOAT)) {
1624                     TRACE_(d3d_caps)("[FAILED]\n");
1625                     return WINED3DERR_NOTAVAILABLE;
1626                 }
1627                 TRACE_(d3d_caps)("[OK]\n");
1628                 return WINED3D_OK;
1629             case WINED3DFMT_A32B32G32R32F:
1630                if (!GL_SUPPORT(ARB_TEXTURE_FLOAT)) {
1631                     TRACE_(d3d_caps)("[FAILED]\n");
1632                     return WINED3DERR_NOTAVAILABLE;
1633                 }
1634                 TRACE_(d3d_caps)("[OK]\n");
1635                 return WINED3D_OK;
1636             default:
1637                 TRACE_(d3d_caps)("[FAILED]\n");
1638                 return WINED3DERR_NOTAVAILABLE;
1639         }
1640     } else if(Usage & WINED3DUSAGE_QUERY_LEGACYBUMPMAP) {
1641         if(GL_SUPPORT(NV_REGISTER_COMBINERS) && GL_SUPPORT(NV_TEXTURE_SHADER2)) {
1642             switch (CheckFormat) {
1643                 case WINED3DFMT_V8U8:
1644                     TRACE_(d3d_caps)("[OK]\n");
1645                     return WINED3D_OK;
1646                 /* TODO: Other bump map formats */
1647                 default:
1648                     TRACE_(d3d_caps)("[FAILED]\n");
1649                     return WINED3DERR_NOTAVAILABLE;
1650             }
1651         }
1652         if(GL_SUPPORT(ATI_ENVMAP_BUMPMAP)) {
1653             switch (CheckFormat) {
1654                 case WINED3DFMT_V8U8:
1655                     TRACE_(d3d_caps)("[OK]\n");
1656                     return WINED3D_OK;
1657                 default:
1658                     TRACE_(d3d_caps)("[FAILED]\n");
1659                     return WINED3DERR_NOTAVAILABLE;
1660             }
1661         }
1662         TRACE_(d3d_caps)("[FAILED]\n");
1663         return WINED3DERR_NOTAVAILABLE;
1664     }
1665
1666     if (GL_SUPPORT(EXT_TEXTURE_COMPRESSION_S3TC)) {
1667         switch (CheckFormat) {
1668         case WINED3DFMT_DXT1:
1669         case WINED3DFMT_DXT2:
1670         case WINED3DFMT_DXT3:
1671         case WINED3DFMT_DXT4:
1672         case WINED3DFMT_DXT5:
1673           TRACE_(d3d_caps)("[OK]\n");
1674           return WINED3D_OK;
1675         default:
1676             break; /* Avoid compiler warnings */
1677         }
1678     }
1679
1680     /* Check for supported sRGB formats (Texture loading and framebuffer) */
1681     if (GL_SUPPORT(EXT_TEXTURE_SRGB) && (Usage & WINED3DUSAGE_QUERY_SRGBREAD)) {
1682         switch (CheckFormat) {
1683             case WINED3DFMT_A8R8G8B8:
1684             case WINED3DFMT_X8R8G8B8:
1685             case WINED3DFMT_A4R4G4B4:
1686             case WINED3DFMT_L8:
1687             case WINED3DFMT_A8L8:
1688             case WINED3DFMT_DXT1:
1689             case WINED3DFMT_DXT2:
1690             case WINED3DFMT_DXT3:
1691             case WINED3DFMT_DXT4:
1692             case WINED3DFMT_DXT5:
1693                 TRACE_(d3d_caps)("[OK]\n");
1694                 return WINED3D_OK;
1695
1696             default:
1697                 TRACE_(d3d_caps)("[FAILED] Gamma texture format %s not supported.\n", debug_d3dformat(CheckFormat));
1698                 return WINED3DERR_NOTAVAILABLE;
1699         }
1700     }
1701
1702     if (GL_SUPPORT(ARB_TEXTURE_FLOAT)) {
1703
1704         BOOL half_pixel_support = GL_SUPPORT(ARB_HALF_FLOAT_PIXEL);
1705
1706         switch (CheckFormat) {
1707             case WINED3DFMT_R16F:
1708             case WINED3DFMT_A16B16G16R16F:
1709                 if (!half_pixel_support) break;
1710             case WINED3DFMT_R32F:
1711             case WINED3DFMT_A32B32G32R32F:
1712                 TRACE_(d3d_caps)("[OK]\n");
1713                 return WINED3D_OK;
1714             default:
1715                 break; /* Avoid compiler warnings */
1716         }
1717     }
1718
1719     /* This format is nothing special and it is supported perfectly.
1720      * However, ati and nvidia driver on windows do not mark this format as
1721      * supported (tested with the dxCapsViewer) and pretending to
1722      * support this format uncovers a bug in Battlefield 1942 (fonts are missing)
1723      * So do the same as Windows drivers and pretend not to support it on dx8 and 9
1724      * Enable it on dx7. It will need additional checking on dx10 when we support it.
1725      */
1726     if(This->dxVersion > 7 && CheckFormat == WINED3DFMT_R8G8B8) {
1727         TRACE_(d3d_caps)("[FAILED]\n");
1728         return WINED3DERR_NOTAVAILABLE;
1729     }
1730
1731     switch (CheckFormat) {
1732
1733         /*****
1734          *  supported: RGB(A) formats
1735          */
1736         case WINED3DFMT_R8G8B8: /* Enable for dx7, blacklisted for 8 and 9 above */
1737         case WINED3DFMT_A8R8G8B8:
1738         case WINED3DFMT_X8R8G8B8:
1739         case WINED3DFMT_R5G6B5:
1740         case WINED3DFMT_X1R5G5B5:
1741         case WINED3DFMT_A1R5G5B5:
1742         case WINED3DFMT_A4R4G4B4:
1743         case WINED3DFMT_R3G3B2:
1744         case WINED3DFMT_A8:
1745         case WINED3DFMT_A8R3G3B2:
1746         case WINED3DFMT_X4R4G4B4:
1747         case WINED3DFMT_A8B8G8R8:
1748         case WINED3DFMT_X8B8G8R8:
1749         case WINED3DFMT_A2R10G10B10:
1750         case WINED3DFMT_A2B10G10R10:
1751             TRACE_(d3d_caps)("[OK]\n");
1752             return WINED3D_OK;
1753
1754         /*****
1755          *  supported: Palettized
1756          */
1757         case WINED3DFMT_P8:
1758             TRACE_(d3d_caps)("[OK]\n");
1759             return WINED3D_OK;
1760
1761         /*****
1762          *  Supported: (Alpha)-Luminance
1763          */
1764         case WINED3DFMT_L8:
1765         case WINED3DFMT_A8L8:
1766         case WINED3DFMT_A4L4:
1767             TRACE_(d3d_caps)("[OK]\n");
1768             return WINED3D_OK;
1769
1770         /*****
1771          *  Not supported for now: Bump mapping formats
1772          *  Enable some because games often fail when they are not available
1773          *  and are still playable even without bump mapping
1774          */
1775         case WINED3DFMT_V8U8:
1776         case WINED3DFMT_V16U16:
1777         case WINED3DFMT_L6V5U5:
1778         case WINED3DFMT_X8L8V8U8:
1779         case WINED3DFMT_Q8W8V8U8:
1780         case WINED3DFMT_W11V11U10:
1781         case WINED3DFMT_A2W10V10U10:
1782             WARN_(d3d_caps)("[Not supported, but pretended to do]\n");
1783             return WINED3D_OK;
1784
1785         /*****
1786          *  DXTN Formats: Handled above
1787          * WINED3DFMT_DXT1
1788          * WINED3DFMT_DXT2
1789          * WINED3DFMT_DXT3
1790          * WINED3DFMT_DXT4
1791          * WINED3DFMT_DXT5
1792          */
1793
1794         /*****
1795          *  Odd formats - not supported
1796          */
1797         case WINED3DFMT_VERTEXDATA:
1798         case WINED3DFMT_INDEX16:
1799         case WINED3DFMT_INDEX32:
1800         case WINED3DFMT_Q16W16V16U16:
1801             TRACE_(d3d_caps)("[FAILED]\n"); /* Enable when implemented */
1802             return WINED3DERR_NOTAVAILABLE;
1803
1804         /*****
1805          *  Float formats: Not supported right now
1806          */
1807         case WINED3DFMT_G16R16F:
1808         case WINED3DFMT_G32R32F:
1809         case WINED3DFMT_CxV8U8:
1810             TRACE_(d3d_caps)("[FAILED]\n"); /* Enable when implemented */
1811             return WINED3DERR_NOTAVAILABLE;
1812
1813             /* Not supported */
1814         case WINED3DFMT_G16R16:
1815         case WINED3DFMT_A16B16G16R16:
1816             TRACE_(d3d_caps)("[FAILED]\n"); /* Enable when implemented */
1817             return WINED3DERR_NOTAVAILABLE;
1818
1819         /* ATI instancing hack: Although ATI cards do not support Shader Model 3.0, they support
1820          * instancing. To query if the card supports instancing CheckDeviceFormat with the special format
1821          * MAKEFOURCC('I','N','S','T') is used. Should a (broken) app check for this provide a proper return value.
1822          * We can do instancing with all shader versions, but we need vertex shaders.
1823          *
1824          * Additionally applications have to set the D3DRS_POINTSIZE render state to MAKEFOURCC('I','N','S','T') once
1825          * to enable instancing. WineD3D doesn't need that and just ignores it.
1826          *
1827          * With Shader Model 3.0 capable cards Instancing 'just works' in Windows.
1828          */
1829         case WINEMAKEFOURCC('I','N','S','T'):
1830             TRACE("ATI Instancing check hack\n");
1831             if(GL_SUPPORT(ARB_VERTEX_PROGRAM) || GL_SUPPORT(ARB_VERTEX_SHADER)) {
1832                 TRACE_(d3d_caps)("[OK]\n");
1833                 return WINED3D_OK;
1834             } else {
1835                 TRACE_(d3d_caps)("[FAILED]\n");
1836                 return WINED3DERR_NOTAVAILABLE;
1837             }
1838
1839         default:
1840             break;
1841     }
1842
1843     TRACE_(d3d_caps)("[FAILED]\n");
1844     return WINED3DERR_NOTAVAILABLE;
1845 }
1846
1847 static HRESULT  WINAPI IWineD3DImpl_CheckDeviceFormatConversion(IWineD3D *iface, UINT Adapter, WINED3DDEVTYPE DeviceType,
1848                                                           WINED3DFORMAT SourceFormat, WINED3DFORMAT TargetFormat) {
1849     IWineD3DImpl *This = (IWineD3DImpl *)iface;
1850
1851     FIXME_(d3d_caps)("(%p)-> (STUB) (Adptr:%d, DevType:(%u,%s), SrcFmt:(%u,%s), TgtFmt:(%u,%s))\n",
1852           This,
1853           Adapter,
1854           DeviceType, debug_d3ddevicetype(DeviceType),
1855           SourceFormat, debug_d3dformat(SourceFormat),
1856           TargetFormat, debug_d3dformat(TargetFormat));
1857     return WINED3D_OK;
1858 }
1859
1860 /* Note: d3d8 passes in a pointer to a D3DCAPS8 structure, which is a true
1861       subset of a D3DCAPS9 structure. However, it has to come via a void *
1862       as the d3d8 interface cannot import the d3d9 header                  */
1863 static HRESULT WINAPI IWineD3DImpl_GetDeviceCaps(IWineD3D *iface, UINT Adapter, WINED3DDEVTYPE DeviceType, WINED3DCAPS* pCaps) {
1864
1865     IWineD3DImpl    *This = (IWineD3DImpl *)iface;
1866     int vs_selected_mode;
1867     int ps_selected_mode;
1868
1869     TRACE_(d3d_caps)("(%p)->(Adptr:%d, DevType: %x, pCaps: %p)\n", This, Adapter, DeviceType, pCaps);
1870
1871     if (Adapter >= IWineD3D_GetAdapterCount(iface)) {
1872         return WINED3DERR_INVALIDCALL;
1873     }
1874
1875     select_shader_mode(&Adapters[Adapter].gl_info, DeviceType, &ps_selected_mode, &vs_selected_mode);
1876
1877     /* This function should *not* be modifying GL caps
1878      * TODO: move the functionality where it belongs */
1879     select_shader_max_constants(ps_selected_mode, vs_selected_mode, &Adapters[Adapter].gl_info);
1880
1881     /* ------------------------------------------------
1882        The following fields apply to both d3d8 and d3d9
1883        ------------------------------------------------ */
1884     *pCaps->DeviceType              = (DeviceType == WINED3DDEVTYPE_HAL) ? WINED3DDEVTYPE_HAL : WINED3DDEVTYPE_REF;  /* Not quite true, but use h/w supported by opengl I suppose */
1885     *pCaps->AdapterOrdinal          = Adapter;
1886
1887     *pCaps->Caps                    = 0;
1888     *pCaps->Caps2                   = WINED3DCAPS2_CANRENDERWINDOWED |
1889                                       WINED3DCAPS2_FULLSCREENGAMMA |
1890                                       WINED3DCAPS2_DYNAMICTEXTURES;
1891     *pCaps->Caps3                   = WINED3DCAPS3_ALPHA_FULLSCREEN_FLIP_OR_DISCARD;
1892     *pCaps->PresentationIntervals   = WINED3DPRESENT_INTERVAL_IMMEDIATE;
1893
1894     *pCaps->CursorCaps              = WINED3DCURSORCAPS_COLOR            |
1895                                       WINED3DCURSORCAPS_LOWRES;
1896
1897     *pCaps->DevCaps                 = WINED3DDEVCAPS_FLOATTLVERTEX       |
1898                                       WINED3DDEVCAPS_EXECUTESYSTEMMEMORY |
1899                                       WINED3DDEVCAPS_TLVERTEXSYSTEMMEMORY|
1900                                       WINED3DDEVCAPS_TLVERTEXVIDEOMEMORY |
1901                                       WINED3DDEVCAPS_DRAWPRIMTLVERTEX    |
1902                                       WINED3DDEVCAPS_HWTRANSFORMANDLIGHT |
1903                                       WINED3DDEVCAPS_EXECUTEVIDEOMEMORY  |
1904                                       WINED3DDEVCAPS_PUREDEVICE          |
1905                                       WINED3DDEVCAPS_HWRASTERIZATION     |
1906                                       WINED3DDEVCAPS_TEXTUREVIDEOMEMORY  |
1907                                       WINED3DDEVCAPS_TEXTURESYSTEMMEMORY |
1908                                       WINED3DDEVCAPS_CANRENDERAFTERFLIP  |
1909                                       WINED3DDEVCAPS_DRAWPRIMITIVES2     |
1910                                       WINED3DDEVCAPS_DRAWPRIMITIVES2EX   |
1911                                       WINED3DDEVCAPS_RTPATCHES;
1912
1913     *pCaps->PrimitiveMiscCaps       = WINED3DPMISCCAPS_CULLNONE              |
1914                                       WINED3DPMISCCAPS_CULLCCW               |
1915                                       WINED3DPMISCCAPS_CULLCW                |
1916                                       WINED3DPMISCCAPS_COLORWRITEENABLE      |
1917                                       WINED3DPMISCCAPS_CLIPTLVERTS           |
1918                                       WINED3DPMISCCAPS_CLIPPLANESCALEDPOINTS |
1919                                       WINED3DPMISCCAPS_MASKZ                 |
1920                                       WINED3DPMISCCAPS_BLENDOP;
1921                                     /* TODO:
1922                                         WINED3DPMISCCAPS_NULLREFERENCE
1923                                         WINED3DPMISCCAPS_INDEPENDENTWRITEMASKS
1924                                         WINED3DPMISCCAPS_FOGANDSPECULARALPHA
1925                                         WINED3DPMISCCAPS_SEPARATEALPHABLEND
1926                                         WINED3DPMISCCAPS_MRTINDEPENDENTBITDEPTHS
1927                                         WINED3DPMISCCAPS_MRTPOSTPIXELSHADERBLENDING
1928                                         WINED3DPMISCCAPS_FOGVERTEXCLAMPED */
1929
1930 /* The caps below can be supported but aren't handled yet in utils.c 'd3dta_to_combiner_input', disable them until support is fixed */
1931 #if 0
1932     if (GL_SUPPORT(NV_REGISTER_COMBINERS))
1933         *pCaps->PrimitiveMiscCaps |=  WINED3DPMISCCAPS_TSSARGTEMP;
1934     if (GL_SUPPORT(NV_REGISTER_COMBINERS2))
1935         *pCaps->PrimitiveMiscCaps |=  WINED3DPMISCCAPS_PERSTAGECONSTANT;
1936 #endif
1937
1938     *pCaps->RasterCaps              = WINED3DPRASTERCAPS_DITHER    |
1939                                       WINED3DPRASTERCAPS_PAT       |
1940                                       WINED3DPRASTERCAPS_WFOG      |
1941                                       WINED3DPRASTERCAPS_ZFOG      |
1942                                       WINED3DPRASTERCAPS_FOGVERTEX |
1943                                       WINED3DPRASTERCAPS_FOGTABLE  |
1944                                       WINED3DPRASTERCAPS_FOGRANGE  |
1945                                       WINED3DPRASTERCAPS_STIPPLE   |
1946                                       WINED3DPRASTERCAPS_SUBPIXEL  |
1947                                       WINED3DPRASTERCAPS_ZTEST     |
1948                                       WINED3DPRASTERCAPS_SCISSORTEST   |
1949                                       WINED3DPRASTERCAPS_SLOPESCALEDEPTHBIAS |
1950                                       WINED3DPRASTERCAPS_DEPTHBIAS;
1951
1952     if (GL_SUPPORT(EXT_TEXTURE_FILTER_ANISOTROPIC)) {
1953       *pCaps->RasterCaps |= WINED3DPRASTERCAPS_ANISOTROPY    |
1954                             WINED3DPRASTERCAPS_ZBIAS         |
1955                             WINED3DPRASTERCAPS_MIPMAPLODBIAS;
1956     }
1957                         /* FIXME Add:
1958                            WINED3DPRASTERCAPS_COLORPERSPECTIVE
1959                            WINED3DPRASTERCAPS_STRETCHBLTMULTISAMPLE
1960                            WINED3DPRASTERCAPS_ANTIALIASEDGES
1961                            WINED3DPRASTERCAPS_ZBUFFERLESSHSR
1962                            WINED3DPRASTERCAPS_WBUFFER */
1963
1964     *pCaps->ZCmpCaps = WINED3DPCMPCAPS_ALWAYS       |
1965                        WINED3DPCMPCAPS_EQUAL        |
1966                        WINED3DPCMPCAPS_GREATER      |
1967                        WINED3DPCMPCAPS_GREATEREQUAL |
1968                        WINED3DPCMPCAPS_LESS         |
1969                        WINED3DPCMPCAPS_LESSEQUAL    |
1970                        WINED3DPCMPCAPS_NEVER        |
1971                        WINED3DPCMPCAPS_NOTEQUAL;
1972
1973     *pCaps->SrcBlendCaps  = WINED3DPBLENDCAPS_BLENDFACTOR     |
1974                             WINED3DPBLENDCAPS_BOTHINVSRCALPHA |
1975                             WINED3DPBLENDCAPS_BOTHSRCALPHA    |
1976                             WINED3DPBLENDCAPS_DESTALPHA       |
1977                             WINED3DPBLENDCAPS_DESTCOLOR       |
1978                             WINED3DPBLENDCAPS_INVDESTALPHA    |
1979                             WINED3DPBLENDCAPS_INVDESTCOLOR    |
1980                             WINED3DPBLENDCAPS_INVSRCALPHA     |
1981                             WINED3DPBLENDCAPS_INVSRCCOLOR     |
1982                             WINED3DPBLENDCAPS_ONE             |
1983                             WINED3DPBLENDCAPS_SRCALPHA        |
1984                             WINED3DPBLENDCAPS_SRCALPHASAT     |
1985                             WINED3DPBLENDCAPS_SRCCOLOR        |
1986                             WINED3DPBLENDCAPS_ZERO;
1987
1988     *pCaps->DestBlendCaps = WINED3DPBLENDCAPS_BLENDFACTOR     |
1989                             WINED3DPBLENDCAPS_BOTHINVSRCALPHA |
1990                             WINED3DPBLENDCAPS_BOTHSRCALPHA    |
1991                             WINED3DPBLENDCAPS_DESTALPHA       |
1992                             WINED3DPBLENDCAPS_DESTCOLOR       |
1993                             WINED3DPBLENDCAPS_INVDESTALPHA    |
1994                             WINED3DPBLENDCAPS_INVDESTCOLOR    |
1995                             WINED3DPBLENDCAPS_INVSRCALPHA     |
1996                             WINED3DPBLENDCAPS_INVSRCCOLOR     |
1997                             WINED3DPBLENDCAPS_ONE             |
1998                             WINED3DPBLENDCAPS_SRCALPHA        |
1999                             WINED3DPBLENDCAPS_SRCALPHASAT     |
2000                             WINED3DPBLENDCAPS_SRCCOLOR        |
2001                             WINED3DPBLENDCAPS_ZERO;
2002
2003     *pCaps->AlphaCmpCaps = WINED3DPCMPCAPS_ALWAYS       |
2004                            WINED3DPCMPCAPS_EQUAL        |
2005                            WINED3DPCMPCAPS_GREATER      |
2006                            WINED3DPCMPCAPS_GREATEREQUAL |
2007                            WINED3DPCMPCAPS_LESS         |
2008                            WINED3DPCMPCAPS_LESSEQUAL    |
2009                            WINED3DPCMPCAPS_NEVER        |
2010                            WINED3DPCMPCAPS_NOTEQUAL;
2011
2012     *pCaps->ShadeCaps     = WINED3DPSHADECAPS_SPECULARGOURAUDRGB |
2013                             WINED3DPSHADECAPS_COLORGOURAUDRGB    |
2014                             WINED3DPSHADECAPS_ALPHAFLATBLEND     |
2015                             WINED3DPSHADECAPS_ALPHAGOURAUDBLEND  |
2016                             WINED3DPSHADECAPS_COLORFLATRGB       |
2017                             WINED3DPSHADECAPS_FOGFLAT            |
2018                             WINED3DPSHADECAPS_FOGGOURAUD         |
2019                             WINED3DPSHADECAPS_SPECULARFLATRGB;
2020
2021     *pCaps->TextureCaps =  WINED3DPTEXTURECAPS_ALPHA              |
2022                            WINED3DPTEXTURECAPS_ALPHAPALETTE       |
2023                            WINED3DPTEXTURECAPS_BORDER             |
2024                            WINED3DPTEXTURECAPS_MIPMAP             |
2025                            WINED3DPTEXTURECAPS_PROJECTED          |
2026                            WINED3DPTEXTURECAPS_PERSPECTIVE        |
2027                            WINED3DPTEXTURECAPS_NONPOW2CONDITIONAL;
2028
2029     if( GL_SUPPORT(EXT_TEXTURE3D)) {
2030         *pCaps->TextureCaps |=  WINED3DPTEXTURECAPS_VOLUMEMAP      |
2031                                 WINED3DPTEXTURECAPS_MIPVOLUMEMAP   |
2032                                 WINED3DPTEXTURECAPS_VOLUMEMAP_POW2;
2033     }
2034
2035     if (GL_SUPPORT(ARB_TEXTURE_CUBE_MAP)) {
2036         *pCaps->TextureCaps |= WINED3DPTEXTURECAPS_CUBEMAP     |
2037                              WINED3DPTEXTURECAPS_MIPCUBEMAP    |
2038                              WINED3DPTEXTURECAPS_CUBEMAP_POW2;
2039
2040     }
2041
2042     *pCaps->TextureFilterCaps = WINED3DPTFILTERCAPS_MAGFLINEAR       |
2043                                 WINED3DPTFILTERCAPS_MAGFPOINT        |
2044                                 WINED3DPTFILTERCAPS_MINFLINEAR       |
2045                                 WINED3DPTFILTERCAPS_MINFPOINT        |
2046                                 WINED3DPTFILTERCAPS_MIPFLINEAR       |
2047                                 WINED3DPTFILTERCAPS_MIPFPOINT        |
2048                                 WINED3DPTFILTERCAPS_LINEAR           |
2049                                 WINED3DPTFILTERCAPS_LINEARMIPLINEAR  |
2050                                 WINED3DPTFILTERCAPS_LINEARMIPNEAREST |
2051                                 WINED3DPTFILTERCAPS_MIPLINEAR        |
2052                                 WINED3DPTFILTERCAPS_MIPNEAREST       |
2053                                 WINED3DPTFILTERCAPS_NEAREST;
2054
2055     if (GL_SUPPORT(EXT_TEXTURE_FILTER_ANISOTROPIC)) {
2056         *pCaps->TextureFilterCaps |= WINED3DPTFILTERCAPS_MAGFANISOTROPIC |
2057                                      WINED3DPTFILTERCAPS_MINFANISOTROPIC;
2058     }
2059
2060     if (GL_SUPPORT(ARB_TEXTURE_CUBE_MAP)) {
2061         *pCaps->CubeTextureFilterCaps = WINED3DPTFILTERCAPS_MAGFLINEAR       |
2062                                         WINED3DPTFILTERCAPS_MAGFPOINT        |
2063                                         WINED3DPTFILTERCAPS_MINFLINEAR       |
2064                                         WINED3DPTFILTERCAPS_MINFPOINT        |
2065                                         WINED3DPTFILTERCAPS_MIPFLINEAR       |
2066                                         WINED3DPTFILTERCAPS_MIPFPOINT        |
2067                                         WINED3DPTFILTERCAPS_LINEAR           |
2068                                         WINED3DPTFILTERCAPS_LINEARMIPLINEAR  |
2069                                         WINED3DPTFILTERCAPS_LINEARMIPNEAREST |
2070                                         WINED3DPTFILTERCAPS_MIPLINEAR        |
2071                                         WINED3DPTFILTERCAPS_MIPNEAREST       |
2072                                         WINED3DPTFILTERCAPS_NEAREST;
2073
2074         if (GL_SUPPORT(EXT_TEXTURE_FILTER_ANISOTROPIC)) {
2075             *pCaps->CubeTextureFilterCaps |= WINED3DPTFILTERCAPS_MAGFANISOTROPIC |
2076                                             WINED3DPTFILTERCAPS_MINFANISOTROPIC;
2077         }
2078     } else
2079         *pCaps->CubeTextureFilterCaps = 0;
2080
2081     if (GL_SUPPORT(EXT_TEXTURE3D)) {
2082         *pCaps->VolumeTextureFilterCaps = WINED3DPTFILTERCAPS_MAGFLINEAR       |
2083                                           WINED3DPTFILTERCAPS_MAGFPOINT        |
2084                                           WINED3DPTFILTERCAPS_MINFLINEAR       |
2085                                           WINED3DPTFILTERCAPS_MINFPOINT        |
2086                                           WINED3DPTFILTERCAPS_MIPFLINEAR       |
2087                                           WINED3DPTFILTERCAPS_MIPFPOINT        |
2088                                           WINED3DPTFILTERCAPS_LINEAR           |
2089                                           WINED3DPTFILTERCAPS_LINEARMIPLINEAR  |
2090                                           WINED3DPTFILTERCAPS_LINEARMIPNEAREST |
2091                                           WINED3DPTFILTERCAPS_MIPLINEAR        |
2092                                           WINED3DPTFILTERCAPS_MIPNEAREST       |
2093                                           WINED3DPTFILTERCAPS_NEAREST;
2094     } else
2095         *pCaps->VolumeTextureFilterCaps = 0;
2096
2097     *pCaps->TextureAddressCaps =  WINED3DPTADDRESSCAPS_INDEPENDENTUV |
2098                                   WINED3DPTADDRESSCAPS_CLAMP  |
2099                                   WINED3DPTADDRESSCAPS_WRAP;
2100
2101     if (GL_SUPPORT(ARB_TEXTURE_BORDER_CLAMP)) {
2102         *pCaps->TextureAddressCaps |= WINED3DPTADDRESSCAPS_BORDER;
2103     }
2104     if (GL_SUPPORT(ARB_TEXTURE_MIRRORED_REPEAT)) {
2105         *pCaps->TextureAddressCaps |= WINED3DPTADDRESSCAPS_MIRROR;
2106     }
2107     if (GL_SUPPORT(ATI_TEXTURE_MIRROR_ONCE)) {
2108         *pCaps->TextureAddressCaps |= WINED3DPTADDRESSCAPS_MIRRORONCE;
2109     }
2110
2111     if (GL_SUPPORT(EXT_TEXTURE3D)) {
2112         *pCaps->VolumeTextureAddressCaps =  WINED3DPTADDRESSCAPS_INDEPENDENTUV |
2113                                             WINED3DPTADDRESSCAPS_CLAMP  |
2114                                             WINED3DPTADDRESSCAPS_WRAP;
2115         if (GL_SUPPORT(ARB_TEXTURE_BORDER_CLAMP)) {
2116             *pCaps->VolumeTextureAddressCaps |= WINED3DPTADDRESSCAPS_BORDER;
2117         }
2118         if (GL_SUPPORT(ARB_TEXTURE_MIRRORED_REPEAT)) {
2119             *pCaps->VolumeTextureAddressCaps |= WINED3DPTADDRESSCAPS_MIRROR;
2120         }
2121         if (GL_SUPPORT(ATI_TEXTURE_MIRROR_ONCE)) {
2122             *pCaps->VolumeTextureAddressCaps |= WINED3DPTADDRESSCAPS_MIRRORONCE;
2123         }
2124     } else
2125         *pCaps->VolumeTextureAddressCaps = 0;
2126
2127     *pCaps->LineCaps = WINED3DLINECAPS_TEXTURE |
2128                        WINED3DLINECAPS_ZTEST;
2129                       /* FIXME: Add
2130                         WINED3DLINECAPS_BLEND
2131                         WINED3DLINECAPS_ALPHACMP
2132                         WINED3DLINECAPS_FOG */
2133
2134     *pCaps->MaxTextureWidth  = GL_LIMITS(texture_size);
2135     *pCaps->MaxTextureHeight = GL_LIMITS(texture_size);
2136
2137     if(GL_SUPPORT(EXT_TEXTURE3D))
2138         *pCaps->MaxVolumeExtent = GL_LIMITS(texture3d_size);
2139     else
2140         *pCaps->MaxVolumeExtent = 0;
2141
2142     *pCaps->MaxTextureRepeat = 32768;
2143     *pCaps->MaxTextureAspectRatio = GL_LIMITS(texture_size);
2144     *pCaps->MaxVertexW = 1.0;
2145
2146     *pCaps->GuardBandLeft = 0;
2147     *pCaps->GuardBandTop = 0;
2148     *pCaps->GuardBandRight = 0;
2149     *pCaps->GuardBandBottom = 0;
2150
2151     *pCaps->ExtentsAdjust = 0;
2152
2153     *pCaps->StencilCaps =  WINED3DSTENCILCAPS_DECRSAT |
2154                            WINED3DSTENCILCAPS_INCRSAT |
2155                            WINED3DSTENCILCAPS_INVERT  |
2156                            WINED3DSTENCILCAPS_KEEP    |
2157                            WINED3DSTENCILCAPS_REPLACE |
2158                            WINED3DSTENCILCAPS_ZERO;
2159     if (GL_SUPPORT(EXT_STENCIL_WRAP)) {
2160       *pCaps->StencilCaps |= WINED3DSTENCILCAPS_DECR  |
2161                              WINED3DSTENCILCAPS_INCR;
2162     }
2163     if ( This->dxVersion > 8 &&
2164         ( GL_SUPPORT(EXT_STENCIL_TWO_SIDE) ||
2165             GL_SUPPORT(ATI_SEPARATE_STENCIL) ) ) {
2166         *pCaps->StencilCaps |= WINED3DSTENCILCAPS_TWOSIDED;
2167     }
2168
2169     *pCaps->FVFCaps = WINED3DFVFCAPS_PSIZE | 0x0008; /* 8 texture coords */
2170
2171     *pCaps->TextureOpCaps =  WINED3DTEXOPCAPS_ADD         |
2172                              WINED3DTEXOPCAPS_ADDSIGNED   |
2173                              WINED3DTEXOPCAPS_ADDSIGNED2X |
2174                              WINED3DTEXOPCAPS_MODULATE    |
2175                              WINED3DTEXOPCAPS_MODULATE2X  |
2176                              WINED3DTEXOPCAPS_MODULATE4X  |
2177                              WINED3DTEXOPCAPS_SELECTARG1  |
2178                              WINED3DTEXOPCAPS_SELECTARG2  |
2179                              WINED3DTEXOPCAPS_DISABLE;
2180
2181     if (GL_SUPPORT(ARB_TEXTURE_ENV_COMBINE) ||
2182         GL_SUPPORT(EXT_TEXTURE_ENV_COMBINE) ||
2183         GL_SUPPORT(NV_TEXTURE_ENV_COMBINE4)) {
2184         *pCaps->TextureOpCaps |= WINED3DTEXOPCAPS_BLENDDIFFUSEALPHA |
2185                                 WINED3DTEXOPCAPS_BLENDTEXTUREALPHA  |
2186                                 WINED3DTEXOPCAPS_BLENDFACTORALPHA   |
2187                                 WINED3DTEXOPCAPS_BLENDCURRENTALPHA  |
2188                                 WINED3DTEXOPCAPS_LERP               |
2189                                 WINED3DTEXOPCAPS_SUBTRACT;
2190     }
2191     if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3) ||
2192          GL_SUPPORT(NV_TEXTURE_ENV_COMBINE4)) {
2193         *pCaps->TextureOpCaps |= WINED3DTEXOPCAPS_ADDSMOOTH             |
2194                                 WINED3DTEXOPCAPS_MULTIPLYADD            |
2195                                 WINED3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR |
2196                                 WINED3DTEXOPCAPS_MODULATECOLOR_ADDALPHA |
2197                                 WINED3DTEXOPCAPS_BLENDTEXTUREALPHAPM;
2198     }
2199     if (GL_SUPPORT(ARB_TEXTURE_ENV_DOT3))
2200         *pCaps->TextureOpCaps |= WINED3DTEXOPCAPS_DOTPRODUCT3;
2201
2202     if (GL_SUPPORT(NV_REGISTER_COMBINERS)) {
2203         *pCaps->TextureOpCaps |= WINED3DTEXOPCAPS_MODULATEINVALPHA_ADDCOLOR |
2204                                  WINED3DTEXOPCAPS_MODULATEINVCOLOR_ADDALPHA;
2205     }
2206
2207     if(GL_SUPPORT(ATI_ENVMAP_BUMPMAP)) {
2208         *pCaps->TextureOpCaps |= WINED3DTEXOPCAPS_BUMPENVMAP;
2209     } else if(GL_SUPPORT(NV_TEXTURE_SHADER2)) {
2210         /* Bump mapping is supported already in NV_TEXTURE_SHADER, but that extension does
2211          * not support 3D textures. This asks for trouble if an app uses both bump mapping
2212          * and 3D textures. It also allows us to keep the code simpler by having texture
2213          * shaders constantly enabled.
2214          */
2215         *pCaps->TextureOpCaps |= WINED3DTEXOPCAPS_BUMPENVMAP;
2216         /* TODO: Luminance bump map? */
2217     }
2218 #if 0
2219     /* FIXME: Add
2220     *pCaps->TextureOpCaps |= WINED3DTEXOPCAPS_BUMPENVMAPLUMINANCE
2221                              WINED3DTEXOPCAPS_PREMODULATE */
2222 #endif
2223
2224     *pCaps->MaxTextureBlendStages   = GL_LIMITS(texture_stages);
2225     *pCaps->MaxSimultaneousTextures = GL_LIMITS(textures);
2226     *pCaps->MaxUserClipPlanes       = GL_LIMITS(clipplanes);
2227     *pCaps->MaxActiveLights         = GL_LIMITS(lights);
2228
2229     *pCaps->MaxVertexBlendMatrices      = GL_LIMITS(blends);
2230     *pCaps->MaxVertexBlendMatrixIndex   = 0;
2231
2232     *pCaps->MaxAnisotropy   = GL_LIMITS(anisotropy);
2233     *pCaps->MaxPointSize    = GL_LIMITS(pointsize);
2234
2235
2236     *pCaps->VertexProcessingCaps = WINED3DVTXPCAPS_DIRECTIONALLIGHTS |
2237                                    WINED3DVTXPCAPS_MATERIALSOURCE7   |
2238                                    WINED3DVTXPCAPS_POSITIONALLIGHTS  |
2239                                    WINED3DVTXPCAPS_LOCALVIEWER       |
2240                                    WINED3DVTXPCAPS_VERTEXFOG         |
2241                                    WINED3DVTXPCAPS_TEXGEN;
2242                                   /* FIXME: Add 
2243                                      D3DVTXPCAPS_TWEENING, D3DVTXPCAPS_TEXGEN_SPHEREMAP */
2244
2245     *pCaps->MaxPrimitiveCount   = 0xFFFFF; /* For now set 2^20-1 which is used by most >=Geforce3/Radeon8500 cards */
2246     *pCaps->MaxVertexIndex      = 0xFFFFF;
2247     *pCaps->MaxStreams          = MAX_STREAMS;
2248     *pCaps->MaxStreamStride     = 1024;
2249
2250     if (vs_selected_mode == SHADER_GLSL) {
2251         /* Nvidia Geforce6/7 or Ati R4xx/R5xx cards with GLSL support, support VS 3.0 but older Nvidia/Ati
2252            models with GLSL support only support 2.0. In case of nvidia we can detect VS 2.0 support using
2253            vs_nv_version which is based on NV_vertex_program. For Ati cards there's no easy way, so for
2254            now only support 2.0/3.0 detection on Nvidia GeforceFX cards and default to 3.0 for everything else */
2255         if(GLINFO_LOCATION.vs_nv_version == VS_VERSION_20)
2256             *pCaps->VertexShaderVersion = WINED3DVS_VERSION(2,0);
2257         else
2258             *pCaps->VertexShaderVersion = WINED3DVS_VERSION(3,0);
2259         TRACE_(d3d_caps)("Hardware vertex shader version 3.0 enabled (GLSL)\n");
2260     } else if (vs_selected_mode == SHADER_ARB) {
2261         *pCaps->VertexShaderVersion = WINED3DVS_VERSION(1,1);
2262         TRACE_(d3d_caps)("Hardware vertex shader version 1.1 enabled (ARB_PROGRAM)\n");
2263     } else {
2264         *pCaps->VertexShaderVersion  = 0;
2265         TRACE_(d3d_caps)("Vertex shader functionality not available\n");
2266     }
2267
2268     *pCaps->MaxVertexShaderConst = GL_LIMITS(vshader_constantsF);
2269
2270     if (ps_selected_mode == SHADER_GLSL) {
2271         /* See the comment about VS2.0/VS3.0 detection as we do the same here but then based on NV_fragment_program
2272            in case of GeforceFX cards. */
2273         if(GLINFO_LOCATION.ps_nv_version == PS_VERSION_20)
2274             *pCaps->PixelShaderVersion = WINED3DPS_VERSION(2,0);
2275         else
2276             *pCaps->PixelShaderVersion = WINED3DPS_VERSION(3,0);
2277         /* FIXME: The following line is card dependent. -1.0 to 1.0 is a safe default clamp range for now */
2278         *pCaps->PixelShader1xMaxValue = 1.0;
2279         TRACE_(d3d_caps)("Hardware pixel shader version 3.0 enabled (GLSL)\n");
2280     } else if (ps_selected_mode == SHADER_ARB) {
2281         *pCaps->PixelShaderVersion    = WINED3DPS_VERSION(1,4);
2282         *pCaps->PixelShader1xMaxValue = 1.0;
2283         TRACE_(d3d_caps)("Hardware pixel shader version 1.4 enabled (ARB_PROGRAM)\n");
2284     } else {
2285         *pCaps->PixelShaderVersion    = 0;
2286         *pCaps->PixelShader1xMaxValue = 0.0;
2287         TRACE_(d3d_caps)("Pixel shader functionality not available\n");
2288     }
2289
2290     /* ------------------------------------------------
2291        The following fields apply to d3d9 only
2292        ------------------------------------------------ */
2293     if (This->dxVersion > 8) {
2294         /* d3d9.dll sets D3DDEVCAPS2_CAN_STRETCHRECT_FROM_TEXTURES here because StretchRects is implemented in d3d9 */
2295         *pCaps->DevCaps2                          = WINED3DDEVCAPS2_STREAMOFFSET;
2296         /* TODO: VS3.0 needs at least D3DDEVCAPS2_VERTEXELEMENTSCANSHARESTREAMOFFSET */
2297         *pCaps->MaxNpatchTessellationLevel        = 0;
2298         *pCaps->MasterAdapterOrdinal              = 0;
2299         *pCaps->AdapterOrdinalInGroup             = 0;
2300         *pCaps->NumberOfAdaptersInGroup           = 1;
2301
2302         if(*pCaps->VertexShaderVersion >= WINED3DVS_VERSION(2,0)) {
2303             /* OpenGL supports all the formats below, perhaps not always
2304              * without conversion, but it supports them.
2305              * Further GLSL doesn't seem to have an official unsigned type so
2306              * don't advertise it yet as I'm not sure how we handle it.
2307              * We might need to add some clamping in the shader engine to
2308              * support it.
2309              * TODO: WINED3DDTCAPS_USHORT2N, WINED3DDTCAPS_USHORT4N, WINED3DDTCAPS_UDEC3, WINED3DDTCAPS_DEC3N */
2310             *pCaps->DeclTypes = WINED3DDTCAPS_UBYTE4    |
2311                                 WINED3DDTCAPS_UBYTE4N   |
2312                                 WINED3DDTCAPS_SHORT2N   |
2313                                 WINED3DDTCAPS_SHORT4N;
2314             if (GL_SUPPORT(NV_HALF_FLOAT)) {
2315                 *pCaps->DeclTypes |=
2316                                 WINED3DDTCAPS_FLOAT16_2 |
2317                                 WINED3DDTCAPS_FLOAT16_4;
2318             }
2319         } else
2320             *pCaps->DeclTypes                         = 0;
2321
2322         *pCaps->NumSimultaneousRTs = GL_LIMITS(buffers);
2323
2324             
2325         *pCaps->StretchRectFilterCaps             = WINED3DPTFILTERCAPS_MINFPOINT  |
2326                                                     WINED3DPTFILTERCAPS_MAGFPOINT  |
2327                                                     WINED3DPTFILTERCAPS_MINFLINEAR |
2328                                                     WINED3DPTFILTERCAPS_MAGFLINEAR;
2329         *pCaps->VertexTextureFilterCaps           = 0;
2330         
2331         if(*pCaps->VertexShaderVersion == WINED3DVS_VERSION(3,0)) {
2332             /* Where possible set the caps based on OpenGL extensions and if they aren't set (in case of software rendering)
2333                use the VS 3.0 from MSDN or else if there's OpenGL spec use a hardcoded value minimum VS3.0 value. */
2334             *pCaps->VS20Caps.Caps                     = WINED3DVS20CAPS_PREDICATION;
2335             *pCaps->VS20Caps.DynamicFlowControlDepth  = WINED3DVS20_MAX_DYNAMICFLOWCONTROLDEPTH; /* VS 3.0 requires MAX_DYNAMICFLOWCONTROLDEPTH (24) */
2336             *pCaps->VS20Caps.NumTemps                 = max(32, GLINFO_LOCATION.vs_arb_max_temps);
2337             *pCaps->VS20Caps.StaticFlowControlDepth   = WINED3DVS20_MAX_STATICFLOWCONTROLDEPTH ; /* level of nesting in loops / if-statements; VS 3.0 requires MAX (4) */
2338
2339             *pCaps->MaxVShaderInstructionsExecuted    = 65535; /* VS 3.0 needs at least 65535, some cards even use 2^32-1 */
2340             *pCaps->MaxVertexShader30InstructionSlots = max(512, GLINFO_LOCATION.vs_arb_max_instructions);
2341         } else if(*pCaps->VertexShaderVersion == WINED3DVS_VERSION(2,0)) {
2342             *pCaps->VS20Caps.Caps                     = 0;
2343             *pCaps->VS20Caps.DynamicFlowControlDepth  = WINED3DVS20_MIN_DYNAMICFLOWCONTROLDEPTH;
2344             *pCaps->VS20Caps.NumTemps                 = max(12, GLINFO_LOCATION.vs_arb_max_temps);
2345             *pCaps->VS20Caps.StaticFlowControlDepth   = 1;    
2346
2347             *pCaps->MaxVShaderInstructionsExecuted    = 65535;
2348             *pCaps->MaxVertexShader30InstructionSlots = 0;
2349         } else { /* VS 1.x */
2350             *pCaps->VS20Caps.Caps                     = 0;
2351             *pCaps->VS20Caps.DynamicFlowControlDepth  = 0;
2352             *pCaps->VS20Caps.NumTemps                 = 0;
2353             *pCaps->VS20Caps.StaticFlowControlDepth   = 0;    
2354
2355             *pCaps->MaxVShaderInstructionsExecuted    = 0;
2356             *pCaps->MaxVertexShader30InstructionSlots = 0;        
2357         }
2358
2359         if(*pCaps->PixelShaderVersion == WINED3DPS_VERSION(3,0)) {
2360             /* Where possible set the caps based on OpenGL extensions and if they aren't set (in case of software rendering)
2361                use the PS 3.0 from MSDN or else if there's OpenGL spec use a hardcoded value minimum PS 3.0 value. */
2362             
2363             /* Caps is more or less undocumented on MSDN but it appears to be used for PS20Caps based on results from R9600/FX5900/Geforce6800 cards from Windows */
2364             *pCaps->PS20Caps.Caps                     = WINED3DPS20CAPS_ARBITRARYSWIZZLE     |
2365                                                         WINED3DPS20CAPS_GRADIENTINSTRUCTIONS |
2366                                                         WINED3DPS20CAPS_PREDICATION          |
2367                                                         WINED3DPS20CAPS_NODEPENDENTREADLIMIT |
2368                                                         WINED3DPS20CAPS_NOTEXINSTRUCTIONLIMIT;
2369             *pCaps->PS20Caps.DynamicFlowControlDepth  = WINED3DPS20_MAX_DYNAMICFLOWCONTROLDEPTH; /* PS 3.0 requires MAX_DYNAMICFLOWCONTROLDEPTH (24) */
2370             *pCaps->PS20Caps.NumTemps                 = max(32, GLINFO_LOCATION.ps_arb_max_temps);
2371             *pCaps->PS20Caps.StaticFlowControlDepth   = WINED3DPS20_MAX_STATICFLOWCONTROLDEPTH; /* PS 3.0 requires MAX_STATICFLOWCONTROLDEPTH (4) */
2372             *pCaps->PS20Caps.NumInstructionSlots      = WINED3DPS20_MAX_NUMINSTRUCTIONSLOTS; /* PS 3.0 requires MAX_NUMINSTRUCTIONSLOTS (512) */
2373
2374             *pCaps->MaxPShaderInstructionsExecuted    = 65535;
2375             *pCaps->MaxPixelShader30InstructionSlots  = max(WINED3DMIN30SHADERINSTRUCTIONS, GLINFO_LOCATION.ps_arb_max_instructions);
2376         } else if(*pCaps->PixelShaderVersion == WINED3DPS_VERSION(2,0)) {
2377             /* Below we assume PS2.0 specs, not extended 2.0a(GeforceFX)/2.0b(Radeon R3xx) ones */
2378             *pCaps->PS20Caps.Caps                     = 0;
2379             *pCaps->PS20Caps.DynamicFlowControlDepth  = 0; /* WINED3DVS20_MIN_DYNAMICFLOWCONTROLDEPTH = 0 */
2380             *pCaps->PS20Caps.NumTemps                 = max(12, GLINFO_LOCATION.ps_arb_max_temps);
2381             *pCaps->PS20Caps.StaticFlowControlDepth   = WINED3DPS20_MIN_STATICFLOWCONTROLDEPTH; /* Minumum: 1 */
2382             *pCaps->PS20Caps.NumInstructionSlots      = WINED3DPS20_MIN_NUMINSTRUCTIONSLOTS; /* Minimum number (64 ALU + 32 Texture), a GeforceFX uses 512 */
2383
2384             *pCaps->MaxPShaderInstructionsExecuted    = 512; /* Minimum value, a GeforceFX uses 1024 */
2385             *pCaps->MaxPixelShader30InstructionSlots  = 0;
2386         } else { /* PS 1.x */
2387             *pCaps->PS20Caps.Caps                     = 0;
2388             *pCaps->PS20Caps.DynamicFlowControlDepth  = 0;
2389             *pCaps->PS20Caps.NumTemps                 = 0;
2390             *pCaps->PS20Caps.StaticFlowControlDepth   = 0;
2391             *pCaps->PS20Caps.NumInstructionSlots      = 0;
2392
2393             *pCaps->MaxPShaderInstructionsExecuted    = 0;
2394             *pCaps->MaxPixelShader30InstructionSlots  = 0;
2395         }
2396     }
2397
2398     return WINED3D_OK;
2399 }
2400
2401 static unsigned int glsl_program_key_hash(void *key) {
2402     glsl_program_key_t *k = (glsl_program_key_t *)key;
2403
2404     unsigned int hash = k->vshader | k->pshader << 16;
2405     hash += ~(hash << 15);
2406     hash ^=  (hash >> 10);
2407     hash +=  (hash << 3);
2408     hash ^=  (hash >> 6);
2409     hash += ~(hash << 11);
2410     hash ^=  (hash >> 16);
2411
2412     return hash;
2413 }
2414
2415 static BOOL glsl_program_key_compare(void *keya, void *keyb) {
2416     glsl_program_key_t *ka = (glsl_program_key_t *)keya;
2417     glsl_program_key_t *kb = (glsl_program_key_t *)keyb;
2418
2419     return ka->vshader == kb->vshader && ka->pshader == kb->pshader;
2420 }
2421
2422 /* Note due to structure differences between dx8 and dx9 D3DPRESENT_PARAMETERS,
2423    and fields being inserted in the middle, a new structure is used in place    */
2424 static HRESULT  WINAPI IWineD3DImpl_CreateDevice(IWineD3D *iface, UINT Adapter, WINED3DDEVTYPE DeviceType, HWND hFocusWindow,
2425                                            DWORD BehaviourFlags, IWineD3DDevice** ppReturnedDeviceInterface,
2426                                            IUnknown *parent) {
2427
2428     IWineD3DDeviceImpl *object  = NULL;
2429     IWineD3DImpl       *This    = (IWineD3DImpl *)iface;
2430     HDC hDC;
2431     int i;
2432
2433     /* Validate the adapter number. If no adapters are available(no GL), ignore the adapter
2434      * number and create a device without a 3D adapter for 2D only operation.
2435      */
2436     if (IWineD3D_GetAdapterCount(iface) && Adapter >= IWineD3D_GetAdapterCount(iface)) {
2437         return WINED3DERR_INVALIDCALL;
2438     }
2439
2440     /* Create a WineD3DDevice object */
2441     object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IWineD3DDeviceImpl));
2442     *ppReturnedDeviceInterface = (IWineD3DDevice *)object;
2443     TRACE("Created WineD3DDevice object @ %p\n", object);
2444     if (NULL == object) {
2445       return WINED3DERR_OUTOFVIDEOMEMORY;
2446     }
2447
2448     /* Set up initial COM information */
2449     object->lpVtbl  = &IWineD3DDevice_Vtbl;
2450     object->ref     = 1;
2451     object->wineD3D = iface;
2452     object->adapter = numAdapters ? &Adapters[Adapter] : NULL;
2453     IWineD3D_AddRef(object->wineD3D);
2454     object->parent  = parent;
2455
2456     if(This->dxVersion == 7) {
2457         object->surface_alignment = 8;
2458     } else {
2459         object->surface_alignment = 4;
2460     }
2461
2462     /* Set the state up as invalid until the device is fully created */
2463     object->state   = WINED3DERR_DRIVERINTERNALERROR;
2464
2465     TRACE("(%p)->(Adptr:%d, DevType: %x, FocusHwnd: %p, BehFlags: %x, RetDevInt: %p)\n", This, Adapter, DeviceType,
2466           hFocusWindow, BehaviourFlags, ppReturnedDeviceInterface);
2467
2468     /* Save the creation parameters */
2469     object->createParms.AdapterOrdinal = Adapter;
2470     object->createParms.DeviceType     = DeviceType;
2471     object->createParms.hFocusWindow   = hFocusWindow;
2472     object->createParms.BehaviorFlags  = BehaviourFlags;
2473
2474     /* Initialize other useful values */
2475     object->adapterNo                    = Adapter;
2476     object->devType                      = DeviceType;
2477
2478     select_shader_mode(&GLINFO_LOCATION, DeviceType, &object->ps_selected_mode, &object->vs_selected_mode);
2479     if (object->ps_selected_mode == SHADER_GLSL || object->vs_selected_mode == SHADER_GLSL) {
2480         object->shader_backend = &glsl_shader_backend;
2481         object->glsl_program_lookup = hash_table_create(&glsl_program_key_hash, &glsl_program_key_compare);
2482     } else if (object->ps_selected_mode == SHADER_ARB || object->vs_selected_mode == SHADER_ARB) {
2483         object->shader_backend = &arb_program_shader_backend;
2484     } else {
2485         object->shader_backend = &none_shader_backend;
2486     }
2487
2488     /* set the state of the device to valid */
2489     object->state = WINED3D_OK;
2490
2491     /* Get the initial screen setup for ddraw */
2492     object->ddraw_width = GetSystemMetrics(SM_CXSCREEN);
2493     object->ddraw_height = GetSystemMetrics(SM_CYSCREEN);
2494     hDC = GetDC(0);
2495     object->ddraw_format = pixelformat_for_depth(GetDeviceCaps(hDC, BITSPIXEL) * GetDeviceCaps(hDC, PLANES));
2496     ReleaseDC(0, hDC);
2497
2498     for(i = 0; i < PATCHMAP_SIZE; i++) {
2499         list_init(&object->patches[i]);
2500     }
2501     return WINED3D_OK;
2502 }
2503 #undef GLINFO_LOCATION
2504
2505 static HRESULT WINAPI IWineD3DImpl_GetParent(IWineD3D *iface, IUnknown **pParent) {
2506     IWineD3DImpl *This = (IWineD3DImpl *)iface;
2507     IUnknown_AddRef(This->parent);
2508     *pParent = This->parent;
2509     return WINED3D_OK;
2510 }
2511
2512 ULONG WINAPI D3DCB_DefaultDestroySurface(IWineD3DSurface *pSurface) {
2513     IUnknown* surfaceParent;
2514     TRACE("(%p) call back\n", pSurface);
2515
2516     /* Now, release the parent, which will take care of cleaning up the surface for us */
2517     IWineD3DSurface_GetParent(pSurface, &surfaceParent);
2518     IUnknown_Release(surfaceParent);
2519     return IUnknown_Release(surfaceParent);
2520 }
2521
2522 ULONG WINAPI D3DCB_DefaultDestroyVolume(IWineD3DVolume *pVolume) {
2523     IUnknown* volumeParent;
2524     TRACE("(%p) call back\n", pVolume);
2525
2526     /* Now, release the parent, which will take care of cleaning up the volume for us */
2527     IWineD3DVolume_GetParent(pVolume, &volumeParent);
2528     IUnknown_Release(volumeParent);
2529     return IUnknown_Release(volumeParent);
2530 }
2531
2532 #define GLINFO_LOCATION (Adapters[0].gl_info)
2533 BOOL InitAdapters(void) {
2534     BOOL ret;
2535     int ps_selected_mode, vs_selected_mode;
2536
2537     /* No need to hold any lock. The calling library makes sure only one thread calls
2538      * wined3d simultaneously
2539      */
2540     if(numAdapters > 0) return TRUE;
2541
2542     TRACE("Initializing adapters\n");
2543     /* For now only one default adapter */
2544     {
2545         int attribute;
2546         TRACE("Initializing default adapter\n");
2547         Adapters[0].monitorPoint.x = -1;
2548         Adapters[0].monitorPoint.y = -1;
2549
2550         ret = IWineD3DImpl_FillGLCaps(&Adapters[0].gl_info);
2551         if(!ret) {
2552             ERR("Failed to initialize gl caps for default adapter\n");
2553             HeapFree(GetProcessHeap(), 0, Adapters);
2554             return FALSE;
2555         }
2556         ret = initPixelFormats(&Adapters[0].gl_info);
2557         if(!ret) {
2558             ERR("Failed to init gl formats\n");
2559             HeapFree(GetProcessHeap(), 0, Adapters);
2560             return FALSE;
2561         }
2562
2563         Adapters[0].driver = "Display";
2564         Adapters[0].description = "Direct3D HAL";
2565
2566         if (WineD3D_CreateFakeGLContext()) {
2567             attribute = WGL_NUMBER_PIXEL_FORMATS_ARB;
2568             GL_EXTCALL(wglGetPixelFormatAttribivARB(wined3d_fake_gl_context_hdc, 0, 0, 1, &attribute, &Adapters[0].nCfgs));
2569             WineD3D_ReleaseFakeGLContext();
2570         }
2571
2572         select_shader_mode(&Adapters[0].gl_info, WINED3DDEVTYPE_HAL, &ps_selected_mode, &vs_selected_mode);
2573         select_shader_max_constants(ps_selected_mode, vs_selected_mode, &Adapters[0].gl_info);
2574
2575     }
2576     numAdapters = 1;
2577     TRACE("%d adapters successfully initialized\n", numAdapters);
2578
2579     return TRUE;
2580 }
2581 #undef GLINFO_LOCATION
2582
2583 /**********************************************************
2584  * IWineD3D VTbl follows
2585  **********************************************************/
2586
2587 const IWineD3DVtbl IWineD3D_Vtbl =
2588 {
2589     /* IUnknown */
2590     IWineD3DImpl_QueryInterface,
2591     IWineD3DImpl_AddRef,
2592     IWineD3DImpl_Release,
2593     /* IWineD3D */
2594     IWineD3DImpl_GetParent,
2595     IWineD3DImpl_GetAdapterCount,
2596     IWineD3DImpl_RegisterSoftwareDevice,
2597     IWineD3DImpl_GetAdapterMonitor,
2598     IWineD3DImpl_GetAdapterModeCount,
2599     IWineD3DImpl_EnumAdapterModes,
2600     IWineD3DImpl_GetAdapterDisplayMode,
2601     IWineD3DImpl_GetAdapterIdentifier,
2602     IWineD3DImpl_CheckDeviceMultiSampleType,
2603     IWineD3DImpl_CheckDepthStencilMatch,
2604     IWineD3DImpl_CheckDeviceType,
2605     IWineD3DImpl_CheckDeviceFormat,
2606     IWineD3DImpl_CheckDeviceFormatConversion,
2607     IWineD3DImpl_GetDeviceCaps,
2608     IWineD3DImpl_CreateDevice
2609 };