wintrust: Implement SoftpubCleanup.
[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     /* TODO: Check support against more of the WINED3DUSAGE_QUERY_* constants
1491      * See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/directx9_c/IDirect3D9__CheckDeviceFormat.asp
1492      * and http://msdn.microsoft.com/library/default.asp?url=/library/en-us/directx9_c/D3DUSAGE_QUERY.asp */
1493     if (Usage & WINED3DUSAGE_QUERY_VERTEXTEXTURE) {
1494         if (!GL_LIMITS(vertex_samplers)) {
1495             TRACE_(d3d_caps)("[FAILED]\n");
1496             return WINED3DERR_NOTAVAILABLE;
1497         }
1498
1499         switch (CheckFormat) {
1500             case WINED3DFMT_A32B32G32R32F:
1501                 if (!GL_SUPPORT(ARB_TEXTURE_FLOAT)) {
1502                     TRACE_(d3d_caps)("[FAILED]\n");
1503                     return WINED3DERR_NOTAVAILABLE;
1504                 }
1505                 TRACE_(d3d_caps)("[OK]\n");
1506                 return WINED3D_OK;
1507
1508             default:
1509                 TRACE_(d3d_caps)("[FAILED]\n");
1510                 return WINED3DERR_NOTAVAILABLE;
1511         }
1512     }
1513
1514     if(Usage & WINED3DUSAGE_DEPTHSTENCIL) {
1515         switch (CheckFormat) {
1516             /* In theory we could do all formats, just fetch them accordingly should the buffer be locked.
1517              * Windows supports only those 3, and enumerating the other formats confuses applications
1518              */
1519             case WINED3DFMT_D24S8:
1520             case WINED3DFMT_D24X8:
1521             case WINED3DFMT_D16:
1522                 TRACE_(d3d_caps)("[OK]\n");
1523                 return WINED3D_OK;
1524             case WINED3DFMT_D16_LOCKABLE:
1525             case WINED3DFMT_D24FS8:
1526             case WINED3DFMT_D32F_LOCKABLE:
1527             case WINED3DFMT_D24X4S4:
1528             case WINED3DFMT_D15S1:
1529             case WINED3DFMT_D32:
1530                 TRACE_(d3d_caps)("[FAILED]. Disabled because not enumerated on windows\n");
1531                 return WINED3DERR_NOTAVAILABLE;
1532             default:
1533                 TRACE_(d3d_caps)("[FAILED]\n");
1534                 return WINED3DERR_NOTAVAILABLE;
1535         }
1536     } else if(Usage & WINED3DUSAGE_RENDERTARGET) {
1537         switch (CheckFormat) {
1538             case WINED3DFMT_R8G8B8:
1539             case WINED3DFMT_A8R8G8B8:
1540             case WINED3DFMT_X8R8G8B8:
1541             case WINED3DFMT_R5G6B5:
1542             case WINED3DFMT_X1R5G5B5:
1543             case WINED3DFMT_A1R5G5B5:
1544             case WINED3DFMT_A4R4G4B4:
1545             case WINED3DFMT_R3G3B2:
1546             case WINED3DFMT_X4R4G4B4:
1547             case WINED3DFMT_A8B8G8R8:
1548             case WINED3DFMT_X8B8G8R8:
1549             case WINED3DFMT_P8:
1550                 TRACE_(d3d_caps)("[OK]\n");
1551                 return WINED3D_OK;
1552             case WINED3DFMT_R16F:
1553             case WINED3DFMT_A16B16G16R16F:
1554                 if (!GL_SUPPORT(ARB_HALF_FLOAT_PIXEL) || !GL_SUPPORT(ARB_TEXTURE_FLOAT)) {
1555                     TRACE_(d3d_caps)("[FAILED]\n");
1556                     return WINED3DERR_NOTAVAILABLE;
1557                 }
1558                 TRACE_(d3d_caps)("[OK]\n");
1559                 return WINED3D_OK;
1560             case WINED3DFMT_A32B32G32R32F:
1561                if (!GL_SUPPORT(ARB_TEXTURE_FLOAT)) {
1562                     TRACE_(d3d_caps)("[FAILED]\n");
1563                     return WINED3DERR_NOTAVAILABLE;
1564                 }
1565                 TRACE_(d3d_caps)("[OK]\n");
1566                 return WINED3D_OK;
1567             default:
1568                 TRACE_(d3d_caps)("[FAILED]\n");
1569                 return WINED3DERR_NOTAVAILABLE;
1570         }
1571     } else if(Usage & WINED3DUSAGE_QUERY_LEGACYBUMPMAP) {
1572         if(GL_SUPPORT(NV_REGISTER_COMBINERS) && GL_SUPPORT(NV_TEXTURE_SHADER2)) {
1573             switch (CheckFormat) {
1574                 case WINED3DFMT_V8U8:
1575                     TRACE_(d3d_caps)("[OK]\n");
1576                     return WINED3D_OK;
1577                 /* TODO: Other bump map formats */
1578                 default:
1579                     TRACE_(d3d_caps)("[FAILED]\n");
1580                     return WINED3DERR_NOTAVAILABLE;
1581             }
1582         }
1583         if(GL_SUPPORT(ATI_ENVMAP_BUMPMAP)) {
1584             switch (CheckFormat) {
1585                 case WINED3DFMT_V8U8:
1586                     TRACE_(d3d_caps)("[OK]\n");
1587                     return WINED3D_OK;
1588                 default:
1589                     TRACE_(d3d_caps)("[FAILED]\n");
1590                     return WINED3DERR_NOTAVAILABLE;
1591             }
1592         }
1593         TRACE_(d3d_caps)("[FAILED]\n");
1594         return WINED3DERR_NOTAVAILABLE;
1595     }
1596
1597     if (GL_SUPPORT(EXT_TEXTURE_COMPRESSION_S3TC)) {
1598         switch (CheckFormat) {
1599         case WINED3DFMT_DXT1:
1600         case WINED3DFMT_DXT2:
1601         case WINED3DFMT_DXT3:
1602         case WINED3DFMT_DXT4:
1603         case WINED3DFMT_DXT5:
1604           TRACE_(d3d_caps)("[OK]\n");
1605           return WINED3D_OK;
1606         default:
1607             break; /* Avoid compiler warnings */
1608         }
1609     }
1610
1611     /* Check for supported sRGB formats (Texture loading and framebuffer) */
1612     if (GL_SUPPORT(EXT_TEXTURE_SRGB) && (Usage & WINED3DUSAGE_QUERY_SRGBREAD)) {
1613         switch (CheckFormat) {
1614             case WINED3DFMT_A8R8G8B8:
1615             case WINED3DFMT_X8R8G8B8:
1616             case WINED3DFMT_A4R4G4B4:
1617             case WINED3DFMT_L8:
1618             case WINED3DFMT_A8L8:
1619             case WINED3DFMT_DXT1:
1620             case WINED3DFMT_DXT2:
1621             case WINED3DFMT_DXT3:
1622             case WINED3DFMT_DXT4:
1623             case WINED3DFMT_DXT5:
1624                 TRACE_(d3d_caps)("[OK]\n");
1625                 return WINED3D_OK;
1626
1627             default:
1628                 TRACE_(d3d_caps)("[FAILED] Gamma texture format %s not supported.\n", debug_d3dformat(CheckFormat));
1629                 return WINED3DERR_NOTAVAILABLE;
1630         }
1631     }
1632
1633     if (GL_SUPPORT(ARB_TEXTURE_FLOAT)) {
1634
1635         BOOL half_pixel_support = GL_SUPPORT(ARB_HALF_FLOAT_PIXEL);
1636
1637         switch (CheckFormat) {
1638             case WINED3DFMT_R16F:
1639             case WINED3DFMT_A16B16G16R16F:
1640                 if (!half_pixel_support) break;
1641             case WINED3DFMT_R32F:
1642             case WINED3DFMT_A32B32G32R32F:
1643                 TRACE_(d3d_caps)("[OK]\n");
1644                 return WINED3D_OK;
1645             default:
1646                 break; /* Avoid compiler warnings */
1647         }
1648     }
1649
1650     /* This format is nothing special and it is supported perfectly.
1651      * However, ati and nvidia driver on windows do not mark this format as
1652      * supported (tested with the dxCapsViewer) and pretending to
1653      * support this format uncovers a bug in Battlefield 1942 (fonts are missing)
1654      * So do the same as Windows drivers and pretend not to support it on dx8 and 9
1655      * Enable it on dx7. It will need additional checking on dx10 when we support it.
1656      */
1657     if(This->dxVersion > 7 && CheckFormat == WINED3DFMT_R8G8B8) {
1658         TRACE_(d3d_caps)("[FAILED]\n");
1659         return WINED3DERR_NOTAVAILABLE;
1660     }
1661
1662     switch (CheckFormat) {
1663
1664         /*****
1665          *  supported: RGB(A) formats
1666          */
1667         case WINED3DFMT_R8G8B8: /* Enable for dx7, blacklisted for 8 and 9 above */
1668         case WINED3DFMT_A8R8G8B8:
1669         case WINED3DFMT_X8R8G8B8:
1670         case WINED3DFMT_R5G6B5:
1671         case WINED3DFMT_X1R5G5B5:
1672         case WINED3DFMT_A1R5G5B5:
1673         case WINED3DFMT_A4R4G4B4:
1674         case WINED3DFMT_R3G3B2:
1675         case WINED3DFMT_A8:
1676         case WINED3DFMT_X4R4G4B4:
1677         case WINED3DFMT_A8B8G8R8:
1678         case WINED3DFMT_X8B8G8R8:
1679         case WINED3DFMT_A2R10G10B10:
1680         case WINED3DFMT_A2B10G10R10:
1681             TRACE_(d3d_caps)("[OK]\n");
1682             return WINED3D_OK;
1683
1684         /*****
1685          *  supported: Palettized
1686          */
1687         case WINED3DFMT_P8:
1688             TRACE_(d3d_caps)("[OK]\n");
1689             return WINED3D_OK;
1690
1691         /*****
1692          *  Supported: (Alpha)-Luminance
1693          */
1694         case WINED3DFMT_L8:
1695         case WINED3DFMT_A8L8:
1696         case WINED3DFMT_A4L4:
1697             TRACE_(d3d_caps)("[OK]\n");
1698             return WINED3D_OK;
1699
1700         /*****
1701          *  Not supported everywhere(depends on GL_ATI_envmap_bumpmap or
1702          *  GL_NV_texture_shader), but advertized to make apps happy.
1703          *  Enable some because games often fail when they are not available
1704          *  and are still playable even without bump mapping
1705          */
1706         case WINED3DFMT_V8U8:
1707         case WINED3DFMT_V16U16:
1708         case WINED3DFMT_L6V5U5:
1709         case WINED3DFMT_X8L8V8U8:
1710         case WINED3DFMT_Q8W8V8U8:
1711             WARN_(d3d_caps)("[Not supported, but pretended to do]\n");
1712             return WINED3D_OK;
1713
1714         /* Those are not advertized by the nvidia windows driver, and not
1715          * supported natively by GL_NV_texture_shader or GL_ATI_envmap_bumpmap.
1716          * WINED3DFMT_A2W10V10U10 could be loaded into shaders using the unsigned
1717          * ARGB format if needed
1718          */
1719         case WINED3DFMT_W11V11U10:
1720         case WINED3DFMT_A2W10V10U10:
1721             WARN_(d3d_caps)("[FAILED]\n");
1722             return WINED3DERR_NOTAVAILABLE;
1723
1724         /*****
1725          *  DXTN Formats: Handled above
1726          * WINED3DFMT_DXT1
1727          * WINED3DFMT_DXT2
1728          * WINED3DFMT_DXT3
1729          * WINED3DFMT_DXT4
1730          * WINED3DFMT_DXT5
1731          */
1732
1733         /*****
1734          *  Odd formats - not supported
1735          */
1736         case WINED3DFMT_VERTEXDATA:
1737         case WINED3DFMT_INDEX16:
1738         case WINED3DFMT_INDEX32:
1739         case WINED3DFMT_Q16W16V16U16:
1740             TRACE_(d3d_caps)("[FAILED]\n"); /* Enable when implemented */
1741             return WINED3DERR_NOTAVAILABLE;
1742
1743         /*****
1744          *  Float formats: Not supported right now
1745          */
1746         case WINED3DFMT_G16R16F:
1747         case WINED3DFMT_G32R32F:
1748         case WINED3DFMT_CxV8U8:
1749             TRACE_(d3d_caps)("[FAILED]\n"); /* Enable when implemented */
1750             return WINED3DERR_NOTAVAILABLE;
1751
1752             /* Not supported */
1753         case WINED3DFMT_G16R16:
1754         case WINED3DFMT_A16B16G16R16:
1755         case WINED3DFMT_A8R3G3B2:
1756             TRACE_(d3d_caps)("[FAILED]\n"); /* Enable when implemented */
1757             return WINED3DERR_NOTAVAILABLE;
1758
1759         /* ATI instancing hack: Although ATI cards do not support Shader Model 3.0, they support
1760          * instancing. To query if the card supports instancing CheckDeviceFormat with the special format
1761          * MAKEFOURCC('I','N','S','T') is used. Should a (broken) app check for this provide a proper return value.
1762          * We can do instancing with all shader versions, but we need vertex shaders.
1763          *
1764          * Additionally applications have to set the D3DRS_POINTSIZE render state to MAKEFOURCC('I','N','S','T') once
1765          * to enable instancing. WineD3D doesn't need that and just ignores it.
1766          *
1767          * With Shader Model 3.0 capable cards Instancing 'just works' in Windows.
1768          */
1769         case WINEMAKEFOURCC('I','N','S','T'):
1770             TRACE("ATI Instancing check hack\n");
1771             if(GL_SUPPORT(ARB_VERTEX_PROGRAM) || GL_SUPPORT(ARB_VERTEX_SHADER)) {
1772                 TRACE_(d3d_caps)("[OK]\n");
1773                 return WINED3D_OK;
1774             } else {
1775                 TRACE_(d3d_caps)("[FAILED]\n");
1776                 return WINED3DERR_NOTAVAILABLE;
1777             }
1778
1779         default:
1780             break;
1781     }
1782
1783     TRACE_(d3d_caps)("[FAILED]\n");
1784     return WINED3DERR_NOTAVAILABLE;
1785 }
1786
1787 static HRESULT  WINAPI IWineD3DImpl_CheckDeviceFormatConversion(IWineD3D *iface, UINT Adapter, WINED3DDEVTYPE DeviceType,
1788                                                           WINED3DFORMAT SourceFormat, WINED3DFORMAT TargetFormat) {
1789     IWineD3DImpl *This = (IWineD3DImpl *)iface;
1790
1791     FIXME_(d3d_caps)("(%p)-> (STUB) (Adptr:%d, DevType:(%u,%s), SrcFmt:(%u,%s), TgtFmt:(%u,%s))\n",
1792           This,
1793           Adapter,
1794           DeviceType, debug_d3ddevicetype(DeviceType),
1795           SourceFormat, debug_d3dformat(SourceFormat),
1796           TargetFormat, debug_d3dformat(TargetFormat));
1797     return WINED3D_OK;
1798 }
1799
1800 /* Note: d3d8 passes in a pointer to a D3DCAPS8 structure, which is a true
1801       subset of a D3DCAPS9 structure. However, it has to come via a void *
1802       as the d3d8 interface cannot import the d3d9 header                  */
1803 static HRESULT WINAPI IWineD3DImpl_GetDeviceCaps(IWineD3D *iface, UINT Adapter, WINED3DDEVTYPE DeviceType, WINED3DCAPS* pCaps) {
1804
1805     IWineD3DImpl    *This = (IWineD3DImpl *)iface;
1806     int vs_selected_mode;
1807     int ps_selected_mode;
1808
1809     TRACE_(d3d_caps)("(%p)->(Adptr:%d, DevType: %x, pCaps: %p)\n", This, Adapter, DeviceType, pCaps);
1810
1811     if (Adapter >= IWineD3D_GetAdapterCount(iface)) {
1812         return WINED3DERR_INVALIDCALL;
1813     }
1814
1815     select_shader_mode(&Adapters[Adapter].gl_info, DeviceType, &ps_selected_mode, &vs_selected_mode);
1816
1817     /* This function should *not* be modifying GL caps
1818      * TODO: move the functionality where it belongs */
1819     select_shader_max_constants(ps_selected_mode, vs_selected_mode, &Adapters[Adapter].gl_info);
1820
1821     /* ------------------------------------------------
1822        The following fields apply to both d3d8 and d3d9
1823        ------------------------------------------------ */
1824     *pCaps->DeviceType              = (DeviceType == WINED3DDEVTYPE_HAL) ? WINED3DDEVTYPE_HAL : WINED3DDEVTYPE_REF;  /* Not quite true, but use h/w supported by opengl I suppose */
1825     *pCaps->AdapterOrdinal          = Adapter;
1826
1827     *pCaps->Caps                    = 0;
1828     *pCaps->Caps2                   = WINED3DCAPS2_CANRENDERWINDOWED |
1829                                       WINED3DCAPS2_FULLSCREENGAMMA |
1830                                       WINED3DCAPS2_DYNAMICTEXTURES;
1831     *pCaps->Caps3                   = WINED3DCAPS3_ALPHA_FULLSCREEN_FLIP_OR_DISCARD;
1832     *pCaps->PresentationIntervals   = WINED3DPRESENT_INTERVAL_IMMEDIATE  |
1833                                       WINED3DPRESENT_INTERVAL_ONE;
1834
1835     *pCaps->CursorCaps              = WINED3DCURSORCAPS_COLOR            |
1836                                       WINED3DCURSORCAPS_LOWRES;
1837
1838     *pCaps->DevCaps                 = WINED3DDEVCAPS_FLOATTLVERTEX       |
1839                                       WINED3DDEVCAPS_EXECUTESYSTEMMEMORY |
1840                                       WINED3DDEVCAPS_TLVERTEXSYSTEMMEMORY|
1841                                       WINED3DDEVCAPS_TLVERTEXVIDEOMEMORY |
1842                                       WINED3DDEVCAPS_DRAWPRIMTLVERTEX    |
1843                                       WINED3DDEVCAPS_HWTRANSFORMANDLIGHT |
1844                                       WINED3DDEVCAPS_EXECUTEVIDEOMEMORY  |
1845                                       WINED3DDEVCAPS_PUREDEVICE          |
1846                                       WINED3DDEVCAPS_HWRASTERIZATION     |
1847                                       WINED3DDEVCAPS_TEXTUREVIDEOMEMORY  |
1848                                       WINED3DDEVCAPS_TEXTURESYSTEMMEMORY |
1849                                       WINED3DDEVCAPS_CANRENDERAFTERFLIP  |
1850                                       WINED3DDEVCAPS_DRAWPRIMITIVES2     |
1851                                       WINED3DDEVCAPS_DRAWPRIMITIVES2EX   |
1852                                       WINED3DDEVCAPS_RTPATCHES;
1853
1854     *pCaps->PrimitiveMiscCaps       = WINED3DPMISCCAPS_CULLNONE              |
1855                                       WINED3DPMISCCAPS_CULLCCW               |
1856                                       WINED3DPMISCCAPS_CULLCW                |
1857                                       WINED3DPMISCCAPS_COLORWRITEENABLE      |
1858                                       WINED3DPMISCCAPS_CLIPTLVERTS           |
1859                                       WINED3DPMISCCAPS_CLIPPLANESCALEDPOINTS |
1860                                       WINED3DPMISCCAPS_MASKZ                 |
1861                                       WINED3DPMISCCAPS_BLENDOP;
1862                                     /* TODO:
1863                                         WINED3DPMISCCAPS_NULLREFERENCE
1864                                         WINED3DPMISCCAPS_INDEPENDENTWRITEMASKS
1865                                         WINED3DPMISCCAPS_FOGANDSPECULARALPHA
1866                                         WINED3DPMISCCAPS_SEPARATEALPHABLEND
1867                                         WINED3DPMISCCAPS_MRTINDEPENDENTBITDEPTHS
1868                                         WINED3DPMISCCAPS_MRTPOSTPIXELSHADERBLENDING
1869                                         WINED3DPMISCCAPS_FOGVERTEXCLAMPED */
1870
1871 /* The caps below can be supported but aren't handled yet in utils.c 'd3dta_to_combiner_input', disable them until support is fixed */
1872 #if 0
1873     if (GL_SUPPORT(NV_REGISTER_COMBINERS))
1874         *pCaps->PrimitiveMiscCaps |=  WINED3DPMISCCAPS_TSSARGTEMP;
1875     if (GL_SUPPORT(NV_REGISTER_COMBINERS2))
1876         *pCaps->PrimitiveMiscCaps |=  WINED3DPMISCCAPS_PERSTAGECONSTANT;
1877 #endif
1878
1879     *pCaps->RasterCaps              = WINED3DPRASTERCAPS_DITHER    |
1880                                       WINED3DPRASTERCAPS_PAT       |
1881                                       WINED3DPRASTERCAPS_WFOG      |
1882                                       WINED3DPRASTERCAPS_ZFOG      |
1883                                       WINED3DPRASTERCAPS_FOGVERTEX |
1884                                       WINED3DPRASTERCAPS_FOGTABLE  |
1885                                       WINED3DPRASTERCAPS_STIPPLE   |
1886                                       WINED3DPRASTERCAPS_SUBPIXEL  |
1887                                       WINED3DPRASTERCAPS_ZTEST     |
1888                                       WINED3DPRASTERCAPS_SCISSORTEST   |
1889                                       WINED3DPRASTERCAPS_SLOPESCALEDEPTHBIAS |
1890                                       WINED3DPRASTERCAPS_DEPTHBIAS;
1891
1892     if (GL_SUPPORT(EXT_TEXTURE_FILTER_ANISOTROPIC)) {
1893       *pCaps->RasterCaps |= WINED3DPRASTERCAPS_ANISOTROPY    |
1894                             WINED3DPRASTERCAPS_ZBIAS         |
1895                             WINED3DPRASTERCAPS_MIPMAPLODBIAS;
1896     }
1897     if(GL_SUPPORT(NV_FOG_DISTANCE)) {
1898         *pCaps->RasterCaps         |= WINED3DPRASTERCAPS_FOGRANGE;
1899     }
1900                         /* FIXME Add:
1901                            WINED3DPRASTERCAPS_COLORPERSPECTIVE
1902                            WINED3DPRASTERCAPS_STRETCHBLTMULTISAMPLE
1903                            WINED3DPRASTERCAPS_ANTIALIASEDGES
1904                            WINED3DPRASTERCAPS_ZBUFFERLESSHSR
1905                            WINED3DPRASTERCAPS_WBUFFER */
1906
1907     *pCaps->ZCmpCaps = WINED3DPCMPCAPS_ALWAYS       |
1908                        WINED3DPCMPCAPS_EQUAL        |
1909                        WINED3DPCMPCAPS_GREATER      |
1910                        WINED3DPCMPCAPS_GREATEREQUAL |
1911                        WINED3DPCMPCAPS_LESS         |
1912                        WINED3DPCMPCAPS_LESSEQUAL    |
1913                        WINED3DPCMPCAPS_NEVER        |
1914                        WINED3DPCMPCAPS_NOTEQUAL;
1915
1916     *pCaps->SrcBlendCaps  = WINED3DPBLENDCAPS_BLENDFACTOR     |
1917                             WINED3DPBLENDCAPS_BOTHINVSRCALPHA |
1918                             WINED3DPBLENDCAPS_BOTHSRCALPHA    |
1919                             WINED3DPBLENDCAPS_DESTALPHA       |
1920                             WINED3DPBLENDCAPS_DESTCOLOR       |
1921                             WINED3DPBLENDCAPS_INVDESTALPHA    |
1922                             WINED3DPBLENDCAPS_INVDESTCOLOR    |
1923                             WINED3DPBLENDCAPS_INVSRCALPHA     |
1924                             WINED3DPBLENDCAPS_INVSRCCOLOR     |
1925                             WINED3DPBLENDCAPS_ONE             |
1926                             WINED3DPBLENDCAPS_SRCALPHA        |
1927                             WINED3DPBLENDCAPS_SRCALPHASAT     |
1928                             WINED3DPBLENDCAPS_SRCCOLOR        |
1929                             WINED3DPBLENDCAPS_ZERO;
1930
1931     *pCaps->DestBlendCaps = WINED3DPBLENDCAPS_BLENDFACTOR     |
1932                             WINED3DPBLENDCAPS_DESTALPHA       |
1933                             WINED3DPBLENDCAPS_DESTCOLOR       |
1934                             WINED3DPBLENDCAPS_INVDESTALPHA    |
1935                             WINED3DPBLENDCAPS_INVDESTCOLOR    |
1936                             WINED3DPBLENDCAPS_INVSRCALPHA     |
1937                             WINED3DPBLENDCAPS_INVSRCCOLOR     |
1938                             WINED3DPBLENDCAPS_ONE             |
1939                             WINED3DPBLENDCAPS_SRCALPHA        |
1940                             WINED3DPBLENDCAPS_SRCCOLOR        |
1941                             WINED3DPBLENDCAPS_ZERO;
1942     /* NOTE: WINED3DPBLENDCAPS_SRCALPHASAT is not supported as dest blend factor,
1943      * according to the glBlendFunc manpage
1944      *
1945      * WINED3DPBLENDCAPS_BOTHINVSRCALPHA and WINED3DPBLENDCAPS_BOTHSRCALPHA are
1946      * legacy settings for srcblend only
1947      */
1948
1949     *pCaps->AlphaCmpCaps = WINED3DPCMPCAPS_ALWAYS       |
1950                            WINED3DPCMPCAPS_EQUAL        |
1951                            WINED3DPCMPCAPS_GREATER      |
1952                            WINED3DPCMPCAPS_GREATEREQUAL |
1953                            WINED3DPCMPCAPS_LESS         |
1954                            WINED3DPCMPCAPS_LESSEQUAL    |
1955                            WINED3DPCMPCAPS_NEVER        |
1956                            WINED3DPCMPCAPS_NOTEQUAL;
1957
1958     *pCaps->ShadeCaps     = WINED3DPSHADECAPS_SPECULARGOURAUDRGB |
1959                             WINED3DPSHADECAPS_COLORGOURAUDRGB    |
1960                             WINED3DPSHADECAPS_ALPHAFLATBLEND     |
1961                             WINED3DPSHADECAPS_ALPHAGOURAUDBLEND  |
1962                             WINED3DPSHADECAPS_COLORFLATRGB       |
1963                             WINED3DPSHADECAPS_FOGFLAT            |
1964                             WINED3DPSHADECAPS_FOGGOURAUD         |
1965                             WINED3DPSHADECAPS_SPECULARFLATRGB;
1966
1967     *pCaps->TextureCaps =  WINED3DPTEXTURECAPS_ALPHA              |
1968                            WINED3DPTEXTURECAPS_ALPHAPALETTE       |
1969                            WINED3DPTEXTURECAPS_BORDER             |
1970                            WINED3DPTEXTURECAPS_MIPMAP             |
1971                            WINED3DPTEXTURECAPS_PROJECTED          |
1972                            WINED3DPTEXTURECAPS_PERSPECTIVE;
1973
1974     if( !GL_SUPPORT(ARB_TEXTURE_NON_POWER_OF_TWO)) {
1975         *pCaps->TextureCaps |= WINED3DPTEXTURECAPS_POW2 |
1976                                 WINED3DPTEXTURECAPS_NONPOW2CONDITIONAL;
1977     }
1978
1979     if( GL_SUPPORT(EXT_TEXTURE3D)) {
1980         *pCaps->TextureCaps |=  WINED3DPTEXTURECAPS_VOLUMEMAP      |
1981                                 WINED3DPTEXTURECAPS_MIPVOLUMEMAP   |
1982                                 WINED3DPTEXTURECAPS_VOLUMEMAP_POW2;
1983     }
1984
1985     if (GL_SUPPORT(ARB_TEXTURE_CUBE_MAP)) {
1986         *pCaps->TextureCaps |= WINED3DPTEXTURECAPS_CUBEMAP     |
1987                              WINED3DPTEXTURECAPS_MIPCUBEMAP    |
1988                              WINED3DPTEXTURECAPS_CUBEMAP_POW2;
1989
1990     }
1991
1992     *pCaps->TextureFilterCaps = WINED3DPTFILTERCAPS_MAGFLINEAR       |
1993                                 WINED3DPTFILTERCAPS_MAGFPOINT        |
1994                                 WINED3DPTFILTERCAPS_MINFLINEAR       |
1995                                 WINED3DPTFILTERCAPS_MINFPOINT        |
1996                                 WINED3DPTFILTERCAPS_MIPFLINEAR       |
1997                                 WINED3DPTFILTERCAPS_MIPFPOINT        |
1998                                 WINED3DPTFILTERCAPS_LINEAR           |
1999                                 WINED3DPTFILTERCAPS_LINEARMIPLINEAR  |
2000                                 WINED3DPTFILTERCAPS_LINEARMIPNEAREST |
2001                                 WINED3DPTFILTERCAPS_MIPLINEAR        |
2002                                 WINED3DPTFILTERCAPS_MIPNEAREST       |
2003                                 WINED3DPTFILTERCAPS_NEAREST;
2004
2005     if (GL_SUPPORT(EXT_TEXTURE_FILTER_ANISOTROPIC)) {
2006         *pCaps->TextureFilterCaps |= WINED3DPTFILTERCAPS_MAGFANISOTROPIC |
2007                                      WINED3DPTFILTERCAPS_MINFANISOTROPIC;
2008     }
2009
2010     if (GL_SUPPORT(ARB_TEXTURE_CUBE_MAP)) {
2011         *pCaps->CubeTextureFilterCaps = WINED3DPTFILTERCAPS_MAGFLINEAR       |
2012                                         WINED3DPTFILTERCAPS_MAGFPOINT        |
2013                                         WINED3DPTFILTERCAPS_MINFLINEAR       |
2014                                         WINED3DPTFILTERCAPS_MINFPOINT        |
2015                                         WINED3DPTFILTERCAPS_MIPFLINEAR       |
2016                                         WINED3DPTFILTERCAPS_MIPFPOINT        |
2017                                         WINED3DPTFILTERCAPS_LINEAR           |
2018                                         WINED3DPTFILTERCAPS_LINEARMIPLINEAR  |
2019                                         WINED3DPTFILTERCAPS_LINEARMIPNEAREST |
2020                                         WINED3DPTFILTERCAPS_MIPLINEAR        |
2021                                         WINED3DPTFILTERCAPS_MIPNEAREST       |
2022                                         WINED3DPTFILTERCAPS_NEAREST;
2023
2024         if (GL_SUPPORT(EXT_TEXTURE_FILTER_ANISOTROPIC)) {
2025             *pCaps->CubeTextureFilterCaps |= WINED3DPTFILTERCAPS_MAGFANISOTROPIC |
2026                                             WINED3DPTFILTERCAPS_MINFANISOTROPIC;
2027         }
2028     } else
2029         *pCaps->CubeTextureFilterCaps = 0;
2030
2031     if (GL_SUPPORT(EXT_TEXTURE3D)) {
2032         *pCaps->VolumeTextureFilterCaps = WINED3DPTFILTERCAPS_MAGFLINEAR       |
2033                                           WINED3DPTFILTERCAPS_MAGFPOINT        |
2034                                           WINED3DPTFILTERCAPS_MINFLINEAR       |
2035                                           WINED3DPTFILTERCAPS_MINFPOINT        |
2036                                           WINED3DPTFILTERCAPS_MIPFLINEAR       |
2037                                           WINED3DPTFILTERCAPS_MIPFPOINT        |
2038                                           WINED3DPTFILTERCAPS_LINEAR           |
2039                                           WINED3DPTFILTERCAPS_LINEARMIPLINEAR  |
2040                                           WINED3DPTFILTERCAPS_LINEARMIPNEAREST |
2041                                           WINED3DPTFILTERCAPS_MIPLINEAR        |
2042                                           WINED3DPTFILTERCAPS_MIPNEAREST       |
2043                                           WINED3DPTFILTERCAPS_NEAREST;
2044     } else
2045         *pCaps->VolumeTextureFilterCaps = 0;
2046
2047     *pCaps->TextureAddressCaps =  WINED3DPTADDRESSCAPS_INDEPENDENTUV |
2048                                   WINED3DPTADDRESSCAPS_CLAMP  |
2049                                   WINED3DPTADDRESSCAPS_WRAP;
2050
2051     if (GL_SUPPORT(ARB_TEXTURE_BORDER_CLAMP)) {
2052         *pCaps->TextureAddressCaps |= WINED3DPTADDRESSCAPS_BORDER;
2053     }
2054     if (GL_SUPPORT(ARB_TEXTURE_MIRRORED_REPEAT)) {
2055         *pCaps->TextureAddressCaps |= WINED3DPTADDRESSCAPS_MIRROR;
2056     }
2057     if (GL_SUPPORT(ATI_TEXTURE_MIRROR_ONCE)) {
2058         *pCaps->TextureAddressCaps |= WINED3DPTADDRESSCAPS_MIRRORONCE;
2059     }
2060
2061     if (GL_SUPPORT(EXT_TEXTURE3D)) {
2062         *pCaps->VolumeTextureAddressCaps =  WINED3DPTADDRESSCAPS_INDEPENDENTUV |
2063                                             WINED3DPTADDRESSCAPS_CLAMP  |
2064                                             WINED3DPTADDRESSCAPS_WRAP;
2065         if (GL_SUPPORT(ARB_TEXTURE_BORDER_CLAMP)) {
2066             *pCaps->VolumeTextureAddressCaps |= WINED3DPTADDRESSCAPS_BORDER;
2067         }
2068         if (GL_SUPPORT(ARB_TEXTURE_MIRRORED_REPEAT)) {
2069             *pCaps->VolumeTextureAddressCaps |= WINED3DPTADDRESSCAPS_MIRROR;
2070         }
2071         if (GL_SUPPORT(ATI_TEXTURE_MIRROR_ONCE)) {
2072             *pCaps->VolumeTextureAddressCaps |= WINED3DPTADDRESSCAPS_MIRRORONCE;
2073         }
2074     } else
2075         *pCaps->VolumeTextureAddressCaps = 0;
2076
2077     *pCaps->LineCaps = WINED3DLINECAPS_TEXTURE |
2078                        WINED3DLINECAPS_ZTEST;
2079                       /* FIXME: Add
2080                         WINED3DLINECAPS_BLEND
2081                         WINED3DLINECAPS_ALPHACMP
2082                         WINED3DLINECAPS_FOG */
2083
2084     *pCaps->MaxTextureWidth  = GL_LIMITS(texture_size);
2085     *pCaps->MaxTextureHeight = GL_LIMITS(texture_size);
2086
2087     if(GL_SUPPORT(EXT_TEXTURE3D))
2088         *pCaps->MaxVolumeExtent = GL_LIMITS(texture3d_size);
2089     else
2090         *pCaps->MaxVolumeExtent = 0;
2091
2092     *pCaps->MaxTextureRepeat = 32768;
2093     *pCaps->MaxTextureAspectRatio = GL_LIMITS(texture_size);
2094     *pCaps->MaxVertexW = 1.0;
2095
2096     *pCaps->GuardBandLeft = 0;
2097     *pCaps->GuardBandTop = 0;
2098     *pCaps->GuardBandRight = 0;
2099     *pCaps->GuardBandBottom = 0;
2100
2101     *pCaps->ExtentsAdjust = 0;
2102
2103     *pCaps->StencilCaps =  WINED3DSTENCILCAPS_DECRSAT |
2104                            WINED3DSTENCILCAPS_INCRSAT |
2105                            WINED3DSTENCILCAPS_INVERT  |
2106                            WINED3DSTENCILCAPS_KEEP    |
2107                            WINED3DSTENCILCAPS_REPLACE |
2108                            WINED3DSTENCILCAPS_ZERO;
2109     if (GL_SUPPORT(EXT_STENCIL_WRAP)) {
2110       *pCaps->StencilCaps |= WINED3DSTENCILCAPS_DECR  |
2111                              WINED3DSTENCILCAPS_INCR;
2112     }
2113     if ( This->dxVersion > 8 &&
2114         ( GL_SUPPORT(EXT_STENCIL_TWO_SIDE) ||
2115             GL_SUPPORT(ATI_SEPARATE_STENCIL) ) ) {
2116         *pCaps->StencilCaps |= WINED3DSTENCILCAPS_TWOSIDED;
2117     }
2118
2119     *pCaps->FVFCaps = WINED3DFVFCAPS_PSIZE | 0x0008; /* 8 texture coords */
2120
2121     *pCaps->TextureOpCaps =  WINED3DTEXOPCAPS_ADD         |
2122                              WINED3DTEXOPCAPS_ADDSIGNED   |
2123                              WINED3DTEXOPCAPS_ADDSIGNED2X |
2124                              WINED3DTEXOPCAPS_MODULATE    |
2125                              WINED3DTEXOPCAPS_MODULATE2X  |
2126                              WINED3DTEXOPCAPS_MODULATE4X  |
2127                              WINED3DTEXOPCAPS_SELECTARG1  |
2128                              WINED3DTEXOPCAPS_SELECTARG2  |
2129                              WINED3DTEXOPCAPS_DISABLE;
2130
2131     if (GL_SUPPORT(ARB_TEXTURE_ENV_COMBINE) ||
2132         GL_SUPPORT(EXT_TEXTURE_ENV_COMBINE) ||
2133         GL_SUPPORT(NV_TEXTURE_ENV_COMBINE4)) {
2134         *pCaps->TextureOpCaps |= WINED3DTEXOPCAPS_BLENDDIFFUSEALPHA |
2135                                 WINED3DTEXOPCAPS_BLENDTEXTUREALPHA  |
2136                                 WINED3DTEXOPCAPS_BLENDFACTORALPHA   |
2137                                 WINED3DTEXOPCAPS_BLENDCURRENTALPHA  |
2138                                 WINED3DTEXOPCAPS_LERP               |
2139                                 WINED3DTEXOPCAPS_SUBTRACT;
2140     }
2141     if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3) ||
2142          GL_SUPPORT(NV_TEXTURE_ENV_COMBINE4)) {
2143         *pCaps->TextureOpCaps |= WINED3DTEXOPCAPS_ADDSMOOTH             |
2144                                 WINED3DTEXOPCAPS_MULTIPLYADD            |
2145                                 WINED3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR |
2146                                 WINED3DTEXOPCAPS_MODULATECOLOR_ADDALPHA |
2147                                 WINED3DTEXOPCAPS_BLENDTEXTUREALPHAPM;
2148     }
2149     if (GL_SUPPORT(ARB_TEXTURE_ENV_DOT3))
2150         *pCaps->TextureOpCaps |= WINED3DTEXOPCAPS_DOTPRODUCT3;
2151
2152     if (GL_SUPPORT(NV_REGISTER_COMBINERS)) {
2153         *pCaps->TextureOpCaps |= WINED3DTEXOPCAPS_MODULATEINVALPHA_ADDCOLOR |
2154                                  WINED3DTEXOPCAPS_MODULATEINVCOLOR_ADDALPHA;
2155     }
2156
2157     if(GL_SUPPORT(ATI_ENVMAP_BUMPMAP)) {
2158         *pCaps->TextureOpCaps |= WINED3DTEXOPCAPS_BUMPENVMAP;
2159     } else if(GL_SUPPORT(NV_TEXTURE_SHADER2)) {
2160         /* Bump mapping is supported already in NV_TEXTURE_SHADER, but that extension does
2161          * not support 3D textures. This asks for trouble if an app uses both bump mapping
2162          * and 3D textures. It also allows us to keep the code simpler by having texture
2163          * shaders constantly enabled.
2164          */
2165         *pCaps->TextureOpCaps |= WINED3DTEXOPCAPS_BUMPENVMAP;
2166         /* TODO: Luminance bump map? */
2167     }
2168 #if 0
2169     /* FIXME: Add
2170     *pCaps->TextureOpCaps |= WINED3DTEXOPCAPS_BUMPENVMAPLUMINANCE
2171                              WINED3DTEXOPCAPS_PREMODULATE */
2172 #endif
2173
2174     *pCaps->MaxTextureBlendStages   = GL_LIMITS(texture_stages);
2175     *pCaps->MaxSimultaneousTextures = GL_LIMITS(textures);
2176     *pCaps->MaxUserClipPlanes       = GL_LIMITS(clipplanes);
2177     *pCaps->MaxActiveLights         = GL_LIMITS(lights);
2178
2179     *pCaps->MaxVertexBlendMatrices      = GL_LIMITS(blends);
2180     *pCaps->MaxVertexBlendMatrixIndex   = 0;
2181
2182     *pCaps->MaxAnisotropy   = GL_LIMITS(anisotropy);
2183     *pCaps->MaxPointSize    = GL_LIMITS(pointsize);
2184
2185
2186     *pCaps->VertexProcessingCaps = WINED3DVTXPCAPS_DIRECTIONALLIGHTS |
2187                                    WINED3DVTXPCAPS_MATERIALSOURCE7   |
2188                                    WINED3DVTXPCAPS_POSITIONALLIGHTS  |
2189                                    WINED3DVTXPCAPS_LOCALVIEWER       |
2190                                    WINED3DVTXPCAPS_VERTEXFOG         |
2191                                    WINED3DVTXPCAPS_TEXGEN;
2192                                   /* FIXME: Add 
2193                                      D3DVTXPCAPS_TWEENING, D3DVTXPCAPS_TEXGEN_SPHEREMAP */
2194
2195     *pCaps->MaxPrimitiveCount   = 0xFFFFF; /* For now set 2^20-1 which is used by most >=Geforce3/Radeon8500 cards */
2196     *pCaps->MaxVertexIndex      = 0xFFFFF;
2197     *pCaps->MaxStreams          = MAX_STREAMS;
2198     *pCaps->MaxStreamStride     = 1024;
2199
2200     if (vs_selected_mode == SHADER_GLSL) {
2201         /* Nvidia Geforce6/7 or Ati R4xx/R5xx cards with GLSL support, support VS 3.0 but older Nvidia/Ati
2202            models with GLSL support only support 2.0. In case of nvidia we can detect VS 2.0 support using
2203            vs_nv_version which is based on NV_vertex_program. For Ati cards there's no easy way, so for
2204            now only support 2.0/3.0 detection on Nvidia GeforceFX cards and default to 3.0 for everything else */
2205         if(GLINFO_LOCATION.vs_nv_version == VS_VERSION_20)
2206             *pCaps->VertexShaderVersion = WINED3DVS_VERSION(2,0);
2207         else
2208             *pCaps->VertexShaderVersion = WINED3DVS_VERSION(3,0);
2209         TRACE_(d3d_caps)("Hardware vertex shader version 3.0 enabled (GLSL)\n");
2210     } else if (vs_selected_mode == SHADER_ARB) {
2211         *pCaps->VertexShaderVersion = WINED3DVS_VERSION(1,1);
2212         TRACE_(d3d_caps)("Hardware vertex shader version 1.1 enabled (ARB_PROGRAM)\n");
2213     } else {
2214         *pCaps->VertexShaderVersion  = 0;
2215         TRACE_(d3d_caps)("Vertex shader functionality not available\n");
2216     }
2217
2218     *pCaps->MaxVertexShaderConst = GL_LIMITS(vshader_constantsF);
2219
2220     if (ps_selected_mode == SHADER_GLSL) {
2221         /* See the comment about VS2.0/VS3.0 detection as we do the same here but then based on NV_fragment_program
2222            in case of GeforceFX cards. */
2223         if(GLINFO_LOCATION.ps_nv_version == PS_VERSION_20)
2224             *pCaps->PixelShaderVersion = WINED3DPS_VERSION(2,0);
2225         else
2226             *pCaps->PixelShaderVersion = WINED3DPS_VERSION(3,0);
2227         /* FIXME: The following line is card dependent. -8.0 to 8.0 is the
2228          * Direct3D minimum requirement.
2229          *
2230          * Both GL_ARB_fragment_program and GLSL require a "maximum representable magnitude"
2231          * of colors to be 2^10, and 2^32 for other floats. Should we use 1024 here?
2232          *
2233          * The problem is that the refrast clamps temporary results in the shader to
2234          * [-MaxValue;+MaxValue]. If the card's max value is bigger than the one we advertize here,
2235          * then applications may miss the clamping behavior. On the other hand, if it is smaller,
2236          * the shader will generate incorrect results too. Unfortunately, GL deliberately doesn't
2237          * offer a way to query this.
2238          */
2239         *pCaps->PixelShader1xMaxValue = 8.0;
2240         TRACE_(d3d_caps)("Hardware pixel shader version 3.0 enabled (GLSL)\n");
2241     } else if (ps_selected_mode == SHADER_ARB) {
2242         *pCaps->PixelShaderVersion    = WINED3DPS_VERSION(1,4);
2243         *pCaps->PixelShader1xMaxValue = 8.0;
2244         TRACE_(d3d_caps)("Hardware pixel shader version 1.4 enabled (ARB_PROGRAM)\n");
2245     } else {
2246         *pCaps->PixelShaderVersion    = 0;
2247         *pCaps->PixelShader1xMaxValue = 0.0;
2248         TRACE_(d3d_caps)("Pixel shader functionality not available\n");
2249     }
2250
2251     /* ------------------------------------------------
2252        The following fields apply to d3d9 only
2253        ------------------------------------------------ */
2254     if (This->dxVersion > 8) {
2255         /* d3d9.dll sets D3DDEVCAPS2_CAN_STRETCHRECT_FROM_TEXTURES here because StretchRects is implemented in d3d9 */
2256         *pCaps->DevCaps2                          = WINED3DDEVCAPS2_STREAMOFFSET;
2257         /* TODO: VS3.0 needs at least D3DDEVCAPS2_VERTEXELEMENTSCANSHARESTREAMOFFSET */
2258         *pCaps->MaxNpatchTessellationLevel        = 0;
2259         *pCaps->MasterAdapterOrdinal              = 0;
2260         *pCaps->AdapterOrdinalInGroup             = 0;
2261         *pCaps->NumberOfAdaptersInGroup           = 1;
2262
2263         if(*pCaps->VertexShaderVersion >= WINED3DVS_VERSION(2,0)) {
2264             /* OpenGL supports all the formats below, perhaps not always
2265              * without conversion, but it supports them.
2266              * Further GLSL doesn't seem to have an official unsigned type so
2267              * don't advertise it yet as I'm not sure how we handle it.
2268              * We might need to add some clamping in the shader engine to
2269              * support it.
2270              * TODO: WINED3DDTCAPS_USHORT2N, WINED3DDTCAPS_USHORT4N, WINED3DDTCAPS_UDEC3, WINED3DDTCAPS_DEC3N */
2271             *pCaps->DeclTypes = WINED3DDTCAPS_UBYTE4    |
2272                                 WINED3DDTCAPS_UBYTE4N   |
2273                                 WINED3DDTCAPS_SHORT2N   |
2274                                 WINED3DDTCAPS_SHORT4N;
2275             if (GL_SUPPORT(NV_HALF_FLOAT)) {
2276                 *pCaps->DeclTypes |=
2277                                 WINED3DDTCAPS_FLOAT16_2 |
2278                                 WINED3DDTCAPS_FLOAT16_4;
2279             }
2280         } else
2281             *pCaps->DeclTypes                         = 0;
2282
2283         *pCaps->NumSimultaneousRTs = GL_LIMITS(buffers);
2284
2285             
2286         *pCaps->StretchRectFilterCaps             = WINED3DPTFILTERCAPS_MINFPOINT  |
2287                                                     WINED3DPTFILTERCAPS_MAGFPOINT  |
2288                                                     WINED3DPTFILTERCAPS_MINFLINEAR |
2289                                                     WINED3DPTFILTERCAPS_MAGFLINEAR;
2290         *pCaps->VertexTextureFilterCaps           = 0;
2291         
2292         if(*pCaps->VertexShaderVersion == WINED3DVS_VERSION(3,0)) {
2293             /* Where possible set the caps based on OpenGL extensions and if they aren't set (in case of software rendering)
2294                use the VS 3.0 from MSDN or else if there's OpenGL spec use a hardcoded value minimum VS3.0 value. */
2295             *pCaps->VS20Caps.Caps                     = WINED3DVS20CAPS_PREDICATION;
2296             *pCaps->VS20Caps.DynamicFlowControlDepth  = WINED3DVS20_MAX_DYNAMICFLOWCONTROLDEPTH; /* VS 3.0 requires MAX_DYNAMICFLOWCONTROLDEPTH (24) */
2297             *pCaps->VS20Caps.NumTemps                 = max(32, GLINFO_LOCATION.vs_arb_max_temps);
2298             *pCaps->VS20Caps.StaticFlowControlDepth   = WINED3DVS20_MAX_STATICFLOWCONTROLDEPTH ; /* level of nesting in loops / if-statements; VS 3.0 requires MAX (4) */
2299
2300             *pCaps->MaxVShaderInstructionsExecuted    = 65535; /* VS 3.0 needs at least 65535, some cards even use 2^32-1 */
2301             *pCaps->MaxVertexShader30InstructionSlots = max(512, GLINFO_LOCATION.vs_arb_max_instructions);
2302         } else if(*pCaps->VertexShaderVersion == WINED3DVS_VERSION(2,0)) {
2303             *pCaps->VS20Caps.Caps                     = 0;
2304             *pCaps->VS20Caps.DynamicFlowControlDepth  = WINED3DVS20_MIN_DYNAMICFLOWCONTROLDEPTH;
2305             *pCaps->VS20Caps.NumTemps                 = max(12, GLINFO_LOCATION.vs_arb_max_temps);
2306             *pCaps->VS20Caps.StaticFlowControlDepth   = 1;    
2307
2308             *pCaps->MaxVShaderInstructionsExecuted    = 65535;
2309             *pCaps->MaxVertexShader30InstructionSlots = 0;
2310         } else { /* VS 1.x */
2311             *pCaps->VS20Caps.Caps                     = 0;
2312             *pCaps->VS20Caps.DynamicFlowControlDepth  = 0;
2313             *pCaps->VS20Caps.NumTemps                 = 0;
2314             *pCaps->VS20Caps.StaticFlowControlDepth   = 0;    
2315
2316             *pCaps->MaxVShaderInstructionsExecuted    = 0;
2317             *pCaps->MaxVertexShader30InstructionSlots = 0;        
2318         }
2319
2320         if(*pCaps->PixelShaderVersion == WINED3DPS_VERSION(3,0)) {
2321             /* Where possible set the caps based on OpenGL extensions and if they aren't set (in case of software rendering)
2322                use the PS 3.0 from MSDN or else if there's OpenGL spec use a hardcoded value minimum PS 3.0 value. */
2323             
2324             /* 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 */
2325             *pCaps->PS20Caps.Caps                     = WINED3DPS20CAPS_ARBITRARYSWIZZLE     |
2326                                                         WINED3DPS20CAPS_GRADIENTINSTRUCTIONS |
2327                                                         WINED3DPS20CAPS_PREDICATION          |
2328                                                         WINED3DPS20CAPS_NODEPENDENTREADLIMIT |
2329                                                         WINED3DPS20CAPS_NOTEXINSTRUCTIONLIMIT;
2330             *pCaps->PS20Caps.DynamicFlowControlDepth  = WINED3DPS20_MAX_DYNAMICFLOWCONTROLDEPTH; /* PS 3.0 requires MAX_DYNAMICFLOWCONTROLDEPTH (24) */
2331             *pCaps->PS20Caps.NumTemps                 = max(32, GLINFO_LOCATION.ps_arb_max_temps);
2332             *pCaps->PS20Caps.StaticFlowControlDepth   = WINED3DPS20_MAX_STATICFLOWCONTROLDEPTH; /* PS 3.0 requires MAX_STATICFLOWCONTROLDEPTH (4) */
2333             *pCaps->PS20Caps.NumInstructionSlots      = WINED3DPS20_MAX_NUMINSTRUCTIONSLOTS; /* PS 3.0 requires MAX_NUMINSTRUCTIONSLOTS (512) */
2334
2335             *pCaps->MaxPShaderInstructionsExecuted    = 65535;
2336             *pCaps->MaxPixelShader30InstructionSlots  = max(WINED3DMIN30SHADERINSTRUCTIONS, GLINFO_LOCATION.ps_arb_max_instructions);
2337         } else if(*pCaps->PixelShaderVersion == WINED3DPS_VERSION(2,0)) {
2338             /* Below we assume PS2.0 specs, not extended 2.0a(GeforceFX)/2.0b(Radeon R3xx) ones */
2339             *pCaps->PS20Caps.Caps                     = 0;
2340             *pCaps->PS20Caps.DynamicFlowControlDepth  = 0; /* WINED3DVS20_MIN_DYNAMICFLOWCONTROLDEPTH = 0 */
2341             *pCaps->PS20Caps.NumTemps                 = max(12, GLINFO_LOCATION.ps_arb_max_temps);
2342             *pCaps->PS20Caps.StaticFlowControlDepth   = WINED3DPS20_MIN_STATICFLOWCONTROLDEPTH; /* Minumum: 1 */
2343             *pCaps->PS20Caps.NumInstructionSlots      = WINED3DPS20_MIN_NUMINSTRUCTIONSLOTS; /* Minimum number (64 ALU + 32 Texture), a GeforceFX uses 512 */
2344
2345             *pCaps->MaxPShaderInstructionsExecuted    = 512; /* Minimum value, a GeforceFX uses 1024 */
2346             *pCaps->MaxPixelShader30InstructionSlots  = 0;
2347         } else { /* PS 1.x */
2348             *pCaps->PS20Caps.Caps                     = 0;
2349             *pCaps->PS20Caps.DynamicFlowControlDepth  = 0;
2350             *pCaps->PS20Caps.NumTemps                 = 0;
2351             *pCaps->PS20Caps.StaticFlowControlDepth   = 0;
2352             *pCaps->PS20Caps.NumInstructionSlots      = 0;
2353
2354             *pCaps->MaxPShaderInstructionsExecuted    = 0;
2355             *pCaps->MaxPixelShader30InstructionSlots  = 0;
2356         }
2357     }
2358
2359     return WINED3D_OK;
2360 }
2361
2362 static unsigned int glsl_program_key_hash(void *key) {
2363     glsl_program_key_t *k = (glsl_program_key_t *)key;
2364
2365     unsigned int hash = k->vshader | k->pshader << 16;
2366     hash += ~(hash << 15);
2367     hash ^=  (hash >> 10);
2368     hash +=  (hash << 3);
2369     hash ^=  (hash >> 6);
2370     hash += ~(hash << 11);
2371     hash ^=  (hash >> 16);
2372
2373     return hash;
2374 }
2375
2376 static BOOL glsl_program_key_compare(void *keya, void *keyb) {
2377     glsl_program_key_t *ka = (glsl_program_key_t *)keya;
2378     glsl_program_key_t *kb = (glsl_program_key_t *)keyb;
2379
2380     return ka->vshader == kb->vshader && ka->pshader == kb->pshader;
2381 }
2382
2383 /* Note due to structure differences between dx8 and dx9 D3DPRESENT_PARAMETERS,
2384    and fields being inserted in the middle, a new structure is used in place    */
2385 static HRESULT  WINAPI IWineD3DImpl_CreateDevice(IWineD3D *iface, UINT Adapter, WINED3DDEVTYPE DeviceType, HWND hFocusWindow,
2386                                            DWORD BehaviourFlags, IWineD3DDevice** ppReturnedDeviceInterface,
2387                                            IUnknown *parent) {
2388
2389     IWineD3DDeviceImpl *object  = NULL;
2390     IWineD3DImpl       *This    = (IWineD3DImpl *)iface;
2391     HDC hDC;
2392     int i;
2393
2394     /* Validate the adapter number. If no adapters are available(no GL), ignore the adapter
2395      * number and create a device without a 3D adapter for 2D only operation.
2396      */
2397     if (IWineD3D_GetAdapterCount(iface) && Adapter >= IWineD3D_GetAdapterCount(iface)) {
2398         return WINED3DERR_INVALIDCALL;
2399     }
2400
2401     /* Create a WineD3DDevice object */
2402     object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IWineD3DDeviceImpl));
2403     *ppReturnedDeviceInterface = (IWineD3DDevice *)object;
2404     TRACE("Created WineD3DDevice object @ %p\n", object);
2405     if (NULL == object) {
2406       return WINED3DERR_OUTOFVIDEOMEMORY;
2407     }
2408
2409     /* Set up initial COM information */
2410     object->lpVtbl  = &IWineD3DDevice_Vtbl;
2411     object->ref     = 1;
2412     object->wineD3D = iface;
2413     object->adapter = numAdapters ? &Adapters[Adapter] : NULL;
2414     IWineD3D_AddRef(object->wineD3D);
2415     object->parent  = parent;
2416
2417     if(This->dxVersion == 7) {
2418         object->surface_alignment = 8;
2419     } else {
2420         object->surface_alignment = 4;
2421     }
2422
2423     /* Set the state up as invalid until the device is fully created */
2424     object->state   = WINED3DERR_DRIVERINTERNALERROR;
2425
2426     TRACE("(%p)->(Adptr:%d, DevType: %x, FocusHwnd: %p, BehFlags: %x, RetDevInt: %p)\n", This, Adapter, DeviceType,
2427           hFocusWindow, BehaviourFlags, ppReturnedDeviceInterface);
2428
2429     /* Save the creation parameters */
2430     object->createParms.AdapterOrdinal = Adapter;
2431     object->createParms.DeviceType     = DeviceType;
2432     object->createParms.hFocusWindow   = hFocusWindow;
2433     object->createParms.BehaviorFlags  = BehaviourFlags;
2434
2435     /* Initialize other useful values */
2436     object->adapterNo                    = Adapter;
2437     object->devType                      = DeviceType;
2438
2439     select_shader_mode(&GLINFO_LOCATION, DeviceType, &object->ps_selected_mode, &object->vs_selected_mode);
2440     if (object->ps_selected_mode == SHADER_GLSL || object->vs_selected_mode == SHADER_GLSL) {
2441         object->shader_backend = &glsl_shader_backend;
2442         object->glsl_program_lookup = hash_table_create(&glsl_program_key_hash, &glsl_program_key_compare);
2443     } else if (object->ps_selected_mode == SHADER_ARB || object->vs_selected_mode == SHADER_ARB) {
2444         object->shader_backend = &arb_program_shader_backend;
2445     } else {
2446         object->shader_backend = &none_shader_backend;
2447     }
2448
2449     /* set the state of the device to valid */
2450     object->state = WINED3D_OK;
2451
2452     /* Get the initial screen setup for ddraw */
2453     object->ddraw_width = GetSystemMetrics(SM_CXSCREEN);
2454     object->ddraw_height = GetSystemMetrics(SM_CYSCREEN);
2455     hDC = GetDC(0);
2456     object->ddraw_format = pixelformat_for_depth(GetDeviceCaps(hDC, BITSPIXEL) * GetDeviceCaps(hDC, PLANES));
2457     ReleaseDC(0, hDC);
2458
2459     for(i = 0; i < PATCHMAP_SIZE; i++) {
2460         list_init(&object->patches[i]);
2461     }
2462     return WINED3D_OK;
2463 }
2464 #undef GLINFO_LOCATION
2465
2466 static HRESULT WINAPI IWineD3DImpl_GetParent(IWineD3D *iface, IUnknown **pParent) {
2467     IWineD3DImpl *This = (IWineD3DImpl *)iface;
2468     IUnknown_AddRef(This->parent);
2469     *pParent = This->parent;
2470     return WINED3D_OK;
2471 }
2472
2473 ULONG WINAPI D3DCB_DefaultDestroySurface(IWineD3DSurface *pSurface) {
2474     IUnknown* surfaceParent;
2475     TRACE("(%p) call back\n", pSurface);
2476
2477     /* Now, release the parent, which will take care of cleaning up the surface for us */
2478     IWineD3DSurface_GetParent(pSurface, &surfaceParent);
2479     IUnknown_Release(surfaceParent);
2480     return IUnknown_Release(surfaceParent);
2481 }
2482
2483 ULONG WINAPI D3DCB_DefaultDestroyVolume(IWineD3DVolume *pVolume) {
2484     IUnknown* volumeParent;
2485     TRACE("(%p) call back\n", pVolume);
2486
2487     /* Now, release the parent, which will take care of cleaning up the volume for us */
2488     IWineD3DVolume_GetParent(pVolume, &volumeParent);
2489     IUnknown_Release(volumeParent);
2490     return IUnknown_Release(volumeParent);
2491 }
2492
2493 #define PUSH1(att)        attribs[nAttribs++] = (att);
2494 #define GLINFO_LOCATION (Adapters[0].gl_info)
2495 BOOL InitAdapters(void) {
2496     static HMODULE mod_gl;
2497     BOOL ret;
2498     int ps_selected_mode, vs_selected_mode;
2499
2500     /* No need to hold any lock. The calling library makes sure only one thread calls
2501      * wined3d simultaneously
2502      */
2503     if(numAdapters > 0) return TRUE;
2504
2505     TRACE("Initializing adapters\n");
2506
2507     if(!mod_gl) {
2508 #ifdef USE_WIN32_OPENGL
2509 #define USE_GL_FUNC(pfn) pfn = (void*)GetProcAddress(mod_gl, #pfn);
2510         mod_gl = LoadLibraryA("opengl32.dll");
2511         if(!mod_gl) {
2512             ERR("Can't load opengl32.dll!\n");
2513             return FALSE;
2514         }
2515 #else
2516 #define USE_GL_FUNC(pfn) pfn = (void*)pwglGetProcAddress(#pfn);
2517         /* To bypass the opengl32 thunks load wglGetProcAddress from gdi32 (glXGetProcAddress wrapper) instead of opengl32's */
2518         mod_gl = GetModuleHandleA("gdi32.dll");
2519 #endif
2520     }
2521
2522 /* Load WGL core functions from opengl32.dll */
2523 #define USE_WGL_FUNC(pfn) p##pfn = (void*)GetProcAddress(mod_gl, #pfn);
2524     WGL_FUNCS_GEN;
2525 #undef USE_WGL_FUNC
2526
2527     if(!pwglGetProcAddress) {
2528         ERR("Unable to load wglGetProcAddress!\n");
2529         return FALSE;
2530     }
2531
2532 /* Dynamically load all GL core functions */
2533     GL_FUNCS_GEN;
2534 #undef USE_GL_FUNC
2535
2536     /* For now only one default adapter */
2537     {
2538         int iPixelFormat;
2539         int attribs[8];
2540         int values[8];
2541         int nAttribs = 0;
2542         int res;
2543         WineD3D_PixelFormat *cfgs;
2544         int attribute;
2545         DISPLAY_DEVICEW DisplayDevice;
2546         HDC hdc;
2547
2548         TRACE("Initializing default adapter\n");
2549         Adapters[0].monitorPoint.x = -1;
2550         Adapters[0].monitorPoint.y = -1;
2551
2552         if (!WineD3D_CreateFakeGLContext()) {
2553             ERR("Failed to get a gl context for default adapter\n");
2554             HeapFree(GetProcessHeap(), 0, Adapters);
2555             WineD3D_ReleaseFakeGLContext();
2556             return FALSE;
2557         }
2558
2559         ret = IWineD3DImpl_FillGLCaps(&Adapters[0].gl_info);
2560         if(!ret) {
2561             ERR("Failed to initialize gl caps for default adapter\n");
2562             HeapFree(GetProcessHeap(), 0, Adapters);
2563             WineD3D_ReleaseFakeGLContext();
2564             return FALSE;
2565         }
2566         ret = initPixelFormats(&Adapters[0].gl_info);
2567         if(!ret) {
2568             ERR("Failed to init gl formats\n");
2569             HeapFree(GetProcessHeap(), 0, Adapters);
2570             WineD3D_ReleaseFakeGLContext();
2571             return FALSE;
2572         }
2573
2574         hdc = pwglGetCurrentDC();
2575         if(!hdc) {
2576             ERR("Failed to get gl HDC\n");
2577             HeapFree(GetProcessHeap(), 0, Adapters);
2578             WineD3D_ReleaseFakeGLContext();
2579             return FALSE;
2580         }
2581
2582         Adapters[0].driver = "Display";
2583         Adapters[0].description = "Direct3D HAL";
2584
2585         /* Initialize the Adapter's DeviceName which is required for ChangeDisplaySettings and friends */
2586         DisplayDevice.cb = sizeof(DisplayDevice);
2587         EnumDisplayDevicesW(NULL, 0 /* Adapter 0 = iDevNum 0 */, &DisplayDevice, 0);
2588         TRACE("DeviceName: %s\n", debugstr_w(DisplayDevice.DeviceName));
2589         strcpyW(Adapters[0].DeviceName, DisplayDevice.DeviceName);
2590
2591         attribute = WGL_NUMBER_PIXEL_FORMATS_ARB;
2592         GL_EXTCALL(wglGetPixelFormatAttribivARB(hdc, 0, 0, 1, &attribute, &Adapters[0].nCfgs));
2593
2594         Adapters[0].cfgs = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, Adapters[0].nCfgs *sizeof(WineD3D_PixelFormat));
2595         cfgs = Adapters[0].cfgs;
2596         PUSH1(WGL_RED_BITS_ARB)
2597         PUSH1(WGL_GREEN_BITS_ARB)
2598         PUSH1(WGL_BLUE_BITS_ARB)
2599         PUSH1(WGL_ALPHA_BITS_ARB)
2600         PUSH1(WGL_DEPTH_BITS_ARB)
2601         PUSH1(WGL_STENCIL_BITS_ARB)
2602
2603         for(iPixelFormat=1; iPixelFormat<=Adapters[0].nCfgs; iPixelFormat++) {
2604             res = GL_EXTCALL(wglGetPixelFormatAttribivARB(hdc, iPixelFormat, 0, nAttribs, attribs, values));
2605
2606             if(!res)
2607                 continue;
2608
2609             /* Cache the pixel format */
2610             cfgs->iPixelFormat = iPixelFormat;
2611             cfgs->redSize = values[0];
2612             cfgs->greenSize = values[1];
2613             cfgs->blueSize = values[2];
2614             cfgs->alphaSize = values[3];
2615             cfgs->depthSize = values[4];
2616             cfgs->stencilSize = values[5];
2617
2618             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);
2619             cfgs++;
2620         }
2621         WineD3D_ReleaseFakeGLContext();
2622
2623         select_shader_mode(&Adapters[0].gl_info, WINED3DDEVTYPE_HAL, &ps_selected_mode, &vs_selected_mode);
2624         select_shader_max_constants(ps_selected_mode, vs_selected_mode, &Adapters[0].gl_info);
2625
2626     }
2627     numAdapters = 1;
2628     TRACE("%d adapters successfully initialized\n", numAdapters);
2629
2630     return TRUE;
2631 }
2632 #undef PUSH1
2633 #undef GLINFO_LOCATION
2634
2635 /**********************************************************
2636  * IWineD3D VTbl follows
2637  **********************************************************/
2638
2639 const IWineD3DVtbl IWineD3D_Vtbl =
2640 {
2641     /* IUnknown */
2642     IWineD3DImpl_QueryInterface,
2643     IWineD3DImpl_AddRef,
2644     IWineD3DImpl_Release,
2645     /* IWineD3D */
2646     IWineD3DImpl_GetParent,
2647     IWineD3DImpl_GetAdapterCount,
2648     IWineD3DImpl_RegisterSoftwareDevice,
2649     IWineD3DImpl_GetAdapterMonitor,
2650     IWineD3DImpl_GetAdapterModeCount,
2651     IWineD3DImpl_EnumAdapterModes,
2652     IWineD3DImpl_GetAdapterDisplayMode,
2653     IWineD3DImpl_GetAdapterIdentifier,
2654     IWineD3DImpl_CheckDeviceMultiSampleType,
2655     IWineD3DImpl_CheckDepthStencilMatch,
2656     IWineD3DImpl_CheckDeviceType,
2657     IWineD3DImpl_CheckDeviceFormat,
2658     IWineD3DImpl_CheckDeviceFormatConversion,
2659     IWineD3DImpl_GetDeviceCaps,
2660     IWineD3DImpl_CreateDevice
2661 };