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