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