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