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