wined3d: Fixed a bug that the 8600M GT could not be detected.
[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                 TRACE_(d3d_caps)("[FAILED] - No converted formats on volumes\n");
1750                 return WINED3DERR_NOTAVAILABLE;
1751
1752             case WINED3DFMT_Q8W8V8U8:
1753             case WINED3DFMT_V16U16:
1754             if(!GL_SUPPORT(NV_TEXTURE_SHADER)) {
1755                 TRACE_(d3d_caps)("[FAILED] - No converted formats on volumes\n");
1756                 return WINED3DERR_NOTAVAILABLE;
1757             }
1758             break;
1759
1760             case WINED3DFMT_V8U8:
1761             if(!GL_SUPPORT(NV_TEXTURE_SHADER) || !GL_SUPPORT(ATI_ENVMAP_BUMPMAP)) {
1762                 TRACE_(d3d_caps)("[FAILED] - No converted formats on volumes\n");
1763                 return WINED3DERR_NOTAVAILABLE;
1764             }
1765             break;
1766
1767             case WINED3DFMT_DXT1:
1768             case WINED3DFMT_DXT2:
1769             case WINED3DFMT_DXT3:
1770             case WINED3DFMT_DXT4:
1771             case WINED3DFMT_DXT5:
1772                 /* The GL_EXT_texture_compression_s3tc spec requires that loading an s3tc
1773                  * compressed texture results in an error. While the D3D refrast does
1774                  * support s3tc volumes, at least the nvidia windows driver does not, so
1775                  * we're free not to support this format.
1776                  */
1777                 TRACE_(d3d_caps)("[FAILED] - DXTn does not support 3D textures\n");
1778                 return WINED3DERR_NOTAVAILABLE;
1779
1780             default:
1781                 /* Do nothing, continue with checking the format below */
1782                 break;
1783         }
1784     }
1785     /* TODO: Check support against more of the WINED3DUSAGE_QUERY_* constants
1786      * See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/directx9_c/IDirect3D9__CheckDeviceFormat.asp
1787      * and http://msdn.microsoft.com/library/default.asp?url=/library/en-us/directx9_c/D3DUSAGE_QUERY.asp */
1788     if (Usage & WINED3DUSAGE_QUERY_VERTEXTEXTURE) {
1789         if (!GL_LIMITS(vertex_samplers)) {
1790             TRACE_(d3d_caps)("[FAILED]\n");
1791             return WINED3DERR_NOTAVAILABLE;
1792         }
1793
1794         switch (CheckFormat) {
1795             case WINED3DFMT_A32B32G32R32F:
1796                 if (!GL_SUPPORT(ARB_TEXTURE_FLOAT)) {
1797                     TRACE_(d3d_caps)("[FAILED]\n");
1798                     return WINED3DERR_NOTAVAILABLE;
1799                 }
1800                 TRACE_(d3d_caps)("[OK]\n");
1801                 return WINED3D_OK;
1802
1803             default:
1804                 TRACE_(d3d_caps)("[FAILED]\n");
1805                 return WINED3DERR_NOTAVAILABLE;
1806         }
1807     }
1808
1809     if(Usage & WINED3DUSAGE_DEPTHSTENCIL) {
1810         switch (CheckFormat) {
1811             /* In theory we could do all formats, just fetch them accordingly should the buffer be locked.
1812              * Windows supports only those 3, and enumerating the other formats confuses applications
1813              */
1814             case WINED3DFMT_D24S8:
1815             case WINED3DFMT_D24X8:
1816             case WINED3DFMT_D16:
1817                 TRACE_(d3d_caps)("[OK]\n");
1818                 return WINED3D_OK;
1819             case WINED3DFMT_D16_LOCKABLE:
1820             case WINED3DFMT_D24FS8:
1821             case WINED3DFMT_D32F_LOCKABLE:
1822             case WINED3DFMT_D24X4S4:
1823             case WINED3DFMT_D15S1:
1824             case WINED3DFMT_D32:
1825                 TRACE_(d3d_caps)("[FAILED]. Disabled because not enumerated on windows\n");
1826                 return WINED3DERR_NOTAVAILABLE;
1827             default:
1828                 TRACE_(d3d_caps)("[FAILED]\n");
1829                 return WINED3DERR_NOTAVAILABLE;
1830         }
1831     } else if(Usage & WINED3DUSAGE_RENDERTARGET) {
1832         switch (CheckFormat) {
1833             case WINED3DFMT_R8G8B8:
1834             case WINED3DFMT_A8R8G8B8:
1835             case WINED3DFMT_X8R8G8B8:
1836             case WINED3DFMT_R5G6B5:
1837             case WINED3DFMT_X1R5G5B5:
1838             case WINED3DFMT_A1R5G5B5:
1839             case WINED3DFMT_A4R4G4B4:
1840             case WINED3DFMT_R3G3B2:
1841             case WINED3DFMT_X4R4G4B4:
1842             case WINED3DFMT_A8B8G8R8:
1843             case WINED3DFMT_X8B8G8R8:
1844             case WINED3DFMT_P8:
1845                 TRACE_(d3d_caps)("[OK]\n");
1846                 return WINED3D_OK;
1847             case WINED3DFMT_R16F:
1848             case WINED3DFMT_A16B16G16R16F:
1849                 if (!GL_SUPPORT(ARB_HALF_FLOAT_PIXEL) || !GL_SUPPORT(ARB_TEXTURE_FLOAT)) {
1850                     TRACE_(d3d_caps)("[FAILED]\n");
1851                     return WINED3DERR_NOTAVAILABLE;
1852                 }
1853                 TRACE_(d3d_caps)("[OK]\n");
1854                 return WINED3D_OK;
1855             case WINED3DFMT_A32B32G32R32F:
1856                if (!GL_SUPPORT(ARB_TEXTURE_FLOAT)) {
1857                     TRACE_(d3d_caps)("[FAILED]\n");
1858                     return WINED3DERR_NOTAVAILABLE;
1859                 }
1860                 TRACE_(d3d_caps)("[OK]\n");
1861                 return WINED3D_OK;
1862             default:
1863                 TRACE_(d3d_caps)("[FAILED]\n");
1864                 return WINED3DERR_NOTAVAILABLE;
1865         }
1866     } else if(Usage & WINED3DUSAGE_QUERY_LEGACYBUMPMAP) {
1867         if(GL_SUPPORT(NV_REGISTER_COMBINERS) && GL_SUPPORT(NV_TEXTURE_SHADER2)) {
1868             switch (CheckFormat) {
1869                 case WINED3DFMT_V8U8:
1870                     TRACE_(d3d_caps)("[OK]\n");
1871                     return WINED3D_OK;
1872                 /* TODO: Other bump map formats */
1873                 default:
1874                     TRACE_(d3d_caps)("[FAILED]\n");
1875                     return WINED3DERR_NOTAVAILABLE;
1876             }
1877         }
1878         if(GL_SUPPORT(ATI_ENVMAP_BUMPMAP)) {
1879             switch (CheckFormat) {
1880                 case WINED3DFMT_V8U8:
1881                     TRACE_(d3d_caps)("[OK]\n");
1882                     return WINED3D_OK;
1883                 default:
1884                     TRACE_(d3d_caps)("[FAILED]\n");
1885                     return WINED3DERR_NOTAVAILABLE;
1886             }
1887         }
1888         TRACE_(d3d_caps)("[FAILED]\n");
1889         return WINED3DERR_NOTAVAILABLE;
1890     }
1891
1892     if (GL_SUPPORT(EXT_TEXTURE_COMPRESSION_S3TC)) {
1893         switch (CheckFormat) {
1894         case WINED3DFMT_DXT1:
1895         case WINED3DFMT_DXT2:
1896         case WINED3DFMT_DXT3:
1897         case WINED3DFMT_DXT4:
1898         case WINED3DFMT_DXT5:
1899           TRACE_(d3d_caps)("[OK]\n");
1900           return WINED3D_OK;
1901         default:
1902             break; /* Avoid compiler warnings */
1903         }
1904     }
1905
1906     /* Check for supported sRGB formats (Texture loading and framebuffer) */
1907     if (GL_SUPPORT(EXT_TEXTURE_SRGB) && (Usage & WINED3DUSAGE_QUERY_SRGBREAD)) {
1908         switch (CheckFormat) {
1909             case WINED3DFMT_A8R8G8B8:
1910             case WINED3DFMT_X8R8G8B8:
1911             case WINED3DFMT_A4R4G4B4:
1912             case WINED3DFMT_L8:
1913             case WINED3DFMT_A8L8:
1914             case WINED3DFMT_DXT1:
1915             case WINED3DFMT_DXT2:
1916             case WINED3DFMT_DXT3:
1917             case WINED3DFMT_DXT4:
1918             case WINED3DFMT_DXT5:
1919                 TRACE_(d3d_caps)("[OK]\n");
1920                 return WINED3D_OK;
1921
1922             default:
1923                 TRACE_(d3d_caps)("[FAILED] Gamma texture format %s not supported.\n", debug_d3dformat(CheckFormat));
1924                 return WINED3DERR_NOTAVAILABLE;
1925         }
1926     }
1927
1928     if (GL_SUPPORT(ARB_TEXTURE_FLOAT)) {
1929
1930         BOOL half_pixel_support = GL_SUPPORT(ARB_HALF_FLOAT_PIXEL);
1931
1932         switch (CheckFormat) {
1933             case WINED3DFMT_R16F:
1934             case WINED3DFMT_A16B16G16R16F:
1935                 if (!half_pixel_support) break;
1936             case WINED3DFMT_R32F:
1937             case WINED3DFMT_A32B32G32R32F:
1938                 TRACE_(d3d_caps)("[OK]\n");
1939                 return WINED3D_OK;
1940             default:
1941                 break; /* Avoid compiler warnings */
1942         }
1943     }
1944
1945     /* This format is nothing special and it is supported perfectly.
1946      * However, ati and nvidia driver on windows do not mark this format as
1947      * supported (tested with the dxCapsViewer) and pretending to
1948      * support this format uncovers a bug in Battlefield 1942 (fonts are missing)
1949      * So do the same as Windows drivers and pretend not to support it on dx8 and 9
1950      * Enable it on dx7. It will need additional checking on dx10 when we support it.
1951      */
1952     if(This->dxVersion > 7 && CheckFormat == WINED3DFMT_R8G8B8) {
1953         TRACE_(d3d_caps)("[FAILED]\n");
1954         return WINED3DERR_NOTAVAILABLE;
1955     }
1956
1957     switch (CheckFormat) {
1958
1959         /*****
1960          *  supported: RGB(A) formats
1961          */
1962         case WINED3DFMT_R8G8B8: /* Enable for dx7, blacklisted for 8 and 9 above */
1963         case WINED3DFMT_A8R8G8B8:
1964         case WINED3DFMT_X8R8G8B8:
1965         case WINED3DFMT_R5G6B5:
1966         case WINED3DFMT_X1R5G5B5:
1967         case WINED3DFMT_A1R5G5B5:
1968         case WINED3DFMT_A4R4G4B4:
1969         case WINED3DFMT_R3G3B2:
1970         case WINED3DFMT_A8:
1971         case WINED3DFMT_X4R4G4B4:
1972         case WINED3DFMT_A8B8G8R8:
1973         case WINED3DFMT_X8B8G8R8:
1974         case WINED3DFMT_A2R10G10B10:
1975         case WINED3DFMT_A2B10G10R10:
1976             TRACE_(d3d_caps)("[OK]\n");
1977             return WINED3D_OK;
1978
1979         /*****
1980          *  supported: Palettized
1981          */
1982         case WINED3DFMT_P8:
1983             TRACE_(d3d_caps)("[OK]\n");
1984             return WINED3D_OK;
1985
1986         /*****
1987          *  Supported: (Alpha)-Luminance
1988          */
1989         case WINED3DFMT_L8:
1990         case WINED3DFMT_A8L8:
1991         case WINED3DFMT_A4L4:
1992             TRACE_(d3d_caps)("[OK]\n");
1993             return WINED3D_OK;
1994
1995         /*****
1996          *  Not supported everywhere(depends on GL_ATI_envmap_bumpmap or
1997          *  GL_NV_texture_shader), but advertized to make apps happy.
1998          *  Enable some because games often fail when they are not available
1999          *  and are still playable even without bump mapping
2000          */
2001         case WINED3DFMT_V8U8:
2002         case WINED3DFMT_V16U16:
2003         case WINED3DFMT_L6V5U5:
2004         case WINED3DFMT_X8L8V8U8:
2005         case WINED3DFMT_Q8W8V8U8:
2006             WARN_(d3d_caps)("[Not supported, but pretended to do]\n");
2007             return WINED3D_OK;
2008
2009         /* Those are not advertized by the nvidia windows driver, and not
2010          * supported natively by GL_NV_texture_shader or GL_ATI_envmap_bumpmap.
2011          * WINED3DFMT_A2W10V10U10 could be loaded into shaders using the unsigned
2012          * ARGB format if needed
2013          */
2014         case WINED3DFMT_W11V11U10:
2015         case WINED3DFMT_A2W10V10U10:
2016             WARN_(d3d_caps)("[FAILED]\n");
2017             return WINED3DERR_NOTAVAILABLE;
2018
2019         /*****
2020          *  DXTN Formats: Handled above
2021          * WINED3DFMT_DXT1
2022          * WINED3DFMT_DXT2
2023          * WINED3DFMT_DXT3
2024          * WINED3DFMT_DXT4
2025          * WINED3DFMT_DXT5
2026          */
2027
2028         /*****
2029          *  Odd formats - not supported
2030          */
2031         case WINED3DFMT_VERTEXDATA:
2032         case WINED3DFMT_INDEX16:
2033         case WINED3DFMT_INDEX32:
2034         case WINED3DFMT_Q16W16V16U16:
2035             TRACE_(d3d_caps)("[FAILED]\n"); /* Enable when implemented */
2036             return WINED3DERR_NOTAVAILABLE;
2037
2038         /*****
2039          *  Float formats: Not supported right now
2040          */
2041         case WINED3DFMT_G16R16F:
2042         case WINED3DFMT_G32R32F:
2043         case WINED3DFMT_CxV8U8:
2044             TRACE_(d3d_caps)("[FAILED]\n"); /* Enable when implemented */
2045             return WINED3DERR_NOTAVAILABLE;
2046
2047             /* Not supported */
2048         case WINED3DFMT_G16R16:
2049         case WINED3DFMT_A16B16G16R16:
2050         case WINED3DFMT_A8R3G3B2:
2051             TRACE_(d3d_caps)("[FAILED]\n"); /* Enable when implemented */
2052             return WINED3DERR_NOTAVAILABLE;
2053
2054         /* ATI instancing hack: Although ATI cards do not support Shader Model 3.0, they support
2055          * instancing. To query if the card supports instancing CheckDeviceFormat with the special format
2056          * MAKEFOURCC('I','N','S','T') is used. Should a (broken) app check for this provide a proper return value.
2057          * We can do instancing with all shader versions, but we need vertex shaders.
2058          *
2059          * Additionally applications have to set the D3DRS_POINTSIZE render state to MAKEFOURCC('I','N','S','T') once
2060          * to enable instancing. WineD3D doesn't need that and just ignores it.
2061          *
2062          * With Shader Model 3.0 capable cards Instancing 'just works' in Windows.
2063          */
2064         case WINEMAKEFOURCC('I','N','S','T'):
2065             TRACE("ATI Instancing check hack\n");
2066             if(GL_SUPPORT(ARB_VERTEX_PROGRAM) || GL_SUPPORT(ARB_VERTEX_SHADER)) {
2067                 TRACE_(d3d_caps)("[OK]\n");
2068                 return WINED3D_OK;
2069             } else {
2070                 TRACE_(d3d_caps)("[FAILED]\n");
2071                 return WINED3DERR_NOTAVAILABLE;
2072             }
2073
2074         default:
2075             break;
2076     }
2077
2078     TRACE_(d3d_caps)("[FAILED]\n");
2079     return WINED3DERR_NOTAVAILABLE;
2080 }
2081
2082 static HRESULT  WINAPI IWineD3DImpl_CheckDeviceFormatConversion(IWineD3D *iface, UINT Adapter, WINED3DDEVTYPE DeviceType,
2083                                                           WINED3DFORMAT SourceFormat, WINED3DFORMAT TargetFormat) {
2084     IWineD3DImpl *This = (IWineD3DImpl *)iface;
2085
2086     FIXME_(d3d_caps)("(%p)-> (STUB) (Adptr:%d, DevType:(%u,%s), SrcFmt:(%u,%s), TgtFmt:(%u,%s))\n",
2087           This,
2088           Adapter,
2089           DeviceType, debug_d3ddevicetype(DeviceType),
2090           SourceFormat, debug_d3dformat(SourceFormat),
2091           TargetFormat, debug_d3dformat(TargetFormat));
2092     return WINED3D_OK;
2093 }
2094
2095 /* Note: d3d8 passes in a pointer to a D3DCAPS8 structure, which is a true
2096       subset of a D3DCAPS9 structure. However, it has to come via a void *
2097       as the d3d8 interface cannot import the d3d9 header                  */
2098 static HRESULT WINAPI IWineD3DImpl_GetDeviceCaps(IWineD3D *iface, UINT Adapter, WINED3DDEVTYPE DeviceType, WINED3DCAPS* pCaps) {
2099
2100     IWineD3DImpl    *This = (IWineD3DImpl *)iface;
2101     int vs_selected_mode;
2102     int ps_selected_mode;
2103
2104     TRACE_(d3d_caps)("(%p)->(Adptr:%d, DevType: %x, pCaps: %p)\n", This, Adapter, DeviceType, pCaps);
2105
2106     if (Adapter >= IWineD3D_GetAdapterCount(iface)) {
2107         return WINED3DERR_INVALIDCALL;
2108     }
2109
2110     select_shader_mode(&Adapters[Adapter].gl_info, DeviceType, &ps_selected_mode, &vs_selected_mode);
2111
2112     /* This function should *not* be modifying GL caps
2113      * TODO: move the functionality where it belongs */
2114     select_shader_max_constants(ps_selected_mode, vs_selected_mode, &Adapters[Adapter].gl_info);
2115
2116     /* ------------------------------------------------
2117        The following fields apply to both d3d8 and d3d9
2118        ------------------------------------------------ */
2119     *pCaps->DeviceType              = (DeviceType == WINED3DDEVTYPE_HAL) ? WINED3DDEVTYPE_HAL : WINED3DDEVTYPE_REF;  /* Not quite true, but use h/w supported by opengl I suppose */
2120     *pCaps->AdapterOrdinal          = Adapter;
2121
2122     *pCaps->Caps                    = 0;
2123     *pCaps->Caps2                   = WINED3DCAPS2_CANRENDERWINDOWED |
2124                                       WINED3DCAPS2_FULLSCREENGAMMA |
2125                                       WINED3DCAPS2_DYNAMICTEXTURES;
2126     if(GL_SUPPORT(SGIS_GENERATE_MIPMAP)) {
2127         *pCaps->Caps2 |= WINED3DCAPS2_CANAUTOGENMIPMAP;
2128     }
2129     *pCaps->Caps3                   = WINED3DCAPS3_ALPHA_FULLSCREEN_FLIP_OR_DISCARD;
2130     *pCaps->PresentationIntervals   = WINED3DPRESENT_INTERVAL_IMMEDIATE  |
2131                                       WINED3DPRESENT_INTERVAL_ONE;
2132
2133     *pCaps->CursorCaps              = WINED3DCURSORCAPS_COLOR            |
2134                                       WINED3DCURSORCAPS_LOWRES;
2135
2136     *pCaps->DevCaps                 = WINED3DDEVCAPS_FLOATTLVERTEX       |
2137                                       WINED3DDEVCAPS_EXECUTESYSTEMMEMORY |
2138                                       WINED3DDEVCAPS_TLVERTEXSYSTEMMEMORY|
2139                                       WINED3DDEVCAPS_TLVERTEXVIDEOMEMORY |
2140                                       WINED3DDEVCAPS_DRAWPRIMTLVERTEX    |
2141                                       WINED3DDEVCAPS_HWTRANSFORMANDLIGHT |
2142                                       WINED3DDEVCAPS_EXECUTEVIDEOMEMORY  |
2143                                       WINED3DDEVCAPS_PUREDEVICE          |
2144                                       WINED3DDEVCAPS_HWRASTERIZATION     |
2145                                       WINED3DDEVCAPS_TEXTUREVIDEOMEMORY  |
2146                                       WINED3DDEVCAPS_TEXTURESYSTEMMEMORY |
2147                                       WINED3DDEVCAPS_CANRENDERAFTERFLIP  |
2148                                       WINED3DDEVCAPS_DRAWPRIMITIVES2     |
2149                                       WINED3DDEVCAPS_DRAWPRIMITIVES2EX   |
2150                                       WINED3DDEVCAPS_RTPATCHES;
2151
2152     *pCaps->PrimitiveMiscCaps       = WINED3DPMISCCAPS_CULLNONE              |
2153                                       WINED3DPMISCCAPS_CULLCCW               |
2154                                       WINED3DPMISCCAPS_CULLCW                |
2155                                       WINED3DPMISCCAPS_COLORWRITEENABLE      |
2156                                       WINED3DPMISCCAPS_CLIPTLVERTS           |
2157                                       WINED3DPMISCCAPS_CLIPPLANESCALEDPOINTS |
2158                                       WINED3DPMISCCAPS_MASKZ                 |
2159                                       WINED3DPMISCCAPS_BLENDOP;
2160                                     /* TODO:
2161                                         WINED3DPMISCCAPS_NULLREFERENCE
2162                                         WINED3DPMISCCAPS_INDEPENDENTWRITEMASKS
2163                                         WINED3DPMISCCAPS_FOGANDSPECULARALPHA
2164                                         WINED3DPMISCCAPS_SEPARATEALPHABLEND
2165                                         WINED3DPMISCCAPS_MRTINDEPENDENTBITDEPTHS
2166                                         WINED3DPMISCCAPS_MRTPOSTPIXELSHADERBLENDING
2167                                         WINED3DPMISCCAPS_FOGVERTEXCLAMPED */
2168
2169 /* The caps below can be supported but aren't handled yet in utils.c 'd3dta_to_combiner_input', disable them until support is fixed */
2170 #if 0
2171     if (GL_SUPPORT(NV_REGISTER_COMBINERS))
2172         *pCaps->PrimitiveMiscCaps |=  WINED3DPMISCCAPS_TSSARGTEMP;
2173     if (GL_SUPPORT(NV_REGISTER_COMBINERS2))
2174         *pCaps->PrimitiveMiscCaps |=  WINED3DPMISCCAPS_PERSTAGECONSTANT;
2175 #endif
2176
2177     *pCaps->RasterCaps              = WINED3DPRASTERCAPS_DITHER    |
2178                                       WINED3DPRASTERCAPS_PAT       |
2179                                       WINED3DPRASTERCAPS_WFOG      |
2180                                       WINED3DPRASTERCAPS_ZFOG      |
2181                                       WINED3DPRASTERCAPS_FOGVERTEX |
2182                                       WINED3DPRASTERCAPS_FOGTABLE  |
2183                                       WINED3DPRASTERCAPS_STIPPLE   |
2184                                       WINED3DPRASTERCAPS_SUBPIXEL  |
2185                                       WINED3DPRASTERCAPS_ZTEST     |
2186                                       WINED3DPRASTERCAPS_SCISSORTEST   |
2187                                       WINED3DPRASTERCAPS_SLOPESCALEDEPTHBIAS |
2188                                       WINED3DPRASTERCAPS_DEPTHBIAS;
2189
2190     if (GL_SUPPORT(EXT_TEXTURE_FILTER_ANISOTROPIC)) {
2191       *pCaps->RasterCaps |= WINED3DPRASTERCAPS_ANISOTROPY    |
2192                             WINED3DPRASTERCAPS_ZBIAS         |
2193                             WINED3DPRASTERCAPS_MIPMAPLODBIAS;
2194     }
2195     if(GL_SUPPORT(NV_FOG_DISTANCE)) {
2196         *pCaps->RasterCaps         |= WINED3DPRASTERCAPS_FOGRANGE;
2197     }
2198                         /* FIXME Add:
2199                            WINED3DPRASTERCAPS_COLORPERSPECTIVE
2200                            WINED3DPRASTERCAPS_STRETCHBLTMULTISAMPLE
2201                            WINED3DPRASTERCAPS_ANTIALIASEDGES
2202                            WINED3DPRASTERCAPS_ZBUFFERLESSHSR
2203                            WINED3DPRASTERCAPS_WBUFFER */
2204
2205     *pCaps->ZCmpCaps = WINED3DPCMPCAPS_ALWAYS       |
2206                        WINED3DPCMPCAPS_EQUAL        |
2207                        WINED3DPCMPCAPS_GREATER      |
2208                        WINED3DPCMPCAPS_GREATEREQUAL |
2209                        WINED3DPCMPCAPS_LESS         |
2210                        WINED3DPCMPCAPS_LESSEQUAL    |
2211                        WINED3DPCMPCAPS_NEVER        |
2212                        WINED3DPCMPCAPS_NOTEQUAL;
2213
2214     *pCaps->SrcBlendCaps  = WINED3DPBLENDCAPS_BLENDFACTOR     |
2215                             WINED3DPBLENDCAPS_BOTHINVSRCALPHA |
2216                             WINED3DPBLENDCAPS_BOTHSRCALPHA    |
2217                             WINED3DPBLENDCAPS_DESTALPHA       |
2218                             WINED3DPBLENDCAPS_DESTCOLOR       |
2219                             WINED3DPBLENDCAPS_INVDESTALPHA    |
2220                             WINED3DPBLENDCAPS_INVDESTCOLOR    |
2221                             WINED3DPBLENDCAPS_INVSRCALPHA     |
2222                             WINED3DPBLENDCAPS_INVSRCCOLOR     |
2223                             WINED3DPBLENDCAPS_ONE             |
2224                             WINED3DPBLENDCAPS_SRCALPHA        |
2225                             WINED3DPBLENDCAPS_SRCALPHASAT     |
2226                             WINED3DPBLENDCAPS_SRCCOLOR        |
2227                             WINED3DPBLENDCAPS_ZERO;
2228
2229     *pCaps->DestBlendCaps = WINED3DPBLENDCAPS_BLENDFACTOR     |
2230                             WINED3DPBLENDCAPS_DESTALPHA       |
2231                             WINED3DPBLENDCAPS_DESTCOLOR       |
2232                             WINED3DPBLENDCAPS_INVDESTALPHA    |
2233                             WINED3DPBLENDCAPS_INVDESTCOLOR    |
2234                             WINED3DPBLENDCAPS_INVSRCALPHA     |
2235                             WINED3DPBLENDCAPS_INVSRCCOLOR     |
2236                             WINED3DPBLENDCAPS_ONE             |
2237                             WINED3DPBLENDCAPS_SRCALPHA        |
2238                             WINED3DPBLENDCAPS_SRCCOLOR        |
2239                             WINED3DPBLENDCAPS_ZERO;
2240     /* NOTE: WINED3DPBLENDCAPS_SRCALPHASAT is not supported as dest blend factor,
2241      * according to the glBlendFunc manpage
2242      *
2243      * WINED3DPBLENDCAPS_BOTHINVSRCALPHA and WINED3DPBLENDCAPS_BOTHSRCALPHA are
2244      * legacy settings for srcblend only
2245      */
2246
2247     *pCaps->AlphaCmpCaps = WINED3DPCMPCAPS_ALWAYS       |
2248                            WINED3DPCMPCAPS_EQUAL        |
2249                            WINED3DPCMPCAPS_GREATER      |
2250                            WINED3DPCMPCAPS_GREATEREQUAL |
2251                            WINED3DPCMPCAPS_LESS         |
2252                            WINED3DPCMPCAPS_LESSEQUAL    |
2253                            WINED3DPCMPCAPS_NEVER        |
2254                            WINED3DPCMPCAPS_NOTEQUAL;
2255
2256     *pCaps->ShadeCaps     = WINED3DPSHADECAPS_SPECULARGOURAUDRGB |
2257                             WINED3DPSHADECAPS_COLORGOURAUDRGB    |
2258                             WINED3DPSHADECAPS_ALPHAFLATBLEND     |
2259                             WINED3DPSHADECAPS_ALPHAGOURAUDBLEND  |
2260                             WINED3DPSHADECAPS_COLORFLATRGB       |
2261                             WINED3DPSHADECAPS_FOGFLAT            |
2262                             WINED3DPSHADECAPS_FOGGOURAUD         |
2263                             WINED3DPSHADECAPS_SPECULARFLATRGB;
2264
2265     *pCaps->TextureCaps =  WINED3DPTEXTURECAPS_ALPHA              |
2266                            WINED3DPTEXTURECAPS_ALPHAPALETTE       |
2267                            WINED3DPTEXTURECAPS_BORDER             |
2268                            WINED3DPTEXTURECAPS_MIPMAP             |
2269                            WINED3DPTEXTURECAPS_PROJECTED          |
2270                            WINED3DPTEXTURECAPS_PERSPECTIVE;
2271
2272     if( !GL_SUPPORT(ARB_TEXTURE_NON_POWER_OF_TWO)) {
2273         *pCaps->TextureCaps |= WINED3DPTEXTURECAPS_POW2 |
2274                                 WINED3DPTEXTURECAPS_NONPOW2CONDITIONAL;
2275     }
2276
2277     if( GL_SUPPORT(EXT_TEXTURE3D)) {
2278         *pCaps->TextureCaps |=  WINED3DPTEXTURECAPS_VOLUMEMAP      |
2279                                 WINED3DPTEXTURECAPS_MIPVOLUMEMAP   |
2280                                 WINED3DPTEXTURECAPS_VOLUMEMAP_POW2;
2281     }
2282
2283     if (GL_SUPPORT(ARB_TEXTURE_CUBE_MAP)) {
2284         *pCaps->TextureCaps |= WINED3DPTEXTURECAPS_CUBEMAP     |
2285                              WINED3DPTEXTURECAPS_MIPCUBEMAP    |
2286                              WINED3DPTEXTURECAPS_CUBEMAP_POW2;
2287
2288     }
2289
2290     *pCaps->TextureFilterCaps = WINED3DPTFILTERCAPS_MAGFLINEAR       |
2291                                 WINED3DPTFILTERCAPS_MAGFPOINT        |
2292                                 WINED3DPTFILTERCAPS_MINFLINEAR       |
2293                                 WINED3DPTFILTERCAPS_MINFPOINT        |
2294                                 WINED3DPTFILTERCAPS_MIPFLINEAR       |
2295                                 WINED3DPTFILTERCAPS_MIPFPOINT        |
2296                                 WINED3DPTFILTERCAPS_LINEAR           |
2297                                 WINED3DPTFILTERCAPS_LINEARMIPLINEAR  |
2298                                 WINED3DPTFILTERCAPS_LINEARMIPNEAREST |
2299                                 WINED3DPTFILTERCAPS_MIPLINEAR        |
2300                                 WINED3DPTFILTERCAPS_MIPNEAREST       |
2301                                 WINED3DPTFILTERCAPS_NEAREST;
2302
2303     if (GL_SUPPORT(EXT_TEXTURE_FILTER_ANISOTROPIC)) {
2304         *pCaps->TextureFilterCaps |= WINED3DPTFILTERCAPS_MAGFANISOTROPIC |
2305                                      WINED3DPTFILTERCAPS_MINFANISOTROPIC;
2306     }
2307
2308     if (GL_SUPPORT(ARB_TEXTURE_CUBE_MAP)) {
2309         *pCaps->CubeTextureFilterCaps = WINED3DPTFILTERCAPS_MAGFLINEAR       |
2310                                         WINED3DPTFILTERCAPS_MAGFPOINT        |
2311                                         WINED3DPTFILTERCAPS_MINFLINEAR       |
2312                                         WINED3DPTFILTERCAPS_MINFPOINT        |
2313                                         WINED3DPTFILTERCAPS_MIPFLINEAR       |
2314                                         WINED3DPTFILTERCAPS_MIPFPOINT        |
2315                                         WINED3DPTFILTERCAPS_LINEAR           |
2316                                         WINED3DPTFILTERCAPS_LINEARMIPLINEAR  |
2317                                         WINED3DPTFILTERCAPS_LINEARMIPNEAREST |
2318                                         WINED3DPTFILTERCAPS_MIPLINEAR        |
2319                                         WINED3DPTFILTERCAPS_MIPNEAREST       |
2320                                         WINED3DPTFILTERCAPS_NEAREST;
2321
2322         if (GL_SUPPORT(EXT_TEXTURE_FILTER_ANISOTROPIC)) {
2323             *pCaps->CubeTextureFilterCaps |= WINED3DPTFILTERCAPS_MAGFANISOTROPIC |
2324                                             WINED3DPTFILTERCAPS_MINFANISOTROPIC;
2325         }
2326     } else
2327         *pCaps->CubeTextureFilterCaps = 0;
2328
2329     if (GL_SUPPORT(EXT_TEXTURE3D)) {
2330         *pCaps->VolumeTextureFilterCaps = WINED3DPTFILTERCAPS_MAGFLINEAR       |
2331                                           WINED3DPTFILTERCAPS_MAGFPOINT        |
2332                                           WINED3DPTFILTERCAPS_MINFLINEAR       |
2333                                           WINED3DPTFILTERCAPS_MINFPOINT        |
2334                                           WINED3DPTFILTERCAPS_MIPFLINEAR       |
2335                                           WINED3DPTFILTERCAPS_MIPFPOINT        |
2336                                           WINED3DPTFILTERCAPS_LINEAR           |
2337                                           WINED3DPTFILTERCAPS_LINEARMIPLINEAR  |
2338                                           WINED3DPTFILTERCAPS_LINEARMIPNEAREST |
2339                                           WINED3DPTFILTERCAPS_MIPLINEAR        |
2340                                           WINED3DPTFILTERCAPS_MIPNEAREST       |
2341                                           WINED3DPTFILTERCAPS_NEAREST;
2342     } else
2343         *pCaps->VolumeTextureFilterCaps = 0;
2344
2345     *pCaps->TextureAddressCaps =  WINED3DPTADDRESSCAPS_INDEPENDENTUV |
2346                                   WINED3DPTADDRESSCAPS_CLAMP  |
2347                                   WINED3DPTADDRESSCAPS_WRAP;
2348
2349     if (GL_SUPPORT(ARB_TEXTURE_BORDER_CLAMP)) {
2350         *pCaps->TextureAddressCaps |= WINED3DPTADDRESSCAPS_BORDER;
2351     }
2352     if (GL_SUPPORT(ARB_TEXTURE_MIRRORED_REPEAT)) {
2353         *pCaps->TextureAddressCaps |= WINED3DPTADDRESSCAPS_MIRROR;
2354     }
2355     if (GL_SUPPORT(ATI_TEXTURE_MIRROR_ONCE)) {
2356         *pCaps->TextureAddressCaps |= WINED3DPTADDRESSCAPS_MIRRORONCE;
2357     }
2358
2359     if (GL_SUPPORT(EXT_TEXTURE3D)) {
2360         *pCaps->VolumeTextureAddressCaps =  WINED3DPTADDRESSCAPS_INDEPENDENTUV |
2361                                             WINED3DPTADDRESSCAPS_CLAMP  |
2362                                             WINED3DPTADDRESSCAPS_WRAP;
2363         if (GL_SUPPORT(ARB_TEXTURE_BORDER_CLAMP)) {
2364             *pCaps->VolumeTextureAddressCaps |= WINED3DPTADDRESSCAPS_BORDER;
2365         }
2366         if (GL_SUPPORT(ARB_TEXTURE_MIRRORED_REPEAT)) {
2367             *pCaps->VolumeTextureAddressCaps |= WINED3DPTADDRESSCAPS_MIRROR;
2368         }
2369         if (GL_SUPPORT(ATI_TEXTURE_MIRROR_ONCE)) {
2370             *pCaps->VolumeTextureAddressCaps |= WINED3DPTADDRESSCAPS_MIRRORONCE;
2371         }
2372     } else
2373         *pCaps->VolumeTextureAddressCaps = 0;
2374
2375     *pCaps->LineCaps = WINED3DLINECAPS_TEXTURE |
2376                        WINED3DLINECAPS_ZTEST;
2377                       /* FIXME: Add
2378                         WINED3DLINECAPS_BLEND
2379                         WINED3DLINECAPS_ALPHACMP
2380                         WINED3DLINECAPS_FOG */
2381
2382     *pCaps->MaxTextureWidth  = GL_LIMITS(texture_size);
2383     *pCaps->MaxTextureHeight = GL_LIMITS(texture_size);
2384
2385     if(GL_SUPPORT(EXT_TEXTURE3D))
2386         *pCaps->MaxVolumeExtent = GL_LIMITS(texture3d_size);
2387     else
2388         *pCaps->MaxVolumeExtent = 0;
2389
2390     *pCaps->MaxTextureRepeat = 32768;
2391     *pCaps->MaxTextureAspectRatio = GL_LIMITS(texture_size);
2392     *pCaps->MaxVertexW = 1.0;
2393
2394     *pCaps->GuardBandLeft = 0;
2395     *pCaps->GuardBandTop = 0;
2396     *pCaps->GuardBandRight = 0;
2397     *pCaps->GuardBandBottom = 0;
2398
2399     *pCaps->ExtentsAdjust = 0;
2400
2401     *pCaps->StencilCaps =  WINED3DSTENCILCAPS_DECRSAT |
2402                            WINED3DSTENCILCAPS_INCRSAT |
2403                            WINED3DSTENCILCAPS_INVERT  |
2404                            WINED3DSTENCILCAPS_KEEP    |
2405                            WINED3DSTENCILCAPS_REPLACE |
2406                            WINED3DSTENCILCAPS_ZERO;
2407     if (GL_SUPPORT(EXT_STENCIL_WRAP)) {
2408       *pCaps->StencilCaps |= WINED3DSTENCILCAPS_DECR  |
2409                              WINED3DSTENCILCAPS_INCR;
2410     }
2411     if ( This->dxVersion > 8 &&
2412         ( GL_SUPPORT(EXT_STENCIL_TWO_SIDE) ||
2413             GL_SUPPORT(ATI_SEPARATE_STENCIL) ) ) {
2414         *pCaps->StencilCaps |= WINED3DSTENCILCAPS_TWOSIDED;
2415     }
2416
2417     *pCaps->FVFCaps = WINED3DFVFCAPS_PSIZE | 0x0008; /* 8 texture coords */
2418
2419     *pCaps->TextureOpCaps =  WINED3DTEXOPCAPS_ADD         |
2420                              WINED3DTEXOPCAPS_ADDSIGNED   |
2421                              WINED3DTEXOPCAPS_ADDSIGNED2X |
2422                              WINED3DTEXOPCAPS_MODULATE    |
2423                              WINED3DTEXOPCAPS_MODULATE2X  |
2424                              WINED3DTEXOPCAPS_MODULATE4X  |
2425                              WINED3DTEXOPCAPS_SELECTARG1  |
2426                              WINED3DTEXOPCAPS_SELECTARG2  |
2427                              WINED3DTEXOPCAPS_DISABLE;
2428
2429     if (GL_SUPPORT(ARB_TEXTURE_ENV_COMBINE) ||
2430         GL_SUPPORT(EXT_TEXTURE_ENV_COMBINE) ||
2431         GL_SUPPORT(NV_TEXTURE_ENV_COMBINE4)) {
2432         *pCaps->TextureOpCaps |= WINED3DTEXOPCAPS_BLENDDIFFUSEALPHA |
2433                                 WINED3DTEXOPCAPS_BLENDTEXTUREALPHA  |
2434                                 WINED3DTEXOPCAPS_BLENDFACTORALPHA   |
2435                                 WINED3DTEXOPCAPS_BLENDCURRENTALPHA  |
2436                                 WINED3DTEXOPCAPS_LERP               |
2437                                 WINED3DTEXOPCAPS_SUBTRACT;
2438     }
2439     if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3) ||
2440          GL_SUPPORT(NV_TEXTURE_ENV_COMBINE4)) {
2441         *pCaps->TextureOpCaps |= WINED3DTEXOPCAPS_ADDSMOOTH             |
2442                                 WINED3DTEXOPCAPS_MULTIPLYADD            |
2443                                 WINED3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR |
2444                                 WINED3DTEXOPCAPS_MODULATECOLOR_ADDALPHA |
2445                                 WINED3DTEXOPCAPS_BLENDTEXTUREALPHAPM;
2446     }
2447     if (GL_SUPPORT(ARB_TEXTURE_ENV_DOT3))
2448         *pCaps->TextureOpCaps |= WINED3DTEXOPCAPS_DOTPRODUCT3;
2449
2450     if (GL_SUPPORT(NV_REGISTER_COMBINERS)) {
2451         *pCaps->TextureOpCaps |= WINED3DTEXOPCAPS_MODULATEINVALPHA_ADDCOLOR |
2452                                  WINED3DTEXOPCAPS_MODULATEINVCOLOR_ADDALPHA;
2453     }
2454
2455     if(GL_SUPPORT(ATI_ENVMAP_BUMPMAP)) {
2456         *pCaps->TextureOpCaps |= WINED3DTEXOPCAPS_BUMPENVMAP;
2457     } else if(GL_SUPPORT(NV_TEXTURE_SHADER2)) {
2458         /* Bump mapping is supported already in NV_TEXTURE_SHADER, but that extension does
2459          * not support 3D textures. This asks for trouble if an app uses both bump mapping
2460          * and 3D textures. It also allows us to keep the code simpler by having texture
2461          * shaders constantly enabled.
2462          */
2463         *pCaps->TextureOpCaps |= WINED3DTEXOPCAPS_BUMPENVMAP;
2464         /* TODO: Luminance bump map? */
2465     }
2466 #if 0
2467     /* FIXME: Add
2468     *pCaps->TextureOpCaps |= WINED3DTEXOPCAPS_BUMPENVMAPLUMINANCE
2469                              WINED3DTEXOPCAPS_PREMODULATE */
2470 #endif
2471
2472     *pCaps->MaxTextureBlendStages   = GL_LIMITS(texture_stages);
2473     *pCaps->MaxSimultaneousTextures = GL_LIMITS(textures);
2474     *pCaps->MaxUserClipPlanes       = GL_LIMITS(clipplanes);
2475     *pCaps->MaxActiveLights         = GL_LIMITS(lights);
2476
2477     *pCaps->MaxVertexBlendMatrices      = GL_LIMITS(blends);
2478     *pCaps->MaxVertexBlendMatrixIndex   = 0;
2479
2480     *pCaps->MaxAnisotropy   = GL_LIMITS(anisotropy);
2481     *pCaps->MaxPointSize    = GL_LIMITS(pointsize);
2482
2483
2484     *pCaps->VertexProcessingCaps = WINED3DVTXPCAPS_DIRECTIONALLIGHTS |
2485                                    WINED3DVTXPCAPS_MATERIALSOURCE7   |
2486                                    WINED3DVTXPCAPS_POSITIONALLIGHTS  |
2487                                    WINED3DVTXPCAPS_LOCALVIEWER       |
2488                                    WINED3DVTXPCAPS_VERTEXFOG         |
2489                                    WINED3DVTXPCAPS_TEXGEN;
2490                                   /* FIXME: Add 
2491                                      D3DVTXPCAPS_TWEENING, D3DVTXPCAPS_TEXGEN_SPHEREMAP */
2492
2493     *pCaps->MaxPrimitiveCount   = 0xFFFFF; /* For now set 2^20-1 which is used by most >=Geforce3/Radeon8500 cards */
2494     *pCaps->MaxVertexIndex      = 0xFFFFF;
2495     *pCaps->MaxStreams          = MAX_STREAMS;
2496     *pCaps->MaxStreamStride     = 1024;
2497
2498     if (vs_selected_mode == SHADER_GLSL) {
2499         /* Nvidia Geforce6/7 or Ati R4xx/R5xx cards with GLSL support, support VS 3.0 but older Nvidia/Ati
2500          * models with GLSL support only support 2.0. In case of nvidia we can detect VS 2.0 support using
2501          * vs_nv_version which is based on NV_vertex_program.
2502          * For Ati cards there's no way using glsl (it abstracts the lowlevel info away) and also not
2503          * using ARB_vertex_program. It is safe to assume that when a card supports pixel shader 2.0 it
2504          * supports vertex shader 2.0 too and the way around. We can detect ps2.0 using the maximum number
2505          * of native instructions, so use that here. For more info see the pixel shader versioning code below. */
2506         if((GLINFO_LOCATION.vs_nv_version == VS_VERSION_20) || (GLINFO_LOCATION.ps_arb_max_instructions <= 512))
2507             *pCaps->VertexShaderVersion = WINED3DVS_VERSION(2,0);
2508         else
2509             *pCaps->VertexShaderVersion = WINED3DVS_VERSION(3,0);
2510         TRACE_(d3d_caps)("Hardware vertex shader version %d.%d enabled (GLSL)\n", (*pCaps->VertexShaderVersion >> 8) & 0xff, *pCaps->VertexShaderVersion & 0xff);
2511     } else if (vs_selected_mode == SHADER_ARB) {
2512         *pCaps->VertexShaderVersion = WINED3DVS_VERSION(1,1);
2513         TRACE_(d3d_caps)("Hardware vertex shader version 1.1 enabled (ARB_PROGRAM)\n");
2514     } else {
2515         *pCaps->VertexShaderVersion  = 0;
2516         TRACE_(d3d_caps)("Vertex shader functionality not available\n");
2517     }
2518
2519     *pCaps->MaxVertexShaderConst = GL_LIMITS(vshader_constantsF);
2520
2521     if (ps_selected_mode == SHADER_GLSL) {
2522         /* Older DX9-class videocards (GeforceFX / Radeon >9500/X*00) only support pixel shader 2.0/2.0a/2.0b.
2523          * In OpenGL the extensions related to GLSL abstract lowlevel GL info away which is needed
2524          * to distinguish between 2.0 and 3.0 (and 2.0a/2.0b). In case of Nvidia we use their fragment
2525          * program extensions. On other hardware including ATI GL_ARB_fragment_program offers the info
2526          * in max native instructions. Intel and others also offer the info in this extension but they
2527          * don't support GLSL (at least on Windows).
2528          *
2529          * PS2.0 requires at least 96 instructions, 2.0a/2.0b go up to 512. Assume that if the number
2530          * of instructions is 512 or less we have to do with ps2.0 hardware.
2531          * 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.
2532          */
2533         if((GLINFO_LOCATION.ps_nv_version == PS_VERSION_20) || (GLINFO_LOCATION.ps_arb_max_instructions <= 512))
2534             *pCaps->PixelShaderVersion = WINED3DPS_VERSION(2,0);
2535         else
2536             *pCaps->PixelShaderVersion = WINED3DPS_VERSION(3,0);
2537         /* FIXME: The following line is card dependent. -8.0 to 8.0 is the
2538          * Direct3D minimum requirement.
2539          *
2540          * Both GL_ARB_fragment_program and GLSL require a "maximum representable magnitude"
2541          * of colors to be 2^10, and 2^32 for other floats. Should we use 1024 here?
2542          *
2543          * The problem is that the refrast clamps temporary results in the shader to
2544          * [-MaxValue;+MaxValue]. If the card's max value is bigger than the one we advertize here,
2545          * then applications may miss the clamping behavior. On the other hand, if it is smaller,
2546          * the shader will generate incorrect results too. Unfortunately, GL deliberately doesn't
2547          * offer a way to query this.
2548          */
2549         *pCaps->PixelShader1xMaxValue = 8.0;
2550         TRACE_(d3d_caps)("Hardware pixel shader version %d.%d enabled (GLSL)\n", (*pCaps->PixelShaderVersion >> 8) & 0xff, *pCaps->PixelShaderVersion & 0xff);
2551     } else if (ps_selected_mode == SHADER_ARB) {
2552         *pCaps->PixelShaderVersion    = WINED3DPS_VERSION(1,4);
2553         *pCaps->PixelShader1xMaxValue = 8.0;
2554         TRACE_(d3d_caps)("Hardware pixel shader version 1.4 enabled (ARB_PROGRAM)\n");
2555     } else {
2556         *pCaps->PixelShaderVersion    = 0;
2557         *pCaps->PixelShader1xMaxValue = 0.0;
2558         TRACE_(d3d_caps)("Pixel shader functionality not available\n");
2559     }
2560
2561     /* ------------------------------------------------
2562        The following fields apply to d3d9 only
2563        ------------------------------------------------ */
2564     if (This->dxVersion > 8) {
2565         /* d3d9.dll sets D3DDEVCAPS2_CAN_STRETCHRECT_FROM_TEXTURES here because StretchRects is implemented in d3d9 */
2566         *pCaps->DevCaps2                          = WINED3DDEVCAPS2_STREAMOFFSET;
2567         /* TODO: VS3.0 needs at least D3DDEVCAPS2_VERTEXELEMENTSCANSHARESTREAMOFFSET */
2568         *pCaps->MaxNpatchTessellationLevel        = 0;
2569         *pCaps->MasterAdapterOrdinal              = 0;
2570         *pCaps->AdapterOrdinalInGroup             = 0;
2571         *pCaps->NumberOfAdaptersInGroup           = 1;
2572
2573         if(*pCaps->VertexShaderVersion >= WINED3DVS_VERSION(2,0)) {
2574             /* OpenGL supports all the formats below, perhaps not always
2575              * without conversion, but it supports them.
2576              * Further GLSL doesn't seem to have an official unsigned type so
2577              * don't advertise it yet as I'm not sure how we handle it.
2578              * We might need to add some clamping in the shader engine to
2579              * support it.
2580              * TODO: WINED3DDTCAPS_USHORT2N, WINED3DDTCAPS_USHORT4N, WINED3DDTCAPS_UDEC3, WINED3DDTCAPS_DEC3N */
2581             *pCaps->DeclTypes = WINED3DDTCAPS_UBYTE4    |
2582                                 WINED3DDTCAPS_UBYTE4N   |
2583                                 WINED3DDTCAPS_SHORT2N   |
2584                                 WINED3DDTCAPS_SHORT4N;
2585             if (GL_SUPPORT(NV_HALF_FLOAT)) {
2586                 *pCaps->DeclTypes |=
2587                                 WINED3DDTCAPS_FLOAT16_2 |
2588                                 WINED3DDTCAPS_FLOAT16_4;
2589             }
2590         } else
2591             *pCaps->DeclTypes                         = 0;
2592
2593         *pCaps->NumSimultaneousRTs = GL_LIMITS(buffers);
2594
2595             
2596         *pCaps->StretchRectFilterCaps             = WINED3DPTFILTERCAPS_MINFPOINT  |
2597                                                     WINED3DPTFILTERCAPS_MAGFPOINT  |
2598                                                     WINED3DPTFILTERCAPS_MINFLINEAR |
2599                                                     WINED3DPTFILTERCAPS_MAGFLINEAR;
2600         *pCaps->VertexTextureFilterCaps           = 0;
2601         
2602         if(*pCaps->VertexShaderVersion == WINED3DVS_VERSION(3,0)) {
2603             /* Where possible set the caps based on OpenGL extensions and if they aren't set (in case of software rendering)
2604                use the VS 3.0 from MSDN or else if there's OpenGL spec use a hardcoded value minimum VS3.0 value. */
2605             *pCaps->VS20Caps.Caps                     = WINED3DVS20CAPS_PREDICATION;
2606             *pCaps->VS20Caps.DynamicFlowControlDepth  = WINED3DVS20_MAX_DYNAMICFLOWCONTROLDEPTH; /* VS 3.0 requires MAX_DYNAMICFLOWCONTROLDEPTH (24) */
2607             *pCaps->VS20Caps.NumTemps                 = max(32, GLINFO_LOCATION.vs_arb_max_temps);
2608             *pCaps->VS20Caps.StaticFlowControlDepth   = WINED3DVS20_MAX_STATICFLOWCONTROLDEPTH ; /* level of nesting in loops / if-statements; VS 3.0 requires MAX (4) */
2609
2610             *pCaps->MaxVShaderInstructionsExecuted    = 65535; /* VS 3.0 needs at least 65535, some cards even use 2^32-1 */
2611             *pCaps->MaxVertexShader30InstructionSlots = max(512, GLINFO_LOCATION.vs_arb_max_instructions);
2612         } else if(*pCaps->VertexShaderVersion == WINED3DVS_VERSION(2,0)) {
2613             *pCaps->VS20Caps.Caps                     = 0;
2614             *pCaps->VS20Caps.DynamicFlowControlDepth  = WINED3DVS20_MIN_DYNAMICFLOWCONTROLDEPTH;
2615             *pCaps->VS20Caps.NumTemps                 = max(12, GLINFO_LOCATION.vs_arb_max_temps);
2616             *pCaps->VS20Caps.StaticFlowControlDepth   = 1;    
2617
2618             *pCaps->MaxVShaderInstructionsExecuted    = 65535;
2619             *pCaps->MaxVertexShader30InstructionSlots = 0;
2620         } else { /* VS 1.x */
2621             *pCaps->VS20Caps.Caps                     = 0;
2622             *pCaps->VS20Caps.DynamicFlowControlDepth  = 0;
2623             *pCaps->VS20Caps.NumTemps                 = 0;
2624             *pCaps->VS20Caps.StaticFlowControlDepth   = 0;    
2625
2626             *pCaps->MaxVShaderInstructionsExecuted    = 0;
2627             *pCaps->MaxVertexShader30InstructionSlots = 0;        
2628         }
2629
2630         if(*pCaps->PixelShaderVersion == WINED3DPS_VERSION(3,0)) {
2631             /* Where possible set the caps based on OpenGL extensions and if they aren't set (in case of software rendering)
2632                use the PS 3.0 from MSDN or else if there's OpenGL spec use a hardcoded value minimum PS 3.0 value. */
2633             
2634             /* 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 */
2635             *pCaps->PS20Caps.Caps                     = WINED3DPS20CAPS_ARBITRARYSWIZZLE     |
2636                                                         WINED3DPS20CAPS_GRADIENTINSTRUCTIONS |
2637                                                         WINED3DPS20CAPS_PREDICATION          |
2638                                                         WINED3DPS20CAPS_NODEPENDENTREADLIMIT |
2639                                                         WINED3DPS20CAPS_NOTEXINSTRUCTIONLIMIT;
2640             *pCaps->PS20Caps.DynamicFlowControlDepth  = WINED3DPS20_MAX_DYNAMICFLOWCONTROLDEPTH; /* PS 3.0 requires MAX_DYNAMICFLOWCONTROLDEPTH (24) */
2641             *pCaps->PS20Caps.NumTemps                 = max(32, GLINFO_LOCATION.ps_arb_max_temps);
2642             *pCaps->PS20Caps.StaticFlowControlDepth   = WINED3DPS20_MAX_STATICFLOWCONTROLDEPTH; /* PS 3.0 requires MAX_STATICFLOWCONTROLDEPTH (4) */
2643             *pCaps->PS20Caps.NumInstructionSlots      = WINED3DPS20_MAX_NUMINSTRUCTIONSLOTS; /* PS 3.0 requires MAX_NUMINSTRUCTIONSLOTS (512) */
2644
2645             *pCaps->MaxPShaderInstructionsExecuted    = 65535;
2646             *pCaps->MaxPixelShader30InstructionSlots  = max(WINED3DMIN30SHADERINSTRUCTIONS, GLINFO_LOCATION.ps_arb_max_instructions);
2647         } else if(*pCaps->PixelShaderVersion == WINED3DPS_VERSION(2,0)) {
2648             /* Below we assume PS2.0 specs, not extended 2.0a(GeforceFX)/2.0b(Radeon R3xx) ones */
2649             *pCaps->PS20Caps.Caps                     = 0;
2650             *pCaps->PS20Caps.DynamicFlowControlDepth  = 0; /* WINED3DVS20_MIN_DYNAMICFLOWCONTROLDEPTH = 0 */
2651             *pCaps->PS20Caps.NumTemps                 = max(12, GLINFO_LOCATION.ps_arb_max_temps);
2652             *pCaps->PS20Caps.StaticFlowControlDepth   = WINED3DPS20_MIN_STATICFLOWCONTROLDEPTH; /* Minumum: 1 */
2653             *pCaps->PS20Caps.NumInstructionSlots      = WINED3DPS20_MIN_NUMINSTRUCTIONSLOTS; /* Minimum number (64 ALU + 32 Texture), a GeforceFX uses 512 */
2654
2655             *pCaps->MaxPShaderInstructionsExecuted    = 512; /* Minimum value, a GeforceFX uses 1024 */
2656             *pCaps->MaxPixelShader30InstructionSlots  = 0;
2657         } else { /* PS 1.x */
2658             *pCaps->PS20Caps.Caps                     = 0;
2659             *pCaps->PS20Caps.DynamicFlowControlDepth  = 0;
2660             *pCaps->PS20Caps.NumTemps                 = 0;
2661             *pCaps->PS20Caps.StaticFlowControlDepth   = 0;
2662             *pCaps->PS20Caps.NumInstructionSlots      = 0;
2663
2664             *pCaps->MaxPShaderInstructionsExecuted    = 0;
2665             *pCaps->MaxPixelShader30InstructionSlots  = 0;
2666         }
2667     }
2668
2669     return WINED3D_OK;
2670 }
2671
2672 static unsigned int glsl_program_key_hash(void *key) {
2673     glsl_program_key_t *k = (glsl_program_key_t *)key;
2674
2675     unsigned int hash = k->vshader | k->pshader << 16;
2676     hash += ~(hash << 15);
2677     hash ^=  (hash >> 10);
2678     hash +=  (hash << 3);
2679     hash ^=  (hash >> 6);
2680     hash += ~(hash << 11);
2681     hash ^=  (hash >> 16);
2682
2683     return hash;
2684 }
2685
2686 static BOOL glsl_program_key_compare(void *keya, void *keyb) {
2687     glsl_program_key_t *ka = (glsl_program_key_t *)keya;
2688     glsl_program_key_t *kb = (glsl_program_key_t *)keyb;
2689
2690     return ka->vshader == kb->vshader && ka->pshader == kb->pshader;
2691 }
2692
2693 /* Note due to structure differences between dx8 and dx9 D3DPRESENT_PARAMETERS,
2694    and fields being inserted in the middle, a new structure is used in place    */
2695 static HRESULT  WINAPI IWineD3DImpl_CreateDevice(IWineD3D *iface, UINT Adapter, WINED3DDEVTYPE DeviceType, HWND hFocusWindow,
2696                                            DWORD BehaviourFlags, IWineD3DDevice** ppReturnedDeviceInterface,
2697                                            IUnknown *parent) {
2698
2699     IWineD3DDeviceImpl *object  = NULL;
2700     IWineD3DImpl       *This    = (IWineD3DImpl *)iface;
2701     WINED3DDISPLAYMODE  mode;
2702     int i;
2703
2704     /* Validate the adapter number. If no adapters are available(no GL), ignore the adapter
2705      * number and create a device without a 3D adapter for 2D only operation.
2706      */
2707     if (IWineD3D_GetAdapterCount(iface) && Adapter >= IWineD3D_GetAdapterCount(iface)) {
2708         return WINED3DERR_INVALIDCALL;
2709     }
2710
2711     /* Create a WineD3DDevice object */
2712     object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IWineD3DDeviceImpl));
2713     *ppReturnedDeviceInterface = (IWineD3DDevice *)object;
2714     TRACE("Created WineD3DDevice object @ %p\n", object);
2715     if (NULL == object) {
2716       return WINED3DERR_OUTOFVIDEOMEMORY;
2717     }
2718
2719     /* Set up initial COM information */
2720     object->lpVtbl  = &IWineD3DDevice_Vtbl;
2721     object->ref     = 1;
2722     object->wineD3D = iface;
2723     object->adapter = numAdapters ? &Adapters[Adapter] : NULL;
2724     IWineD3D_AddRef(object->wineD3D);
2725     object->parent  = parent;
2726     list_init(&object->resources);
2727
2728     if(This->dxVersion == 7) {
2729         object->surface_alignment = 8;
2730     } else {
2731         object->surface_alignment = 4;
2732     }
2733     object->posFixup[0] = 1.0; /* This is needed to get the x coord unmodified through a MAD */
2734
2735     /* Set the state up as invalid until the device is fully created */
2736     object->state   = WINED3DERR_DRIVERINTERNALERROR;
2737
2738     TRACE("(%p)->(Adptr:%d, DevType: %x, FocusHwnd: %p, BehFlags: %x, RetDevInt: %p)\n", This, Adapter, DeviceType,
2739           hFocusWindow, BehaviourFlags, ppReturnedDeviceInterface);
2740
2741     /* Save the creation parameters */
2742     object->createParms.AdapterOrdinal = Adapter;
2743     object->createParms.DeviceType     = DeviceType;
2744     object->createParms.hFocusWindow   = hFocusWindow;
2745     object->createParms.BehaviorFlags  = BehaviourFlags;
2746
2747     /* Initialize other useful values */
2748     object->adapterNo                    = Adapter;
2749     object->devType                      = DeviceType;
2750
2751     select_shader_mode(&GLINFO_LOCATION, DeviceType, &object->ps_selected_mode, &object->vs_selected_mode);
2752     if (object->ps_selected_mode == SHADER_GLSL || object->vs_selected_mode == SHADER_GLSL) {
2753         object->shader_backend = &glsl_shader_backend;
2754         object->glsl_program_lookup = hash_table_create(&glsl_program_key_hash, &glsl_program_key_compare);
2755     } else if (object->ps_selected_mode == SHADER_ARB || object->vs_selected_mode == SHADER_ARB) {
2756         object->shader_backend = &arb_program_shader_backend;
2757     } else {
2758         object->shader_backend = &none_shader_backend;
2759     }
2760
2761     /* set the state of the device to valid */
2762     object->state = WINED3D_OK;
2763
2764     /* Get the initial screen setup for ddraw */
2765     IWineD3DImpl_GetAdapterDisplayMode(iface, Adapter, &mode);
2766
2767     object->ddraw_width = mode.Width;
2768     object->ddraw_height = mode.Height;
2769     object->ddraw_format = mode.Format;
2770
2771     for(i = 0; i < PATCHMAP_SIZE; i++) {
2772         list_init(&object->patches[i]);
2773     }
2774     return WINED3D_OK;
2775 }
2776 #undef GLINFO_LOCATION
2777
2778 static HRESULT WINAPI IWineD3DImpl_GetParent(IWineD3D *iface, IUnknown **pParent) {
2779     IWineD3DImpl *This = (IWineD3DImpl *)iface;
2780     IUnknown_AddRef(This->parent);
2781     *pParent = This->parent;
2782     return WINED3D_OK;
2783 }
2784
2785 ULONG WINAPI D3DCB_DefaultDestroySurface(IWineD3DSurface *pSurface) {
2786     IUnknown* surfaceParent;
2787     TRACE("(%p) call back\n", pSurface);
2788
2789     /* Now, release the parent, which will take care of cleaning up the surface for us */
2790     IWineD3DSurface_GetParent(pSurface, &surfaceParent);
2791     IUnknown_Release(surfaceParent);
2792     return IUnknown_Release(surfaceParent);
2793 }
2794
2795 ULONG WINAPI D3DCB_DefaultDestroyVolume(IWineD3DVolume *pVolume) {
2796     IUnknown* volumeParent;
2797     TRACE("(%p) call back\n", pVolume);
2798
2799     /* Now, release the parent, which will take care of cleaning up the volume for us */
2800     IWineD3DVolume_GetParent(pVolume, &volumeParent);
2801     IUnknown_Release(volumeParent);
2802     return IUnknown_Release(volumeParent);
2803 }
2804
2805 static BOOL implementation_is_apple(WineD3D_GL_Info *gl_info) {
2806     /* MacOS has various specialities in the extensions it advertises. Some have to be loaded from
2807      * the opengl 1.2+ core, while other extensions are advertised, but software emulated. So try to
2808      * detect the Apple OpenGL implementation to apply some extension fixups afterwards.
2809      *
2810      * Detecting this isn't really easy. The vendor string doesn't mention Apple. Compile-time checks
2811      * aren't sufficient either because a Linux binary may display on a macos X server via remote X11.
2812      * So try to detect the GL implementation by looking at certain Apple extensions. Some extensions
2813      * like client storage might be supported on other implementations too, but GL_APPLE_flush_render
2814      * is specific to the Mac OS X window management, and GL_APPLE_ycbcr_422 is QuickTime specific. So
2815      * the chance that other implementations support them is rather small since Win32 QuickTime uses
2816      * DirectDraw, not OpenGL.
2817      */
2818     if(gl_info->supported[APPLE_FENCE] &&
2819        gl_info->supported[APPLE_CLIENT_STORAGE] &&
2820        gl_info->supported[APPLE_FLUSH_RENDER] &&
2821        gl_info->supported[APPLE_YCBCR_422]) {
2822         TRACE_(d3d_caps)("GL_APPLE_fence, GL_APPLE_client_storage, GL_APPLE_flush_render and GL_ycbcr_422 are supported\n");
2823         TRACE_(d3d_caps)("Activating MacOS fixups\n");
2824         return TRUE;
2825     } else {
2826         TRACE_(d3d_caps)("Apple extensions are not supported\n");
2827         TRACE_(d3d_caps)("Not activating MacOS fixups\n");
2828         return FALSE;
2829     }
2830 }
2831
2832 static void fixup_extensions(WineD3D_GL_Info *gl_info) {
2833     if(implementation_is_apple(gl_info)) {
2834         /* MacOS advertises more GLSL vertex shader uniforms than supported by the hardware, and if more are
2835          * used it falls back to software. While the compiler can detect if the shader uses all declared
2836          * uniforms, the optimization fails if the shader uses relative addressing. So any GLSL shader
2837          * using relative addressing falls back to software.
2838          *
2839          * ARB vp gives the correct amount of uniforms, so use it instead of GLSL
2840          */
2841         if(gl_info->vs_glsl_constantsF <= gl_info->vs_arb_constantsF) {
2842             FIXME("GLSL doesn't advertise more vertex shader uniforms than ARB. Driver fixup outdated?\n");
2843         } else {
2844             TRACE("Driver claims %u GLSL vs uniforms, replacing with %u ARB vp uniforms\n",
2845                   gl_info->vs_glsl_constantsF, gl_info->vs_arb_constantsF);
2846             gl_info->vs_glsl_constantsF = gl_info->vs_arb_constantsF;
2847         }
2848
2849         /* MacOS advertises GL_ARB_texture_non_power_of_two on ATI r500 and earlier cards, although
2850          * these cards only support GL_ARB_texture_rectangle(D3DPTEXTURECAPS_NONPOW2CONDITIONAL).
2851          * If real NP2 textures are used, the driver falls back to software. So remove the supported
2852          * flag for this extension
2853          */
2854         if(gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO] && gl_info->gl_vendor == VENDOR_ATI) {
2855             if(gl_info->gl_card == CARD_ATI_RADEON_X700 || gl_info->gl_card == CARD_ATI_RADEON_X1600 ||
2856                gl_info->gl_card == CARD_ATI_RADEON_9500 || gl_info->gl_card == CARD_ATI_RADEON_8500  ||
2857                gl_info->gl_card == CARD_ATI_RADEON_7200 || gl_info->gl_card == CARD_ATI_RAGE_128PRO) {
2858                 TRACE("GL_ARB_texture_non_power_of_two advertised on R500 or earlier card, removing\n");
2859                 gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO] = FALSE;
2860                 gl_info->supported[ARB_TEXTURE_RECTANGLE] = TRUE;
2861             }
2862         }
2863
2864         /* The Intel GPUs on MacOS set the .w register of texcoords to 0.0 by default, which causes problems
2865          * with fixed function fragment processing. Ideally this flag should be detected with a test shader
2866          * and opengl feedback mode, but some GL implementations(MacOS ATI at least, propably all macos ones)
2867          * do not like vertex shaders in feedback mode and return an error, even though it should be valid
2868          * according to the spec.
2869          *
2870          * We don't want to enable this on all cards, as it adds an extra instruction per texcoord used. This
2871          * makes the shader slower and eats instruction slots which should be available to the d3d app.
2872          */
2873         if(gl_info->gl_vendor == VENDOR_INTEL) {
2874             TRACE("Enabling vertex texture coord fixes in vertex shaders\n");
2875             gl_info->set_texcoord_w = TRUE;
2876         }
2877     }
2878 }
2879
2880 #define PUSH1(att)        attribs[nAttribs++] = (att);
2881 #define GLINFO_LOCATION (Adapters[0].gl_info)
2882 BOOL InitAdapters(void) {
2883     static HMODULE mod_gl;
2884     BOOL ret;
2885     int ps_selected_mode, vs_selected_mode;
2886
2887     /* No need to hold any lock. The calling library makes sure only one thread calls
2888      * wined3d simultaneously
2889      */
2890     if(numAdapters > 0) return TRUE;
2891
2892     TRACE("Initializing adapters\n");
2893
2894     if(!mod_gl) {
2895 #ifdef USE_WIN32_OPENGL
2896 #define USE_GL_FUNC(pfn) pfn = (void*)GetProcAddress(mod_gl, #pfn);
2897         mod_gl = LoadLibraryA("opengl32.dll");
2898         if(!mod_gl) {
2899             ERR("Can't load opengl32.dll!\n");
2900             return FALSE;
2901         }
2902 #else
2903 #define USE_GL_FUNC(pfn) pfn = (void*)pwglGetProcAddress(#pfn);
2904         /* To bypass the opengl32 thunks load wglGetProcAddress from gdi32 (glXGetProcAddress wrapper) instead of opengl32's */
2905         mod_gl = GetModuleHandleA("gdi32.dll");
2906 #endif
2907     }
2908
2909 /* Load WGL core functions from opengl32.dll */
2910 #define USE_WGL_FUNC(pfn) p##pfn = (void*)GetProcAddress(mod_gl, #pfn);
2911     WGL_FUNCS_GEN;
2912 #undef USE_WGL_FUNC
2913
2914     if(!pwglGetProcAddress) {
2915         ERR("Unable to load wglGetProcAddress!\n");
2916         return FALSE;
2917     }
2918
2919 /* Dynamically load all GL core functions */
2920     GL_FUNCS_GEN;
2921 #undef USE_GL_FUNC
2922
2923     /* For now only one default adapter */
2924     {
2925         int iPixelFormat;
2926         int attribs[8];
2927         int values[8];
2928         int nAttribs = 0;
2929         int res;
2930         WineD3D_PixelFormat *cfgs;
2931         int attribute;
2932         DISPLAY_DEVICEW DisplayDevice;
2933         HDC hdc;
2934
2935         TRACE("Initializing default adapter\n");
2936         Adapters[0].num = 0;
2937         Adapters[0].monitorPoint.x = -1;
2938         Adapters[0].monitorPoint.y = -1;
2939
2940         if (!WineD3D_CreateFakeGLContext()) {
2941             ERR("Failed to get a gl context for default adapter\n");
2942             HeapFree(GetProcessHeap(), 0, Adapters);
2943             WineD3D_ReleaseFakeGLContext();
2944             return FALSE;
2945         }
2946
2947         ret = IWineD3DImpl_FillGLCaps(&Adapters[0].gl_info);
2948         if(!ret) {
2949             ERR("Failed to initialize gl caps for default adapter\n");
2950             HeapFree(GetProcessHeap(), 0, Adapters);
2951             WineD3D_ReleaseFakeGLContext();
2952             return FALSE;
2953         }
2954         ret = initPixelFormats(&Adapters[0].gl_info);
2955         if(!ret) {
2956             ERR("Failed to init gl formats\n");
2957             HeapFree(GetProcessHeap(), 0, Adapters);
2958             WineD3D_ReleaseFakeGLContext();
2959             return FALSE;
2960         }
2961
2962         hdc = pwglGetCurrentDC();
2963         if(!hdc) {
2964             ERR("Failed to get gl HDC\n");
2965             HeapFree(GetProcessHeap(), 0, Adapters);
2966             WineD3D_ReleaseFakeGLContext();
2967             return FALSE;
2968         }
2969
2970         Adapters[0].driver = "Display";
2971         Adapters[0].description = "Direct3D HAL";
2972
2973         /* Use the VideoRamSize registry setting when set */
2974         if(wined3d_settings.emulated_textureram)
2975             Adapters[0].TextureRam = wined3d_settings.emulated_textureram;
2976         else
2977             Adapters[0].TextureRam = Adapters[0].gl_info.vidmem;
2978         Adapters[0].UsedTextureRam = 0;
2979         TRACE("Emulating %dMB of texture ram\n", Adapters[0].TextureRam/(1024*1024));
2980
2981         /* Initialize the Adapter's DeviceName which is required for ChangeDisplaySettings and friends */
2982         DisplayDevice.cb = sizeof(DisplayDevice);
2983         EnumDisplayDevicesW(NULL, 0 /* Adapter 0 = iDevNum 0 */, &DisplayDevice, 0);
2984         TRACE("DeviceName: %s\n", debugstr_w(DisplayDevice.DeviceName));
2985         strcpyW(Adapters[0].DeviceName, DisplayDevice.DeviceName);
2986
2987         attribute = WGL_NUMBER_PIXEL_FORMATS_ARB;
2988         GL_EXTCALL(wglGetPixelFormatAttribivARB(hdc, 0, 0, 1, &attribute, &Adapters[0].nCfgs));
2989
2990         Adapters[0].cfgs = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, Adapters[0].nCfgs *sizeof(WineD3D_PixelFormat));
2991         cfgs = Adapters[0].cfgs;
2992         PUSH1(WGL_RED_BITS_ARB)
2993         PUSH1(WGL_GREEN_BITS_ARB)
2994         PUSH1(WGL_BLUE_BITS_ARB)
2995         PUSH1(WGL_ALPHA_BITS_ARB)
2996         PUSH1(WGL_DEPTH_BITS_ARB)
2997         PUSH1(WGL_STENCIL_BITS_ARB)
2998
2999         for(iPixelFormat=1; iPixelFormat<=Adapters[0].nCfgs; iPixelFormat++) {
3000             res = GL_EXTCALL(wglGetPixelFormatAttribivARB(hdc, iPixelFormat, 0, nAttribs, attribs, values));
3001
3002             if(!res)
3003                 continue;
3004
3005             /* Cache the pixel format */
3006             cfgs->iPixelFormat = iPixelFormat;
3007             cfgs->redSize = values[0];
3008             cfgs->greenSize = values[1];
3009             cfgs->blueSize = values[2];
3010             cfgs->alphaSize = values[3];
3011             cfgs->depthSize = values[4];
3012             cfgs->stencilSize = values[5];
3013
3014             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);
3015             cfgs++;
3016         }
3017         WineD3D_ReleaseFakeGLContext();
3018
3019         fixup_extensions(&Adapters[0].gl_info);
3020
3021         select_shader_mode(&Adapters[0].gl_info, WINED3DDEVTYPE_HAL, &ps_selected_mode, &vs_selected_mode);
3022         select_shader_max_constants(ps_selected_mode, vs_selected_mode, &Adapters[0].gl_info);
3023
3024     }
3025     numAdapters = 1;
3026     TRACE("%d adapters successfully initialized\n", numAdapters);
3027
3028     return TRUE;
3029 }
3030 #undef PUSH1
3031 #undef GLINFO_LOCATION
3032
3033 /**********************************************************
3034  * IWineD3D VTbl follows
3035  **********************************************************/
3036
3037 const IWineD3DVtbl IWineD3D_Vtbl =
3038 {
3039     /* IUnknown */
3040     IWineD3DImpl_QueryInterface,
3041     IWineD3DImpl_AddRef,
3042     IWineD3DImpl_Release,
3043     /* IWineD3D */
3044     IWineD3DImpl_GetParent,
3045     IWineD3DImpl_GetAdapterCount,
3046     IWineD3DImpl_RegisterSoftwareDevice,
3047     IWineD3DImpl_GetAdapterMonitor,
3048     IWineD3DImpl_GetAdapterModeCount,
3049     IWineD3DImpl_EnumAdapterModes,
3050     IWineD3DImpl_GetAdapterDisplayMode,
3051     IWineD3DImpl_GetAdapterIdentifier,
3052     IWineD3DImpl_CheckDeviceMultiSampleType,
3053     IWineD3DImpl_CheckDepthStencilMatch,
3054     IWineD3DImpl_CheckDeviceType,
3055     IWineD3DImpl_CheckDeviceFormat,
3056     IWineD3DImpl_CheckDeviceFormatConversion,
3057     IWineD3DImpl_GetDeviceCaps,
3058     IWineD3DImpl_CreateDevice
3059 };