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