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