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