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