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