advapi32: Create MachineGuid value if it doesn't exist.
[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 /* The d3d device ID */
40 static const GUID IID_D3DDEVICE_D3DUID = { 0xaeb2cdd4, 0x6e41, 0x43ea, { 0x94,0x1c,0x83,0x61,0xcc,0x76,0x07,0x81 } };
41
42 /* Extension detection */
43 static const struct {
44     const char *extension_string;
45     GL_SupportedExt extension;
46     DWORD version;
47 } EXTENSION_MAP[] = {
48     /* APPLE */
49     {"GL_APPLE_client_storage",             APPLE_CLIENT_STORAGE,           0                           },
50     {"GL_APPLE_fence",                      APPLE_FENCE,                    0                           },
51     {"GL_APPLE_flush_render",               APPLE_FLUSH_RENDER,             0                           },
52     {"GL_APPLE_ycbcr_422",                  APPLE_YCBCR_422,                0                           },
53     {"GL_APPLE_float_pixels",               APPLE_FLOAT_PIXELS,             0                           },
54
55     /* ATI */
56     {"GL_ATI_separate_stencil",             ATI_SEPARATE_STENCIL,           0                           },
57     {"GL_ATI_texture_env_combine3",         ATI_TEXTURE_ENV_COMBINE3,       0                           },
58     {"GL_ATI_texture_mirror_once",          ATI_TEXTURE_MIRROR_ONCE,        0                           },
59     {"GL_ATI_envmap_bumpmap",               ATI_ENVMAP_BUMPMAP,             0                           },
60     {"GL_ATI_fragment_shader",              ATI_FRAGMENT_SHADER,            0                           },
61
62     /* ARB */
63     {"GL_ARB_draw_buffers",                 ARB_DRAW_BUFFERS,               0                           },
64     {"GL_ARB_fragment_program",             ARB_FRAGMENT_PROGRAM,           0                           },
65     {"GL_ARB_fragment_shader",              ARB_FRAGMENT_SHADER,            0                           },
66     {"GL_ARB_half_float_pixel",             ARB_HALF_FLOAT_PIXEL,           0                           },
67     {"GL_ARB_imaging",                      ARB_IMAGING,                    0                           },
68     {"GL_ARB_multisample",                  ARB_MULTISAMPLE,                0                           }, /* needs GLX_ARB_MULTISAMPLE as well */
69     {"GL_ARB_multitexture",                 ARB_MULTITEXTURE,               0                           },
70     {"GL_ARB_occlusion_query",              ARB_OCCLUSION_QUERY,            0                           },
71     {"GL_ARB_pixel_buffer_object",          ARB_PIXEL_BUFFER_OBJECT,        0                           },
72     {"GL_ARB_point_parameters",             ARB_POINT_PARAMETERS,           0                           },
73     {"GL_ARB_point_sprite",                 ARB_POINT_SPRITE,               0                           },
74     {"GL_ARB_texture_border_clamp",         ARB_TEXTURE_BORDER_CLAMP,       0                           },
75     {"GL_ARB_texture_compression",          ARB_TEXTURE_COMPRESSION,        0                           },
76     {"GL_ARB_texture_cube_map",             ARB_TEXTURE_CUBE_MAP,           0                           },
77     {"GL_ARB_texture_env_add",              ARB_TEXTURE_ENV_ADD,            0                           },
78     {"GL_ARB_texture_env_combine",          ARB_TEXTURE_ENV_COMBINE,        0                           },
79     {"GL_ARB_texture_env_dot3",             ARB_TEXTURE_ENV_DOT3,           0                           },
80     {"GL_ARB_texture_float",                ARB_TEXTURE_FLOAT,              0                           },
81     {"GL_ARB_texture_mirrored_repeat",      ARB_TEXTURE_MIRRORED_REPEAT,    0                           },
82     {"GL_ARB_texture_non_power_of_two",     ARB_TEXTURE_NON_POWER_OF_TWO,   0                           },
83     {"GL_ARB_texture_rectangle",            ARB_TEXTURE_RECTANGLE,          0                           },
84     {"GL_ARB_vertex_blend",                 ARB_VERTEX_BLEND,               0                           },
85     {"GL_ARB_vertex_buffer_object",         ARB_VERTEX_BUFFER_OBJECT,       0                           },
86     {"GL_ARB_vertex_program",               ARB_VERTEX_PROGRAM,             0                           },
87     {"GL_ARB_vertex_shader",                ARB_VERTEX_SHADER,              0                           },
88     {"GL_ARB_shader_objects",               ARB_SHADER_OBJECTS,             0                           },
89
90     /* EXT */
91     {"GL_EXT_blend_color",                  EXT_BLEND_COLOR,                0                           },
92     {"GL_EXT_blend_minmax",                 EXT_BLEND_MINMAX,               0                           },
93     {"GL_EXT_blend_equation_separate",      EXT_BLEND_EQUATION_SEPARATE,    0                           },
94     {"GL_EXT_blend_func_separate",          EXT_BLEND_FUNC_SEPARATE,        0                           },
95     {"GL_EXT_fog_coord",                    EXT_FOG_COORD,                  0                           },
96     {"GL_EXT_framebuffer_blit",             EXT_FRAMEBUFFER_BLIT,           0                           },
97     {"GL_EXT_framebuffer_object",           EXT_FRAMEBUFFER_OBJECT,         0                           },
98     {"GL_EXT_paletted_texture",             EXT_PALETTED_TEXTURE,           0                           },
99     {"GL_EXT_point_parameters",             EXT_POINT_PARAMETERS,           0                           },
100     {"GL_EXT_secondary_color",              EXT_SECONDARY_COLOR,            0                           },
101     {"GL_EXT_stencil_two_side",             EXT_STENCIL_TWO_SIDE,           0                           },
102     {"GL_EXT_stencil_wrap",                 EXT_STENCIL_WRAP,               0                           },
103     {"GL_EXT_texture3D",                    EXT_TEXTURE3D,                  MAKEDWORD_VERSION(1, 2)     },
104     {"GL_EXT_texture_compression_s3tc",     EXT_TEXTURE_COMPRESSION_S3TC,   0                           },
105     {"GL_EXT_texture_env_add",              EXT_TEXTURE_ENV_ADD,            0                           },
106     {"GL_EXT_texture_env_combine",          EXT_TEXTURE_ENV_COMBINE,        0                           },
107     {"GL_EXT_texture_env_dot3",             EXT_TEXTURE_ENV_DOT3,           0                           },
108     {"GL_EXT_texture_sRGB",                 EXT_TEXTURE_SRGB,               0                           },
109     {"GL_EXT_texture_filter_anisotropic",   EXT_TEXTURE_FILTER_ANISOTROPIC, 0                           },
110     {"GL_EXT_texture_lod",                  EXT_TEXTURE_LOD,                0                           },
111     {"GL_EXT_texture_lod_bias",             EXT_TEXTURE_LOD_BIAS,           0                           },
112     {"GL_EXT_vertex_shader",                EXT_VERTEX_SHADER,              0                           },
113     {"GL_EXT_vertex_weighting",             EXT_VERTEX_WEIGHTING,           0                           },
114     {"GL_EXT_gpu_program_parameters",       EXT_GPU_PROGRAM_PARAMETERS,     0                           },
115
116     /* NV */
117     {"GL_NV_half_float",                    NV_HALF_FLOAT,                  0                           },
118     {"GL_NV_fence",                         NV_FENCE,                       0                           },
119     {"GL_NV_fog_distance",                  NV_FOG_DISTANCE,                0                           },
120     {"GL_NV_fragment_program",              NV_FRAGMENT_PROGRAM,            0                           },
121     {"GL_NV_fragment_program2",             NV_FRAGMENT_PROGRAM2,           0                           },
122     {"GL_NV_register_combiners",            NV_REGISTER_COMBINERS,          0                           },
123     {"GL_NV_register_combiners2",           NV_REGISTER_COMBINERS2,         0                           },
124     {"GL_NV_texgen_reflection",             NV_TEXGEN_REFLECTION,           0                           },
125     {"GL_NV_texture_env_combine4",          NV_TEXTURE_ENV_COMBINE4,        0                           },
126     {"GL_NV_texture_shader",                NV_TEXTURE_SHADER,              0                           },
127     {"GL_NV_texture_shader2",               NV_TEXTURE_SHADER2,             0                           },
128     {"GL_NV_texture_shader3",               NV_TEXTURE_SHADER3,             0                           },
129     {"GL_NV_occlusion_query",               NV_OCCLUSION_QUERY,             0                           },
130     {"GL_NV_vertex_program",                NV_VERTEX_PROGRAM,              0                           },
131     {"GL_NV_vertex_program1_1",             NV_VERTEX_PROGRAM1_1,           0                           },
132     {"GL_NV_vertex_program2",               NV_VERTEX_PROGRAM2,             0                           },
133     {"GL_NV_vertex_program3",               NV_VERTEX_PROGRAM3,             0                           },
134     {"GL_NV_depth_clamp",                   NV_DEPTH_CLAMP,                 0                           },
135     {"GL_NV_light_max_exponent",            NV_LIGHT_MAX_EXPONENT,          0                           },
136
137     /* SGI */
138     {"GL_SGIS_generate_mipmap",             SGIS_GENERATE_MIPMAP,           0                           },
139 };
140
141 /**********************************************************
142  * Utility functions follow
143  **********************************************************/
144
145 /* Adapters */
146 static int numAdapters = 0;
147 static struct WineD3DAdapter Adapters[1];
148
149 static HRESULT WINAPI IWineD3DImpl_CheckDeviceFormat(IWineD3D *iface, UINT Adapter, WINED3DDEVTYPE DeviceType, WINED3DFORMAT AdapterFormat, DWORD Usage, WINED3DRESOURCETYPE RType, WINED3DFORMAT CheckFormat);
150
151 /* lookup tables */
152 int minLookup[MAX_LOOKUPS];
153 int maxLookup[MAX_LOOKUPS];
154 DWORD *stateLookup[MAX_LOOKUPS];
155
156 DWORD minMipLookup[WINED3DTEXF_ANISOTROPIC + 1][WINED3DTEXF_LINEAR + 1];
157
158 /* drawStridedSlow attributes */
159 glAttribFunc position_funcs[WINED3DDECLTYPE_UNUSED];
160 glAttribFunc diffuse_funcs[WINED3DDECLTYPE_UNUSED];
161 glAttribFunc specular_funcs[WINED3DDECLTYPE_UNUSED];
162 glAttribFunc normal_funcs[WINED3DDECLTYPE_UNUSED];
163 glTexAttribFunc texcoord_funcs[WINED3DDECLTYPE_UNUSED];
164
165 /**
166  * Note: GL seems to trap if GetDeviceCaps is called before any HWND's created
167  * ie there is no GL Context - Get a default rendering context to enable the
168  * function query some info from GL
169  */
170
171 static int             wined3d_fake_gl_context_ref = 0;
172 static BOOL            wined3d_fake_gl_context_foreign;
173 static BOOL            wined3d_fake_gl_context_available = FALSE;
174 static HDC             wined3d_fake_gl_context_hdc = NULL;
175 static HWND            wined3d_fake_gl_context_hwnd = NULL;
176
177 static CRITICAL_SECTION wined3d_fake_gl_context_cs;
178 static CRITICAL_SECTION_DEBUG wined3d_fake_gl_context_cs_debug =
179 {
180     0, 0, &wined3d_fake_gl_context_cs,
181     { &wined3d_fake_gl_context_cs_debug.ProcessLocksList,
182       &wined3d_fake_gl_context_cs_debug.ProcessLocksList },
183     0, 0, { (DWORD_PTR)(__FILE__ ": wined3d_fake_gl_context_cs") }
184 };
185 static CRITICAL_SECTION wined3d_fake_gl_context_cs = { &wined3d_fake_gl_context_cs_debug, -1, 0, 0, 0, 0 };
186
187 static void WineD3D_ReleaseFakeGLContext(void) {
188     HGLRC glCtx;
189
190     EnterCriticalSection(&wined3d_fake_gl_context_cs);
191
192     if(!wined3d_fake_gl_context_available) {
193         TRACE_(d3d_caps)("context not available\n");
194         LeaveCriticalSection(&wined3d_fake_gl_context_cs);
195         return;
196     }
197
198     glCtx = pwglGetCurrentContext();
199
200     TRACE_(d3d_caps)("decrementing ref from %i\n", wined3d_fake_gl_context_ref);
201     if (0 == (--wined3d_fake_gl_context_ref) ) {
202         if(!wined3d_fake_gl_context_foreign && glCtx) {
203             TRACE_(d3d_caps)("destroying fake GL context\n");
204             pwglMakeCurrent(NULL, NULL);
205             pwglDeleteContext(glCtx);
206         }
207         if(wined3d_fake_gl_context_hdc)
208             ReleaseDC(wined3d_fake_gl_context_hwnd, wined3d_fake_gl_context_hdc);
209         wined3d_fake_gl_context_hdc = NULL; /* Make sure we don't think that it is still around */
210         if(wined3d_fake_gl_context_hwnd)
211             DestroyWindow(wined3d_fake_gl_context_hwnd);
212         wined3d_fake_gl_context_hwnd = NULL;
213         wined3d_fake_gl_context_available = FALSE;
214     }
215     assert(wined3d_fake_gl_context_ref >= 0);
216
217     LeaveCriticalSection(&wined3d_fake_gl_context_cs);
218 }
219
220 static BOOL WineD3D_CreateFakeGLContext(void) {
221     HGLRC glCtx = NULL;
222
223     EnterCriticalSection(&wined3d_fake_gl_context_cs);
224
225     TRACE("getting context...\n");
226     if(wined3d_fake_gl_context_ref > 0) goto ret;
227     assert(0 == wined3d_fake_gl_context_ref);
228
229     wined3d_fake_gl_context_foreign = TRUE;
230
231     glCtx = pwglGetCurrentContext();
232     if (!glCtx) {
233         PIXELFORMATDESCRIPTOR pfd;
234         int iPixelFormat;
235
236         wined3d_fake_gl_context_foreign = FALSE;
237
238         /* We need a fake window as a hdc retrieved using GetDC(0) can't be used for much GL purposes */
239         wined3d_fake_gl_context_hwnd = CreateWindowA("WineD3D_OpenGL", "WineD3D fake window", WS_OVERLAPPEDWINDOW,        10, 10, 10, 10, NULL, NULL, NULL, NULL);
240         if(!wined3d_fake_gl_context_hwnd) {
241             ERR("HWND creation failed!\n");
242             goto fail;
243         }
244         wined3d_fake_gl_context_hdc = GetDC(wined3d_fake_gl_context_hwnd);
245         if(!wined3d_fake_gl_context_hdc) {
246             ERR("GetDC failed!\n");
247             goto fail;
248         }
249
250         /* PixelFormat selection */
251         ZeroMemory(&pfd, sizeof(pfd));
252         pfd.nSize      = sizeof(pfd);
253         pfd.nVersion   = 1;
254         pfd.dwFlags    = PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER | PFD_DRAW_TO_WINDOW;/*PFD_GENERIC_ACCELERATED*/
255         pfd.iPixelType = PFD_TYPE_RGBA;
256         pfd.cColorBits = 32;
257         pfd.iLayerType = PFD_MAIN_PLANE;
258
259         iPixelFormat = ChoosePixelFormat(wined3d_fake_gl_context_hdc, &pfd);
260         if(!iPixelFormat) {
261             /* If this happens something is very wrong as ChoosePixelFormat barely fails */
262             ERR("Can't find a suitable iPixelFormat\n");
263             goto fail;
264         }
265         DescribePixelFormat(wined3d_fake_gl_context_hdc, iPixelFormat, sizeof(pfd), &pfd);
266         SetPixelFormat(wined3d_fake_gl_context_hdc, iPixelFormat, &pfd);
267
268         /* Create a GL context */
269         glCtx = pwglCreateContext(wined3d_fake_gl_context_hdc);
270         if (!glCtx) {
271             WARN_(d3d_caps)("Error creating default context for capabilities initialization\n");
272             goto fail;
273         }
274
275         /* Make it the current GL context */
276         if (!pwglMakeCurrent(wined3d_fake_gl_context_hdc, glCtx)) {
277             WARN_(d3d_caps)("Error setting default context as current for capabilities initialization\n");
278             goto fail;
279         }
280     }
281
282   ret:
283     TRACE("incrementing ref from %i\n", wined3d_fake_gl_context_ref);
284     wined3d_fake_gl_context_ref++;
285     wined3d_fake_gl_context_available = TRUE;
286     LeaveCriticalSection(&wined3d_fake_gl_context_cs);
287     return TRUE;
288   fail:
289     if(wined3d_fake_gl_context_hdc)
290         ReleaseDC(wined3d_fake_gl_context_hwnd, wined3d_fake_gl_context_hdc);
291     wined3d_fake_gl_context_hdc = NULL;
292     if(wined3d_fake_gl_context_hwnd)
293         DestroyWindow(wined3d_fake_gl_context_hwnd);
294     wined3d_fake_gl_context_hwnd = NULL;
295     if(glCtx) pwglDeleteContext(glCtx);
296     LeaveCriticalSection(&wined3d_fake_gl_context_cs);
297     return FALSE;
298 }
299
300 /* Adjust the amount of used texture memory */
301 long WineD3DAdapterChangeGLRam(IWineD3DDeviceImpl *D3DDevice, long glram){
302     UINT Adapter = D3DDevice->adapterNo;
303
304     Adapters[Adapter].UsedTextureRam += glram;
305     TRACE("Adjusted gl ram by %ld to %d\n", glram, Adapters[Adapter].UsedTextureRam);
306     return Adapters[Adapter].UsedTextureRam;
307 }
308
309 /**********************************************************
310  * IUnknown parts follows
311  **********************************************************/
312
313 static HRESULT WINAPI IWineD3DImpl_QueryInterface(IWineD3D *iface,REFIID riid,LPVOID *ppobj)
314 {
315     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
316
317     TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(riid),ppobj);
318     if (IsEqualGUID(riid, &IID_IUnknown)
319         || IsEqualGUID(riid, &IID_IWineD3DBase)
320         || IsEqualGUID(riid, &IID_IWineD3DDevice)) {
321         IUnknown_AddRef(iface);
322         *ppobj = This;
323         return S_OK;
324     }
325     *ppobj = NULL;
326     return E_NOINTERFACE;
327 }
328
329 static ULONG WINAPI IWineD3DImpl_AddRef(IWineD3D *iface) {
330     IWineD3DImpl *This = (IWineD3DImpl *)iface;
331     ULONG refCount = InterlockedIncrement(&This->ref);
332
333     TRACE("(%p) : AddRef increasing from %d\n", This, refCount - 1);
334     return refCount;
335 }
336
337 static ULONG WINAPI IWineD3DImpl_Release(IWineD3D *iface) {
338     IWineD3DImpl *This = (IWineD3DImpl *)iface;
339     ULONG ref;
340     TRACE("(%p) : Releasing from %d\n", This, This->ref);
341     ref = InterlockedDecrement(&This->ref);
342     if (ref == 0) {
343         HeapFree(GetProcessHeap(), 0, This);
344     }
345
346     return ref;
347 }
348
349 /* Set the shader type for this device, depending on the given capabilities,
350  * the device type, and the user preferences in wined3d_settings */
351
352 void select_shader_mode(
353     WineD3D_GL_Info *gl_info,
354     WINED3DDEVTYPE DeviceType,
355     int* ps_selected,
356     int* vs_selected) {
357
358     if (wined3d_settings.vs_mode == VS_NONE) {
359         *vs_selected = SHADER_NONE;
360     } else if (gl_info->supported[ARB_VERTEX_SHADER] && wined3d_settings.glslRequested) {
361         /* Geforce4 cards support GLSL but for vertex shaders only. Further its reported GLSL caps are
362          * wrong. This combined with the fact that glsl won't offer more features or performance, use ARB
363          * shaders only on this card. */
364         if(gl_info->vs_nv_version && gl_info->vs_nv_version < VS_VERSION_20)
365             *vs_selected = SHADER_ARB;
366         else
367             *vs_selected = SHADER_GLSL;
368     } else if (gl_info->supported[ARB_VERTEX_PROGRAM]) {
369         *vs_selected = SHADER_ARB;
370     } else {
371         *vs_selected = SHADER_NONE;
372     }
373
374     if (wined3d_settings.ps_mode == PS_NONE) {
375         *ps_selected = SHADER_NONE;
376     } else if (gl_info->supported[ARB_FRAGMENT_SHADER] && wined3d_settings.glslRequested) {
377         *ps_selected = SHADER_GLSL;
378     } else if (gl_info->supported[ARB_FRAGMENT_PROGRAM]) {
379         *ps_selected = SHADER_ARB;
380     } else if (gl_info->supported[ATI_FRAGMENT_SHADER]) {
381         *ps_selected = SHADER_ATI;
382     } else {
383         *ps_selected = SHADER_NONE;
384     }
385 }
386
387 /** Select the number of report maximum shader constants based on the selected shader modes */
388 static void select_shader_max_constants(
389     int ps_selected_mode,
390     int vs_selected_mode,
391     WineD3D_GL_Info *gl_info) {
392
393     switch (vs_selected_mode) {
394         case SHADER_GLSL:
395             /* Subtract the other potential uniforms from the max available (bools, ints, and 1 row of projection matrix) */
396             gl_info->max_vshader_constantsF = gl_info->vs_glsl_constantsF - (MAX_CONST_B / 4) - MAX_CONST_I - 1;
397             break;
398         case SHADER_ARB:
399             /* We have to subtract any other PARAMs that we might use in our shader programs.
400              * ATI seems to count 2 implicit PARAMs when we use fog and NVIDIA counts 1,
401              * and we reference one row of the PROJECTION matrix which counts as 1 PARAM. */
402             gl_info->max_vshader_constantsF = gl_info->vs_arb_constantsF - 3;
403             break;
404         default:
405             gl_info->max_vshader_constantsF = 0;
406             break;
407     }
408
409     switch (ps_selected_mode) {
410         case SHADER_GLSL:
411             /* Subtract the other potential uniforms from the max available (bools & ints), and 2 states for fog.
412              * In theory the texbem instruction may need one more shader constant too. But lets assume
413              * that a sm <= 1.3 shader does not need all the uniforms provided by a glsl-capable card,
414              * and lets not take away a uniform needlessly from all other shaders.
415              */
416             gl_info->max_pshader_constantsF = gl_info->ps_glsl_constantsF - (MAX_CONST_B / 4) - MAX_CONST_I - 2;
417             break;
418         case SHADER_ARB:
419             /* The arb shader only loads the bump mapping environment matrix into the shader if it finds
420              * a free constant to do that, so only reduce the number of available constants by 2 for the fog states.
421              */
422             gl_info->max_pshader_constantsF = gl_info->ps_arb_constantsF - 2;
423             break;
424         default:
425             gl_info->max_pshader_constantsF = 0;
426             break;
427     }
428 }
429
430 /**********************************************************
431  * IWineD3D parts follows
432  **********************************************************/
433
434 #define GLINFO_LOCATION (*gl_info)
435 static inline BOOL test_arb_vs_offset_limit(WineD3D_GL_Info *gl_info) {
436     GLuint prog;
437     BOOL ret = FALSE;
438     const char *testcode =
439         "!!ARBvp1.0\n"
440         "PARAM C[66] = { program.env[0..65] };\n"
441         "ADDRESS A0;"
442         "PARAM zero = {0.0, 0.0, 0.0, 0.0};\n"
443         "ARL A0.x, zero.x;\n"
444         "MOV result.position, C[A0.x + 65];\n"
445         "END\n";
446
447     while(glGetError());
448     GL_EXTCALL(glGenProgramsARB(1, &prog));
449     if(!prog) {
450         ERR("Failed to create an ARB offset limit test program\n");
451     }
452     GL_EXTCALL(glBindProgramARB(GL_VERTEX_PROGRAM_ARB, prog));
453     GL_EXTCALL(glProgramStringARB(GL_VERTEX_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB,
454                                   strlen(testcode), testcode));
455     if(glGetError() != 0) {
456         TRACE("OpenGL implementation does not allow indirect addressing offsets > 63\n");
457         TRACE("error: %s\n", debugstr_a((const char *)glGetString(GL_PROGRAM_ERROR_STRING_ARB)));
458         ret = TRUE;
459     } else TRACE("OpenGL implementation allows offsets > 63\n");
460
461     GL_EXTCALL(glBindProgramARB(GL_VERTEX_PROGRAM_ARB, 0));
462     GL_EXTCALL(glDeleteProgramsARB(1, &prog));
463     checkGLcall("ARB vp offset limit test cleanup\n");
464
465     return ret;
466 }
467
468 static DWORD ver_for_ext(GL_SupportedExt ext)
469 {
470     unsigned int i;
471     for (i = 0; i < (sizeof(EXTENSION_MAP) / sizeof(*EXTENSION_MAP)); ++i) {
472         if(EXTENSION_MAP[i].extension == ext) {
473             return EXTENSION_MAP[i].version;
474         }
475     }
476     return 0;
477 }
478
479 BOOL IWineD3DImpl_FillGLCaps(WineD3D_GL_Info *gl_info) {
480     const char *GL_Extensions    = NULL;
481     const char *WGL_Extensions   = NULL;
482     const char *gl_string        = NULL;
483     const char *gl_string_cursor = NULL;
484     GLint       gl_max;
485     GLfloat     gl_floatv[2];
486     int         major = 1, minor = 0;
487     BOOL        return_value = TRUE;
488     unsigned    i;
489     HDC         hdc;
490     unsigned int vidmem=0;
491
492     TRACE_(d3d_caps)("(%p)\n", gl_info);
493
494     ENTER_GL();
495
496     gl_string = (const char *) glGetString(GL_RENDERER);
497     if (NULL == gl_string)
498         gl_string = "None";
499     strcpy(gl_info->gl_renderer, gl_string);
500
501     gl_string = (const char *) glGetString(GL_VENDOR);
502     TRACE_(d3d_caps)("Filling vendor string %s\n", gl_string);
503     if (gl_string != NULL) {
504         /* Fill in the GL vendor */
505         if (strstr(gl_string, "NVIDIA")) {
506             gl_info->gl_vendor = VENDOR_NVIDIA;
507         } else if (strstr(gl_string, "ATI")) {
508             gl_info->gl_vendor = VENDOR_ATI;
509         } else if (strstr(gl_string, "Intel(R)") ||
510                    strstr(gl_info->gl_renderer, "Intel(R)") ||
511                    strstr(gl_string, "Intel Inc.")) {
512             gl_info->gl_vendor = VENDOR_INTEL;
513         } else if (strstr(gl_string, "Mesa")) {
514             gl_info->gl_vendor = VENDOR_MESA;
515         } else {
516             gl_info->gl_vendor = VENDOR_WINE;
517         }
518     } else {
519         gl_info->gl_vendor = VENDOR_WINE;
520     }
521
522
523     TRACE_(d3d_caps)("found GL_VENDOR (%s)->(0x%04x)\n", debugstr_a(gl_string), gl_info->gl_vendor);
524
525     /* Parse the GL_VERSION field into major and minor information */
526     gl_string = (const char *) glGetString(GL_VERSION);
527     if (gl_string != NULL) {
528
529         /* First, parse the generic opengl version. This is supposed not to be convoluted with
530          * driver specific information
531          */
532         gl_string_cursor = gl_string;
533         major = atoi(gl_string_cursor);
534         if(major <= 0) {
535             ERR("Invalid opengl major version: %d\n", major);
536         }
537         while (*gl_string_cursor <= '9' && *gl_string_cursor >= '0') {
538             ++gl_string_cursor;
539         }
540         if (*gl_string_cursor++ != '.') {
541             ERR_(d3d_caps)("Invalid opengl version string: %s\n", debugstr_a(gl_string));
542         }
543         minor = atoi(gl_string_cursor);
544         TRACE_(d3d_caps)("Found OpenGL version: %d.%d\n", major, minor);
545         gl_info->gl_version = MAKEDWORD_VERSION(major, minor);
546
547         /* Now parse the driver specific string which we'll report to the app */
548         switch (gl_info->gl_vendor) {
549         case VENDOR_NVIDIA:
550             gl_string_cursor = strstr(gl_string, "NVIDIA");
551             if (!gl_string_cursor) {
552                 ERR_(d3d_caps)("Invalid nVidia version string: %s\n", debugstr_a(gl_string));
553                 break;
554             }
555
556             gl_string_cursor = strstr(gl_string_cursor, " ");
557             if (!gl_string_cursor) {
558                 ERR_(d3d_caps)("Invalid nVidia version string: %s\n", debugstr_a(gl_string));
559                 break;
560             }
561
562             while (*gl_string_cursor == ' ') {
563                 ++gl_string_cursor;
564             }
565
566             if (!*gl_string_cursor) {
567                 ERR_(d3d_caps)("Invalid nVidia version string: %s\n", debugstr_a(gl_string));
568                 break;
569             }
570
571             major = atoi(gl_string_cursor);
572             while (*gl_string_cursor <= '9' && *gl_string_cursor >= '0') {
573                 ++gl_string_cursor;
574             }
575
576             if (*gl_string_cursor++ != '.') {
577                 ERR_(d3d_caps)("Invalid nVidia version string: %s\n", debugstr_a(gl_string));
578                 break;
579             }
580
581             minor = atoi(gl_string_cursor);
582             minor = major*100+minor;
583             major = 10;
584
585             break;
586
587         case VENDOR_ATI:
588             major = minor = 0;
589             gl_string_cursor = strchr(gl_string, '-');
590             if (gl_string_cursor) {
591                 int error = 0;
592                 gl_string_cursor++;
593
594                 /* Check if version number is of the form x.y.z */
595                 if (*gl_string_cursor > '9' && *gl_string_cursor < '0')
596                     error = 1;
597                 if (!error && *(gl_string_cursor+2) > '9' && *(gl_string_cursor+2) < '0')
598                     error = 1;
599                 if (!error && *(gl_string_cursor+4) > '9' && *(gl_string_cursor+4) < '0')
600                     error = 1;
601                 if (!error && *(gl_string_cursor+1) != '.' && *(gl_string_cursor+3) != '.')
602                     error = 1;
603
604                 /* Mark version number as malformed */
605                 if (error)
606                     gl_string_cursor = 0;
607             }
608
609             if (!gl_string_cursor)
610                 WARN_(d3d_caps)("malformed GL_VERSION (%s)\n", debugstr_a(gl_string));
611             else {
612                 major = *gl_string_cursor - '0';
613                 minor = (*(gl_string_cursor+2) - '0') * 256 + (*(gl_string_cursor+4) - '0');
614             }
615             break;
616
617         case VENDOR_INTEL:
618             /* Apple and Mesa version strings look differently, but both provide intel drivers */
619             if(strstr(gl_string, "APPLE")) {
620                 /* [0-9]+.[0-9]+ APPLE-[0-9]+.[0.9]+.[0.9]+
621                  * We only need the first part, and use the APPLE as identification
622                  * "1.2 APPLE-1.4.56"
623                  */
624                 gl_string_cursor = gl_string;
625                 major = atoi(gl_string_cursor);
626                 while (*gl_string_cursor <= '9' && *gl_string_cursor >= '0') {
627                     ++gl_string_cursor;
628                 }
629
630                 if (*gl_string_cursor++ != '.') {
631                     ERR_(d3d_caps)("Invalid MacOS-Intel version string: %s\n", debugstr_a(gl_string));
632                     break;
633                 }
634
635                 minor = atoi(gl_string_cursor);
636                 break;
637             }
638
639         case VENDOR_MESA:
640             gl_string_cursor = strstr(gl_string, "Mesa");
641             gl_string_cursor = strstr(gl_string_cursor, " ");
642             while (*gl_string_cursor && ' ' == *gl_string_cursor) ++gl_string_cursor;
643             if (*gl_string_cursor) {
644                 char tmp[16];
645                 int cursor = 0;
646
647                 while (*gl_string_cursor <= '9' && *gl_string_cursor >= '0') {
648                     tmp[cursor++] = *gl_string_cursor;
649                     ++gl_string_cursor;
650                 }
651                 tmp[cursor] = 0;
652                 major = atoi(tmp);
653
654                 if (*gl_string_cursor != '.') WARN_(d3d_caps)("malformed GL_VERSION (%s)\n", debugstr_a(gl_string));
655                 ++gl_string_cursor;
656
657                 cursor = 0;
658                 while (*gl_string_cursor <= '9' && *gl_string_cursor >= '0') {
659                     tmp[cursor++] = *gl_string_cursor;
660                     ++gl_string_cursor;
661                 }
662                 tmp[cursor] = 0;
663                 minor = atoi(tmp);
664             }
665             break;
666
667         default:
668             major = 0;
669             minor = 9;
670         }
671         gl_info->driver_version = MAKEDWORD_VERSION(major, minor);
672         TRACE_(d3d_caps)("found driver version (%s)->%i.%i->(0x%08x)\n", debugstr_a(gl_string), major, minor, gl_info->driver_version);
673         /* Current Windows drivers have versions like 6.14.... (some older have an earlier version) */
674         gl_info->driver_version_hipart = MAKEDWORD_VERSION(6, 14);
675     } else {
676         FIXME("OpenGL driver did not return version information\n");
677         gl_info->driver_version = MAKEDWORD_VERSION(0, 0);
678         gl_info->driver_version_hipart = MAKEDWORD_VERSION(6, 14);
679     }
680
681     TRACE_(d3d_caps)("found GL_RENDERER (%s)->(0x%04x)\n", debugstr_a(gl_info->gl_renderer), gl_info->gl_card);
682
683     /*
684      * Initialize openGL extension related variables
685      *  with Default values
686      */
687     memset(&gl_info->supported, 0, sizeof(gl_info->supported));
688     gl_info->max_buffers        = 1;
689     gl_info->max_textures       = 1;
690     gl_info->max_texture_stages = 1;
691     gl_info->max_fragment_samplers = 1;
692     gl_info->max_vertex_samplers = 0;
693     gl_info->max_combined_samplers = 0;
694     gl_info->max_sampler_stages = 1;
695     gl_info->ps_arb_version = PS_VERSION_NOT_SUPPORTED;
696     gl_info->ps_arb_max_temps = 0;
697     gl_info->ps_arb_max_instructions = 0;
698     gl_info->vs_arb_version = VS_VERSION_NOT_SUPPORTED;
699     gl_info->vs_arb_max_temps = 0;
700     gl_info->vs_arb_max_instructions = 0;
701     gl_info->vs_nv_version  = VS_VERSION_NOT_SUPPORTED;
702     gl_info->vs_ati_version = VS_VERSION_NOT_SUPPORTED;
703     gl_info->vs_glsl_constantsF = 0;
704     gl_info->ps_glsl_constantsF = 0;
705     gl_info->vs_arb_constantsF = 0;
706     gl_info->ps_arb_constantsF = 0;
707
708     /* Retrieve opengl defaults */
709     glGetIntegerv(GL_MAX_CLIP_PLANES, &gl_max);
710     gl_info->max_clipplanes = min(WINED3DMAXUSERCLIPPLANES, gl_max);
711     TRACE_(d3d_caps)("ClipPlanes support - num Planes=%d\n", gl_max);
712
713     glGetIntegerv(GL_MAX_LIGHTS, &gl_max);
714     gl_info->max_lights = gl_max;
715     TRACE_(d3d_caps)("Lights support - max lights=%d\n", gl_max);
716
717     glGetIntegerv(GL_MAX_TEXTURE_SIZE, &gl_max);
718     gl_info->max_texture_size = gl_max;
719     TRACE_(d3d_caps)("Maximum texture size support - max texture size=%d\n", gl_max);
720
721     glGetFloatv(GL_POINT_SIZE_RANGE, gl_floatv);
722     gl_info->max_pointsizemin = gl_floatv[0];
723     gl_info->max_pointsize = gl_floatv[1];
724     TRACE_(d3d_caps)("Maximum point size support - max point size=%f\n", gl_floatv[1]);
725
726     glGetIntegerv(GL_AUX_BUFFERS, &gl_max);
727     gl_info->max_aux_buffers = gl_max;
728     TRACE_(d3d_caps)("Offscreen rendering support - number of aux buffers=%d\n", gl_max);
729
730     /* Parse the gl supported features, in theory enabling parts of our code appropriately */
731     GL_Extensions = (const char *) glGetString(GL_EXTENSIONS);
732     TRACE_(d3d_caps)("GL_Extensions reported:\n");
733
734     if (NULL == GL_Extensions) {
735         ERR("   GL_Extensions returns NULL\n");
736     } else {
737         while (*GL_Extensions != 0x00) {
738             const char *Start;
739             char        ThisExtn[256];
740             size_t      len;
741
742             while (isspace(*GL_Extensions)) GL_Extensions++;
743             Start = GL_Extensions;
744             while (!isspace(*GL_Extensions) && *GL_Extensions != 0x00) {
745                 GL_Extensions++;
746             }
747
748             len = GL_Extensions - Start;
749             if (len == 0 || len >= sizeof(ThisExtn))
750                 continue;
751
752             memcpy(ThisExtn, Start, len);
753             ThisExtn[len] = '\0';
754             TRACE_(d3d_caps)("- %s\n", ThisExtn);
755
756             for (i = 0; i < (sizeof(EXTENSION_MAP) / sizeof(*EXTENSION_MAP)); ++i) {
757                 if (!strcmp(ThisExtn, EXTENSION_MAP[i].extension_string)) {
758                     TRACE_(d3d_caps)(" FOUND: %s support\n", EXTENSION_MAP[i].extension_string);
759                     gl_info->supported[EXTENSION_MAP[i].extension] = TRUE;
760                     break;
761                 }
762             }
763         }
764         /* Now work out what GL support this card really has */
765 #define USE_GL_FUNC(type, pfn, ext, replace) { \
766             DWORD ver = ver_for_ext(ext); \
767             if(gl_info->supported[ext]) gl_info->pfn = (type) pwglGetProcAddress(#pfn); \
768             else if(ver && ver <= gl_info->gl_version) gl_info->pfn = (type) pwglGetProcAddress(#replace); \
769             else gl_info->pfn = NULL; \
770         }
771         GL_EXT_FUNCS_GEN;
772 #undef USE_GL_FUNC
773
774 #define USE_GL_FUNC(type, pfn, ext, replace) gl_info->pfn = (type) pwglGetProcAddress(#pfn);
775         WGL_EXT_FUNCS_GEN;
776 #undef USE_GL_FUNC
777
778         /* Now mark all the extensions supported which are included in the opengl core version. Do this *after*
779          * loading the functions, otherwise the code above will load the extension entry points instead of the
780          * core functions, which may not work
781          */
782         for (i = 0; i < (sizeof(EXTENSION_MAP) / sizeof(*EXTENSION_MAP)); ++i) {
783             if (gl_info->supported[EXTENSION_MAP[i].extension] == FALSE &&
784                 EXTENSION_MAP[i].version <= gl_info->gl_version && EXTENSION_MAP[i].version) {
785                 TRACE_(d3d_caps)(" GL CORE: %s support\n", EXTENSION_MAP[i].extension_string);
786                 gl_info->supported[EXTENSION_MAP[i].extension] = TRUE;
787             }
788         }
789
790         if (gl_info->supported[APPLE_FENCE]) {
791             /* GL_NV_fence and GL_APPLE_fence provide the same functionality basically.
792              * The apple extension interacts with some other apple exts. Disable the NV
793              * extension if the apple one is support to prevent confusion in other parts
794              * of the code
795              */
796             gl_info->supported[NV_FENCE] = FALSE;
797         }
798         if (gl_info->supported[APPLE_FLOAT_PIXELS]) {
799             /* GL_APPLE_float_pixels == GL_ARB_texture_float + GL_ARB_half_float_pixel
800              *
801              * The enums are the same:
802              * GL_RGBA16F_ARB     = GL_RGBA_FLOAT16_APPLE = 0x881A
803              * GL_RGB16F_ARB      = GL_RGB_FLOAT16_APPLE  = 0x881B
804              * GL_RGBA32F_ARB     = GL_RGBA_FLOAT32_APPLE = 0x8814
805              * GL_RGB32F_ARB      = GL_RGB_FLOAT32_APPLE  = 0x8815
806              * GL_HALF_FLOAT_ARB  = GL_HALF_APPLE         =  0x140B
807              */
808             if(!gl_info->supported[ARB_TEXTURE_FLOAT]) {
809                 TRACE_(d3d_caps)(" IMPLIED: GL_ARB_texture_float support(from GL_APPLE_float_pixels\n");
810                 gl_info->supported[ARB_TEXTURE_FLOAT] = TRUE;
811             }
812             if(!gl_info->supported[ARB_HALF_FLOAT_PIXEL]) {
813                 TRACE_(d3d_caps)(" IMPLIED: GL_ARB_half_float_pixel support(from GL_APPLE_float_pixels\n");
814                 gl_info->supported[ARB_HALF_FLOAT_PIXEL] = TRUE;
815             }
816         }
817         if (gl_info->supported[ARB_TEXTURE_CUBE_MAP]) {
818             TRACE_(d3d_caps)(" IMPLIED: NVIDIA (NV) Texture Gen Reflection support\n");
819             gl_info->supported[NV_TEXGEN_REFLECTION] = TRUE;
820         }
821         if (gl_info->supported[NV_TEXTURE_SHADER2]) {
822             /* GL_ATI_envmap_bumpmap won't play nice with texture shaders, so disable it
823              * Won't occur in any real world situation though
824              */
825             gl_info->supported[ATI_ENVMAP_BUMPMAP] = FALSE;
826             if(gl_info->supported[NV_REGISTER_COMBINERS]) {
827                 /* Also disable ATI_FRAGMENT_SHADER if register combienrs and texture_shader2
828                  * are supported. The nv extensions provide the same functionality as the
829                  * ATI one, and a bit more(signed pixelformats)
830                  */
831                 gl_info->supported[ATI_FRAGMENT_SHADER] = FALSE;
832             }
833         }
834         if (gl_info->supported[ARB_DRAW_BUFFERS]) {
835             glGetIntegerv(GL_MAX_DRAW_BUFFERS_ARB, &gl_max);
836             gl_info->max_buffers = gl_max;
837             TRACE_(d3d_caps)("Max draw buffers: %u\n", gl_max);
838         }
839         if (gl_info->supported[ARB_MULTITEXTURE]) {
840             glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, &gl_max);
841             gl_info->max_textures = min(MAX_TEXTURES, gl_max);
842             TRACE_(d3d_caps)("Max textures: %d\n", gl_info->max_textures);
843
844             if (gl_info->supported[NV_REGISTER_COMBINERS]) {
845                 GLint tmp;
846                 glGetIntegerv(GL_MAX_GENERAL_COMBINERS_NV, &tmp);
847                 gl_info->max_texture_stages = min(MAX_TEXTURES, tmp);
848             } else {
849                 gl_info->max_texture_stages = min(MAX_TEXTURES, gl_max);
850             }
851             TRACE_(d3d_caps)("Max texture stages: %d\n", gl_info->max_texture_stages);
852
853             if (gl_info->supported[ARB_FRAGMENT_PROGRAM]) {
854                 GLint tmp;
855                 glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS_ARB, &tmp);
856                 gl_info->max_fragment_samplers = min(MAX_FRAGMENT_SAMPLERS, tmp);
857             } else {
858                 gl_info->max_fragment_samplers = max(gl_info->max_fragment_samplers, gl_max);
859             }
860             TRACE_(d3d_caps)("Max fragment samplers: %d\n", gl_info->max_fragment_samplers);
861
862             if (gl_info->supported[ARB_VERTEX_SHADER]) {
863                 GLint tmp;
864                 glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB, &tmp);
865                 gl_info->max_vertex_samplers = tmp;
866                 glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB, &tmp);
867                 gl_info->max_combined_samplers = tmp;
868
869                 /* Loading GLSL sampler uniforms is much simpler if we can assume that the sampler setup
870                  * is known at shader link time. In a vertex shader + pixel shader combination this isn't
871                  * an issue because then the sampler setup only depends on the two shaders. If a pixel
872                  * shader is used with fixed function vertex processing we're fine too because fixed function
873                  * vertex processing doesn't use any samplers. If fixed function fragment processing is
874                  * used we have to make sure that all vertex sampler setups are valid together with all
875                  * possible fixed function fragment processing setups. This is true if vsamplers + MAX_TEXTURES
876                  * <= max_samplers. This is true on all d3d9 cards that support vtf(gf 6 and gf7 cards).
877                  * dx9 radeon cards do not support vertex texture fetch. DX10 cards have 128 samplers, and
878                  * dx9 is limited to 8 fixed function texture stages and 4 vertex samplers. DX10 does not have
879                  * a fixed function pipeline anymore.
880                  *
881                  * So this is just a check to check that our assumption holds true. If not, write a warning
882                  * and reduce the number of vertex samplers or probably disable vertex texture fetch.
883                  */
884                 if(gl_info->max_vertex_samplers &&
885                    MAX_TEXTURES + gl_info->max_vertex_samplers > gl_info->max_combined_samplers) {
886                     FIXME("OpenGL implementation supports %u vertex samplers and %u total samplers\n",
887                           gl_info->max_vertex_samplers, gl_info->max_combined_samplers);
888                     FIXME("Expected vertex samplers + MAX_TEXTURES(=8) > combined_samplers\n");
889                     if( gl_info->max_combined_samplers > MAX_TEXTURES )
890                         gl_info->max_vertex_samplers =
891                             gl_info->max_combined_samplers - MAX_TEXTURES;
892                     else
893                         gl_info->max_vertex_samplers = 0;
894                 }
895             } else {
896                 gl_info->max_combined_samplers = gl_info->max_fragment_samplers;
897             }
898             TRACE_(d3d_caps)("Max vertex samplers: %u\n", gl_info->max_vertex_samplers);
899             TRACE_(d3d_caps)("Max combined samplers: %u\n", gl_info->max_combined_samplers);
900         }
901         if (gl_info->supported[ARB_VERTEX_BLEND]) {
902             glGetIntegerv(GL_MAX_VERTEX_UNITS_ARB, &gl_max);
903             gl_info->max_blends = gl_max;
904             TRACE_(d3d_caps)("Max blends: %u\n", gl_info->max_blends);
905         }
906         if (gl_info->supported[EXT_TEXTURE3D]) {
907             glGetIntegerv(GL_MAX_3D_TEXTURE_SIZE_EXT, &gl_max);
908             gl_info->max_texture3d_size = gl_max;
909             TRACE_(d3d_caps)("Max texture3D size: %d\n", gl_info->max_texture3d_size);
910         }
911         if (gl_info->supported[EXT_TEXTURE_FILTER_ANISOTROPIC]) {
912             glGetIntegerv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &gl_max);
913             gl_info->max_anisotropy = gl_max;
914             TRACE_(d3d_caps)("Max anisotropy: %d\n", gl_info->max_anisotropy);
915         }
916         if (gl_info->supported[ARB_FRAGMENT_PROGRAM]) {
917             gl_info->ps_arb_version = PS_VERSION_11;
918             GL_EXTCALL(glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_ENV_PARAMETERS_ARB, &gl_max));
919             gl_info->ps_arb_constantsF = gl_max;
920             TRACE_(d3d_caps)("Max ARB_FRAGMENT_PROGRAM float constants: %d\n", gl_info->ps_arb_constantsF);
921             GL_EXTCALL(glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB, &gl_max));
922             gl_info->ps_arb_max_temps = gl_max;
923             TRACE_(d3d_caps)("Max ARB_FRAGMENT_PROGRAM native temporaries: %d\n", gl_info->ps_arb_max_temps);
924             GL_EXTCALL(glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB, &gl_max));
925             gl_info->ps_arb_max_instructions = gl_max;
926             TRACE_(d3d_caps)("Max ARB_FRAGMENT_PROGRAM native instructions: %d\n", gl_info->ps_arb_max_instructions);
927         }
928         if (gl_info->supported[ARB_VERTEX_PROGRAM]) {
929             gl_info->vs_arb_version = VS_VERSION_11;
930             GL_EXTCALL(glGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_MAX_PROGRAM_ENV_PARAMETERS_ARB, &gl_max));
931             gl_info->vs_arb_constantsF = gl_max;
932             TRACE_(d3d_caps)("Max ARB_VERTEX_PROGRAM float constants: %d\n", gl_info->vs_arb_constantsF);
933             GL_EXTCALL(glGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB, &gl_max));
934             gl_info->vs_arb_max_temps = gl_max;
935             TRACE_(d3d_caps)("Max ARB_VERTEX_PROGRAM native temporaries: %d\n", gl_info->vs_arb_max_temps);
936             GL_EXTCALL(glGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB, &gl_max));
937             gl_info->vs_arb_max_instructions = gl_max;
938             TRACE_(d3d_caps)("Max ARB_VERTEX_PROGRAM native instructions: %d\n", gl_info->vs_arb_max_instructions);
939
940             gl_info->arb_vs_offset_limit = test_arb_vs_offset_limit(gl_info);
941         }
942         if (gl_info->supported[ARB_VERTEX_SHADER]) {
943             glGetIntegerv(GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB, &gl_max);
944             gl_info->vs_glsl_constantsF = gl_max / 4;
945             TRACE_(d3d_caps)("Max ARB_VERTEX_SHADER float constants: %u\n", gl_info->vs_glsl_constantsF);
946         }
947         if (gl_info->supported[ARB_FRAGMENT_SHADER]) {
948             glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB, &gl_max);
949             gl_info->ps_glsl_constantsF = gl_max / 4;
950             TRACE_(d3d_caps)("Max ARB_FRAGMENT_SHADER float constants: %u\n", gl_info->ps_glsl_constantsF);
951             glGetIntegerv(GL_MAX_VARYING_FLOATS_ARB, &gl_max);
952             gl_info->max_glsl_varyings = gl_max;
953             TRACE_(d3d_caps)("Max GLSL varyings: %u (%u 4 component varyings)\n", gl_max, gl_max / 4);
954         }
955         if (gl_info->supported[EXT_VERTEX_SHADER]) {
956             gl_info->vs_ati_version = VS_VERSION_11;
957         }
958         if (gl_info->supported[NV_VERTEX_PROGRAM3]) {
959             gl_info->vs_nv_version = VS_VERSION_30;
960         } else if (gl_info->supported[NV_VERTEX_PROGRAM2]) {
961             gl_info->vs_nv_version = VS_VERSION_20;
962         } else if (gl_info->supported[NV_VERTEX_PROGRAM1_1]) {
963             gl_info->vs_nv_version = VS_VERSION_11;
964         } else if (gl_info->supported[NV_VERTEX_PROGRAM]) {
965             gl_info->vs_nv_version = VS_VERSION_10;
966         }
967         if (gl_info->supported[NV_FRAGMENT_PROGRAM2]) {
968             gl_info->ps_nv_version = PS_VERSION_30;
969         } else if (gl_info->supported[NV_FRAGMENT_PROGRAM]) {
970             gl_info->ps_nv_version = PS_VERSION_20;
971         }
972         if (gl_info->supported[NV_LIGHT_MAX_EXPONENT]) {
973             glGetFloatv(GL_MAX_SHININESS_NV, &gl_info->max_shininess);
974         } else {
975             gl_info->max_shininess = 128.0;
976         }
977         if (gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO]) {
978             /* If we have full NP2 texture support, disable GL_ARB_texture_rectangle because we will never use it.
979              * This saves a few redundant glDisable calls
980              */
981             gl_info->supported[ARB_TEXTURE_RECTANGLE] = FALSE;
982         }
983         if(gl_info->supported[ATI_FRAGMENT_SHADER]) {
984             /* Disable NV_register_combiners and fragment shader if this is supported.
985              * generally the NV extensions are prefered over the ATI one, and this
986              * extension is disabled if register_combiners and texture_shader2 are both
987              * supported. So we reach this place only if we have incomplete NV dxlevel 8
988              * fragment processing support
989              */
990             gl_info->supported[NV_REGISTER_COMBINERS] = FALSE;
991             gl_info->supported[NV_REGISTER_COMBINERS2] = FALSE;
992             gl_info->supported[NV_TEXTURE_SHADER] = FALSE;
993             gl_info->supported[NV_TEXTURE_SHADER2] = FALSE;
994             gl_info->supported[NV_TEXTURE_SHADER3] = FALSE;
995         }
996
997     }
998     checkGLcall("extension detection\n");
999
1000     /* In some cases the number of texture stages can be larger than the number
1001      * of samplers. The GF4 for example can use only 2 samplers (no fragment
1002      * shaders), but 8 texture stages (register combiners). */
1003     gl_info->max_sampler_stages = max(gl_info->max_fragment_samplers, gl_info->max_texture_stages);
1004
1005     /* We can only use ORM_FBO when the hardware supports it. */
1006     if (wined3d_settings.offscreen_rendering_mode == ORM_FBO && !gl_info->supported[EXT_FRAMEBUFFER_OBJECT]) {
1007         WARN_(d3d_caps)("GL_EXT_framebuffer_object not supported, falling back to PBuffer offscreen rendering mode.\n");
1008         wined3d_settings.offscreen_rendering_mode = ORM_PBUFFER;
1009     }
1010
1011     /* MRTs are currently only supported when FBOs are used. */
1012     if (wined3d_settings.offscreen_rendering_mode != ORM_FBO) {
1013         gl_info->max_buffers = 1;
1014     }
1015
1016     /* Below is a list of Nvidia and ATI GPUs. Both vendors have dozens of different GPUs with roughly the same
1017      * features. In most cases GPUs from a certain family differ in clockspeeds, the amount of video memory and
1018      * in case of the latest videocards in the number of pixel/vertex pipelines.
1019      *
1020      * A Direct3D device object contains the PCI id (vendor + device) of the videocard which is used for
1021      * rendering. Various games use this information to get a rough estimation of the features of the card
1022      * and some might use it for enabling 3d effects only on certain types of videocards. In some cases
1023      * games might even use it to work around bugs which happen on certain videocards/driver combinations.
1024      * The problem is that OpenGL only exposes a rendering string containing the name of the videocard and
1025      * not the PCI id.
1026      *
1027      * Various games depend on the PCI id, so somehow we need to provide one. A simple option is to parse
1028      * the renderer string and translate this to the right PCI id. This is a lot of work because there are more
1029      * than 200 GPUs just for Nvidia. Various cards share the same renderer string, so the amount of code might
1030      * be 'small' but there are quite a number of exceptions which would make this a pain to maintain.
1031      * Another way would be to query the PCI id from the operating system (assuming this is the videocard which
1032      * is used for rendering which is not always the case). This would work but it is not very portable. Second
1033      * it would not work well in, let's say, a remote X situation in which the amount of 3d features which can be used
1034      * is limited.
1035      *
1036      * As said most games only use the PCI id to get an indication of the capabilities of the card.
1037      * It doesn't really matter if the given id is the correct one if we return the id of a card with
1038      * similar 3d features.
1039      *
1040      * The code below checks the OpenGL capabilities of a videocard and matches that to a certain level of
1041      * Direct3D functionality. Once a card passes the Direct3D9 check, we know that the card (in case of Nvidia)
1042      * is at least a GeforceFX. To give a better estimate we do a basic check on the renderer string but if that
1043      * won't pass we return a default card. This way is better than maintaining a full card database as even
1044      * without a full database we can return a card with similar features. Second the size of the database
1045      * can be made quite small because when you know what type of 3d functionality a card has, you know to which
1046      * GPU family the GPU must belong. Because of this you only have to check a small part of the renderer string
1047      * to distinguishes between different models from that family.
1048      *
1049      * The code also selects a default amount of video memory which we will use for an estimation of the amount
1050      * of free texture memory. In case of real D3D the amount of texture memory includes video memory and system
1051      * memory (to be specific AGP memory or in case of PCIE TurboCache/HyperMemory). We don't know how much
1052      * system memory can be addressed by the system but we can make a reasonable estimation about the amount of
1053      * video memory. If the value is slightly wrong it doesn't matter as we didn't include AGP-like memory which
1054      * makes the amount of addressable memory higher and second OpenGL isn't that critical it moves to system
1055      * memory behind our backs if really needed.
1056      * Note that the amount of video memory can be overruled using a registry setting.
1057      */
1058     switch (gl_info->gl_vendor) {
1059         case VENDOR_NVIDIA:
1060             /* Both the GeforceFX, 6xxx and 7xxx series support D3D9. The last two types have more
1061              * shader capabilities, so we use the shader capabilities to distinguish between FX and 6xxx/7xxx.
1062              */
1063             if(WINE_D3D9_CAPABLE(gl_info) && (gl_info->vs_nv_version == VS_VERSION_30)) {
1064                 /* Geforce8 - highend */
1065                 if (strstr(gl_info->gl_renderer, "8800")) {
1066                     gl_info->gl_card = CARD_NVIDIA_GEFORCE_8800GTS;
1067                     vidmem = 320; /* The 8800GTS uses 320MB, a 8800GTX can have 768MB */
1068                 }
1069                 /* Geforce8 - midend mobile */
1070                 else if(strstr(gl_info->gl_renderer, "8600 M")) {
1071                     gl_info->gl_card = CARD_NVIDIA_GEFORCE_8600MGT;
1072                     vidmem = 512;
1073                 }
1074                 /* Geforce8 - midend */
1075                 else if(strstr(gl_info->gl_renderer, "8600") ||
1076                         strstr(gl_info->gl_renderer, "8700"))
1077                 {
1078                     gl_info->gl_card = CARD_NVIDIA_GEFORCE_8600GT;
1079                     vidmem = 256;
1080                 }
1081                 /* Geforce8 - lowend */
1082                 else if(strstr(gl_info->gl_renderer, "8300") ||
1083                         strstr(gl_info->gl_renderer, "8400") ||
1084                         strstr(gl_info->gl_renderer, "8500"))
1085                 {
1086                     gl_info->gl_card = CARD_NVIDIA_GEFORCE_8300GS;
1087                     vidmem = 128; /* 128-256MB for a 8300, 256-512MB for a 8400 */
1088                 }
1089                 /* Geforce7 - highend */
1090                 else if(strstr(gl_info->gl_renderer, "7800") ||
1091                         strstr(gl_info->gl_renderer, "7900") ||
1092                         strstr(gl_info->gl_renderer, "7950") ||
1093                         strstr(gl_info->gl_renderer, "Quadro FX 4") ||
1094                         strstr(gl_info->gl_renderer, "Quadro FX 5"))
1095                 {
1096                     gl_info->gl_card = CARD_NVIDIA_GEFORCE_7800GT;
1097                     vidmem = 256; /* A 7800GT uses 256MB while highend 7900 cards can use 512MB */
1098                 }
1099                 /* Geforce7 midend */
1100                 else if(strstr(gl_info->gl_renderer, "7600") ||
1101                         strstr(gl_info->gl_renderer, "7700")) {
1102                     gl_info->gl_card = CARD_NVIDIA_GEFORCE_7600;
1103                     vidmem = 256; /* The 7600 uses 256-512MB */
1104                 /* Geforce7 lower medium */
1105                 } else if(strstr(gl_info->gl_renderer, "7400")) {
1106                     gl_info->gl_card = CARD_NVIDIA_GEFORCE_7400;
1107                     vidmem = 256; /* The 7400 uses 256-512MB */
1108                 }
1109                 /* Geforce7 lowend */
1110                 else if(strstr(gl_info->gl_renderer, "7300")) {
1111                     gl_info->gl_card = CARD_NVIDIA_GEFORCE_7300;
1112                     vidmem = 256; /* Mac Pros with this card have 256 MB */
1113                 }
1114                 /* Geforce6 highend */
1115                 else if(strstr(gl_info->gl_renderer, "6800"))
1116                 {
1117                     gl_info->gl_card = CARD_NVIDIA_GEFORCE_6800;
1118                     vidmem = 128; /* The 6800 uses 128-256MB, the 7600 uses 256-512MB */
1119                 }
1120                 /* Geforce6 - midend */
1121                 else if(strstr(gl_info->gl_renderer, "6600") ||
1122                         strstr(gl_info->gl_renderer, "6610") ||
1123                         strstr(gl_info->gl_renderer, "6700"))
1124                 {
1125                     gl_info->gl_card = CARD_NVIDIA_GEFORCE_6600GT;
1126                     vidmem = 128; /* A 6600GT has 128-256MB */
1127                 }
1128                 /* Geforce6/7 lowend */
1129                 else {
1130                     gl_info->gl_card = CARD_NVIDIA_GEFORCE_6200; /* Geforce 6100/6150/6200/7300/7400/7500 */
1131                     vidmem = 64; /* */
1132                 }
1133             } else if(WINE_D3D9_CAPABLE(gl_info)) {
1134                 /* GeforceFX - highend */
1135                 if (strstr(gl_info->gl_renderer, "5800") ||
1136                     strstr(gl_info->gl_renderer, "5900") ||
1137                     strstr(gl_info->gl_renderer, "5950") ||
1138                     strstr(gl_info->gl_renderer, "Quadro FX"))
1139                 {
1140                     gl_info->gl_card = CARD_NVIDIA_GEFORCEFX_5800;
1141                     vidmem = 256; /* 5800-5900 cards use 256MB */
1142                 }
1143                 /* GeforceFX - midend */
1144                 else if(strstr(gl_info->gl_renderer, "5600") ||
1145                         strstr(gl_info->gl_renderer, "5650") ||
1146                         strstr(gl_info->gl_renderer, "5700") ||
1147                         strstr(gl_info->gl_renderer, "5750"))
1148                 {
1149                     gl_info->gl_card = CARD_NVIDIA_GEFORCEFX_5600;
1150                     vidmem = 128; /* A 5600 uses 128-256MB */
1151                 }
1152                 /* GeforceFX - lowend */
1153                 else {
1154                     gl_info->gl_card = CARD_NVIDIA_GEFORCEFX_5200; /* GeforceFX 5100/5200/5250/5300/5500 */
1155                     vidmem = 64; /* Normal FX5200 cards use 64-256MB; laptop (non-standard) can have less */
1156                 }
1157             } else if(WINE_D3D8_CAPABLE(gl_info)) {
1158                 if (strstr(gl_info->gl_renderer, "GeForce4 Ti") || strstr(gl_info->gl_renderer, "Quadro4")) {
1159                     gl_info->gl_card = CARD_NVIDIA_GEFORCE4_TI4200; /* Geforce4 Ti4200/Ti4400/Ti4600/Ti4800, Quadro4 */
1160                     vidmem = 64; /* Geforce4 Ti cards have 64-128MB */
1161                 }
1162                 else {
1163                     gl_info->gl_card = CARD_NVIDIA_GEFORCE3; /* Geforce3 standard/Ti200/Ti500, Quadro DCC */
1164                     vidmem = 64; /* Geforce3 cards have 64-128MB */
1165                 }
1166             } else if(WINE_D3D7_CAPABLE(gl_info)) {
1167                 if (strstr(gl_info->gl_renderer, "GeForce4 MX")) {
1168                     gl_info->gl_card = CARD_NVIDIA_GEFORCE4_MX; /* MX420/MX440/MX460/MX4000 */
1169                     vidmem = 64; /* Most Geforce4MX GPUs have at least 64MB of memory, some early models had 32MB but most have 64MB or even 128MB */
1170                 }
1171                 else if(strstr(gl_info->gl_renderer, "GeForce2 MX") || strstr(gl_info->gl_renderer, "Quadro2 MXR")) {
1172                     gl_info->gl_card = CARD_NVIDIA_GEFORCE2_MX; /* Geforce2 standard/MX100/MX200/MX400, Quadro2 MXR */
1173                     vidmem = 32; /* Geforce2MX GPUs have 32-64MB of video memory */
1174                 }
1175                 else if(strstr(gl_info->gl_renderer, "GeForce2") || strstr(gl_info->gl_renderer, "Quadro2")) {
1176                     gl_info->gl_card = CARD_NVIDIA_GEFORCE2; /* Geforce2 GTS/Pro/Ti/Ultra, Quadro2 */
1177                     vidmem = 32; /* Geforce2 GPUs have 32-64MB of video memory */
1178                 }
1179                 else {
1180                     gl_info->gl_card = CARD_NVIDIA_GEFORCE; /* Geforce 256/DDR, Quadro */
1181                     vidmem = 32; /* Most Geforce1 cards have 32MB, there are also some rare 16 and 64MB (Dell) models */
1182                 }
1183             } else {
1184                 if (strstr(gl_info->gl_renderer, "TNT2")) {
1185                     gl_info->gl_card = CARD_NVIDIA_RIVA_TNT2; /* Riva TNT2 standard/M64/Pro/Ultra */
1186                     vidmem = 32; /* Most TNT2 boards have 32MB, though there are 16MB boards too */
1187                 }
1188                 else {
1189                     gl_info->gl_card = CARD_NVIDIA_RIVA_TNT; /* Riva TNT, Vanta */
1190                     vidmem = 16; /* Most TNT boards have 16MB, some rare models have 8MB */
1191                 }
1192             }
1193             break;
1194         case VENDOR_ATI:
1195             if(WINE_D3D9_CAPABLE(gl_info)) {
1196                 /* Radeon R6xx HD2900 - highend */
1197                 if (strstr(gl_info->gl_renderer, "HD 2900")) {
1198                     gl_info->gl_card = CARD_ATI_RADEON_HD2900;
1199                     vidmem = 512; /* HD2900 uses 512-1024MB */
1200                 }
1201                 /* Radeon R6xx HD2600- midend */
1202                 else if (strstr(gl_info->gl_renderer, "HD 2600")) {
1203                     gl_info->gl_card = CARD_ATI_RADEON_HD2600;
1204                     vidmem = 256; /* HD2600 uses 256-512MB */
1205                 }
1206                 /* Radeon R6xx HD2300/HD2400 - lowend */
1207                 else if (strstr(gl_info->gl_renderer, "HD 2300") ||
1208                          strstr(gl_info->gl_renderer, "HD 2400"))
1209                 {
1210                     gl_info->gl_card = CARD_ATI_RADEON_HD2300;
1211                     vidmem = 128; /* HD2300 uses at least 128MB, HD2400 uses 256MB */
1212                 }
1213                 /* Radeon R5xx */
1214                 else if (strstr(gl_info->gl_renderer, "X1600") ||
1215                          strstr(gl_info->gl_renderer, "X1650") ||
1216                          strstr(gl_info->gl_renderer, "X1800") ||
1217                          strstr(gl_info->gl_renderer, "X1900") ||
1218                          strstr(gl_info->gl_renderer, "X1950"))
1219                 {
1220                     gl_info->gl_card = CARD_ATI_RADEON_X1600;
1221                     vidmem = 128; /* X1600 uses 128-256MB, >=X1800 uses 256MB */
1222                 }
1223                 /* Radeon R4xx + X1300/X1400/X1450/X1550/X2300 (lowend R5xx) */
1224                 else if(strstr(gl_info->gl_renderer, "X700") ||
1225                         strstr(gl_info->gl_renderer, "X800") ||
1226                         strstr(gl_info->gl_renderer, "X850") ||
1227                         strstr(gl_info->gl_renderer, "X1300") ||
1228                         strstr(gl_info->gl_renderer, "X1400") ||
1229                         strstr(gl_info->gl_renderer, "X1450") ||
1230                         strstr(gl_info->gl_renderer, "X1550"))
1231                 {
1232                     gl_info->gl_card = CARD_ATI_RADEON_X700;
1233                     vidmem = 128; /* x700/x8*0 use 128-256MB, >=x1300 128-512MB */
1234                 }
1235                 /* Radeon R3xx */ 
1236                 else {
1237                     gl_info->gl_card = CARD_ATI_RADEON_9500; /* Radeon 9500/9550/9600/9700/9800/X300/X550/X600 */
1238                     vidmem = 64; /* Radeon 9500 uses 64MB, higher models use up to 256MB */
1239                 }
1240             } else if(WINE_D3D8_CAPABLE(gl_info)) {
1241                 gl_info->gl_card = CARD_ATI_RADEON_8500; /* Radeon 8500/9000/9100/9200/9300 */
1242                 vidmem = 64; /* 8500/9000 cards use mostly 64MB, though there are 32MB and 128MB models */
1243             } else if(WINE_D3D7_CAPABLE(gl_info)) {
1244                 gl_info->gl_card = CARD_ATI_RADEON_7200; /* Radeon 7000/7100/7200/7500 */
1245                 vidmem = 32; /* There are models with up to 64MB */
1246             } else {
1247                 gl_info->gl_card = CARD_ATI_RAGE_128PRO;
1248                 vidmem = 16; /* There are 16-32MB models */
1249             }
1250             break;
1251         case VENDOR_INTEL:
1252             if (strstr(gl_info->gl_renderer, "GMA 950")) {
1253                 /* MacOS calls the card GMA 950, but everywhere else the PCI ID is named 945GM */
1254                 gl_info->gl_card = CARD_INTEL_I945GM;
1255                 vidmem = 64;
1256             } else if (strstr(gl_info->gl_renderer, "915GM")) {
1257                 gl_info->gl_card = CARD_INTEL_I915GM;
1258             } else if (strstr(gl_info->gl_renderer, "915G")) {
1259                 gl_info->gl_card = CARD_INTEL_I915G;
1260             } else if (strstr(gl_info->gl_renderer, "865G")) {
1261                 gl_info->gl_card = CARD_INTEL_I865G;
1262             } else if (strstr(gl_info->gl_renderer, "855G")) {
1263                 gl_info->gl_card = CARD_INTEL_I855G;
1264             } else if (strstr(gl_info->gl_renderer, "830G")) {
1265                 gl_info->gl_card = CARD_INTEL_I830G;
1266             } else {
1267                 gl_info->gl_card = CARD_INTEL_I915G;
1268             }
1269             break;
1270         case VENDOR_MESA:
1271         case VENDOR_WINE:
1272         default:
1273             /* Default to generic Nvidia hardware based on the supported OpenGL extensions. The choice 
1274              * for Nvidia was because the hardware and drivers they make are of good quality. This makes
1275              * them a good generic choice.
1276              */
1277             gl_info->gl_vendor = VENDOR_NVIDIA;
1278             if(WINE_D3D9_CAPABLE(gl_info))
1279                 gl_info->gl_card = CARD_NVIDIA_GEFORCEFX_5600;
1280             else if(WINE_D3D8_CAPABLE(gl_info))
1281                 gl_info->gl_card = CARD_NVIDIA_GEFORCE3;
1282             else if(WINE_D3D7_CAPABLE(gl_info))
1283                 gl_info->gl_card = CARD_NVIDIA_GEFORCE;
1284             else if(WINE_D3D6_CAPABLE(gl_info))
1285                 gl_info->gl_card = CARD_NVIDIA_RIVA_TNT;
1286             else
1287                 gl_info->gl_card = CARD_NVIDIA_RIVA_128;
1288     }
1289     TRACE_(d3d_caps)("FOUND (fake) card: 0x%x (vendor id), 0x%x (device id)\n", gl_info->gl_vendor, gl_info->gl_card);
1290
1291     /* If we have an estimate use it, else default to 64MB;  */
1292     if(vidmem)
1293         gl_info->vidmem = vidmem*1024*1024; /* convert from MBs to bytes */
1294     else
1295         gl_info->vidmem = WINE_DEFAULT_VIDMEM;
1296
1297     /* Load all the lookup tables
1298     TODO: It may be a good idea to make minLookup and maxLookup const and populate them in wined3d_private.h where they are declared */
1299     minLookup[WINELOOKUP_WARPPARAM] = WINED3DTADDRESS_WRAP;
1300     maxLookup[WINELOOKUP_WARPPARAM] = WINED3DTADDRESS_MIRRORONCE;
1301
1302     minLookup[WINELOOKUP_MAGFILTER] = WINED3DTEXF_NONE;
1303     maxLookup[WINELOOKUP_MAGFILTER] = WINED3DTEXF_ANISOTROPIC;
1304
1305
1306     for (i = 0; i < MAX_LOOKUPS; i++) {
1307         stateLookup[i] = HeapAlloc(GetProcessHeap(), 0, sizeof(*stateLookup[i]) * (1 + maxLookup[i] - minLookup[i]) );
1308     }
1309
1310     stateLookup[WINELOOKUP_WARPPARAM][WINED3DTADDRESS_WRAP   - minLookup[WINELOOKUP_WARPPARAM]] = GL_REPEAT;
1311     stateLookup[WINELOOKUP_WARPPARAM][WINED3DTADDRESS_CLAMP  - minLookup[WINELOOKUP_WARPPARAM]] = GL_CLAMP_TO_EDGE;
1312     stateLookup[WINELOOKUP_WARPPARAM][WINED3DTADDRESS_BORDER - minLookup[WINELOOKUP_WARPPARAM]] =
1313              gl_info->supported[ARB_TEXTURE_BORDER_CLAMP] ? GL_CLAMP_TO_BORDER_ARB : GL_REPEAT;
1314     stateLookup[WINELOOKUP_WARPPARAM][WINED3DTADDRESS_BORDER - minLookup[WINELOOKUP_WARPPARAM]] =
1315              gl_info->supported[ARB_TEXTURE_BORDER_CLAMP] ? GL_CLAMP_TO_BORDER_ARB : GL_REPEAT;
1316     stateLookup[WINELOOKUP_WARPPARAM][WINED3DTADDRESS_MIRROR - minLookup[WINELOOKUP_WARPPARAM]] =
1317              gl_info->supported[ARB_TEXTURE_MIRRORED_REPEAT] ? GL_MIRRORED_REPEAT_ARB : GL_REPEAT;
1318     stateLookup[WINELOOKUP_WARPPARAM][WINED3DTADDRESS_MIRRORONCE - minLookup[WINELOOKUP_WARPPARAM]] =
1319              gl_info->supported[ATI_TEXTURE_MIRROR_ONCE] ? GL_MIRROR_CLAMP_TO_EDGE_ATI : GL_REPEAT;
1320
1321     stateLookup[WINELOOKUP_MAGFILTER][WINED3DTEXF_NONE        - minLookup[WINELOOKUP_MAGFILTER]]  = GL_NEAREST;
1322     stateLookup[WINELOOKUP_MAGFILTER][WINED3DTEXF_POINT       - minLookup[WINELOOKUP_MAGFILTER]] = GL_NEAREST;
1323     stateLookup[WINELOOKUP_MAGFILTER][WINED3DTEXF_LINEAR      - minLookup[WINELOOKUP_MAGFILTER]] = GL_LINEAR;
1324     stateLookup[WINELOOKUP_MAGFILTER][WINED3DTEXF_ANISOTROPIC - minLookup[WINELOOKUP_MAGFILTER]] =
1325              gl_info->supported[EXT_TEXTURE_FILTER_ANISOTROPIC] ? GL_LINEAR : GL_NEAREST;
1326
1327
1328     minMipLookup[WINED3DTEXF_NONE][WINED3DTEXF_NONE]     = GL_LINEAR;
1329     minMipLookup[WINED3DTEXF_NONE][WINED3DTEXF_POINT]    = GL_LINEAR;
1330     minMipLookup[WINED3DTEXF_NONE][WINED3DTEXF_LINEAR]   = GL_LINEAR;
1331     minMipLookup[WINED3DTEXF_POINT][WINED3DTEXF_NONE]    = GL_NEAREST;
1332     minMipLookup[WINED3DTEXF_POINT][WINED3DTEXF_POINT]   = GL_NEAREST_MIPMAP_NEAREST;
1333     minMipLookup[WINED3DTEXF_POINT][WINED3DTEXF_LINEAR]  = GL_NEAREST_MIPMAP_LINEAR;
1334     minMipLookup[WINED3DTEXF_LINEAR][WINED3DTEXF_NONE]   = GL_LINEAR;
1335     minMipLookup[WINED3DTEXF_LINEAR][WINED3DTEXF_POINT]  = GL_LINEAR_MIPMAP_NEAREST;
1336     minMipLookup[WINED3DTEXF_LINEAR][WINED3DTEXF_LINEAR] = GL_LINEAR_MIPMAP_LINEAR;
1337     minMipLookup[WINED3DTEXF_ANISOTROPIC][WINED3DTEXF_NONE]   = gl_info->supported[EXT_TEXTURE_FILTER_ANISOTROPIC] ?
1338     GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR;
1339     minMipLookup[WINED3DTEXF_ANISOTROPIC][WINED3DTEXF_POINT]  = gl_info->supported[EXT_TEXTURE_FILTER_ANISOTROPIC] ? GL_LINEAR_MIPMAP_NEAREST : GL_LINEAR;
1340     minMipLookup[WINED3DTEXF_ANISOTROPIC][WINED3DTEXF_LINEAR] = gl_info->supported[EXT_TEXTURE_FILTER_ANISOTROPIC] ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR;
1341
1342 /* TODO: config lookups */
1343
1344     /* Make sure there's an active HDC else the WGL extensions will fail */
1345     hdc = pwglGetCurrentDC();
1346     if (hdc) {
1347         WGL_Extensions = GL_EXTCALL(wglGetExtensionsStringARB(hdc));
1348         TRACE_(d3d_caps)("WGL_Extensions reported:\n");
1349
1350         if (NULL == WGL_Extensions) {
1351             ERR("   WGL_Extensions returns NULL\n");
1352         } else {
1353             while (*WGL_Extensions != 0x00) {
1354                 const char *Start;
1355                 char ThisExtn[256];
1356                 size_t len;
1357
1358                 while (isspace(*WGL_Extensions)) WGL_Extensions++;
1359                 Start = WGL_Extensions;
1360                 while (!isspace(*WGL_Extensions) && *WGL_Extensions != 0x00) {
1361                     WGL_Extensions++;
1362                 }
1363
1364                 len = WGL_Extensions - Start;
1365                 if (len == 0 || len >= sizeof(ThisExtn))
1366                     continue;
1367
1368                 memcpy(ThisExtn, Start, len);
1369                 ThisExtn[len] = '\0';
1370                 TRACE_(d3d_caps)("- %s\n", ThisExtn);
1371
1372                 if (!strcmp(ThisExtn, "WGL_ARB_pbuffer")) {
1373                     gl_info->supported[WGL_ARB_PBUFFER] = TRUE;
1374                     TRACE_(d3d_caps)("FOUND: WGL_ARB_pbuffer support\n");
1375                 }
1376             }
1377         }
1378     }
1379     LEAVE_GL();
1380
1381     return return_value;
1382 }
1383 #undef GLINFO_LOCATION
1384
1385 /**********************************************************
1386  * IWineD3D implementation follows
1387  **********************************************************/
1388
1389 static UINT     WINAPI IWineD3DImpl_GetAdapterCount (IWineD3D *iface) {
1390     IWineD3DImpl *This = (IWineD3DImpl *)iface;
1391
1392     TRACE_(d3d_caps)("(%p): Reporting %d adapters\n", This, numAdapters);
1393     return numAdapters;
1394 }
1395
1396 static HRESULT  WINAPI IWineD3DImpl_RegisterSoftwareDevice(IWineD3D *iface, void* pInitializeFunction) {
1397     IWineD3DImpl *This = (IWineD3DImpl *)iface;
1398     FIXME("(%p)->(%p): stub\n", This, pInitializeFunction);
1399     return WINED3D_OK;
1400 }
1401
1402 static HMONITOR WINAPI IWineD3DImpl_GetAdapterMonitor(IWineD3D *iface, UINT Adapter) {
1403     IWineD3DImpl *This = (IWineD3DImpl *)iface;
1404
1405     if (Adapter >= IWineD3DImpl_GetAdapterCount(iface)) {
1406         return NULL;
1407     }
1408
1409     TRACE_(d3d_caps)("(%p)->(%d)\n", This, Adapter);
1410     return MonitorFromPoint(Adapters[Adapter].monitorPoint, MONITOR_DEFAULTTOPRIMARY);
1411 }
1412
1413 /* FIXME: GetAdapterModeCount and EnumAdapterModes currently only returns modes
1414      of the same bpp but different resolutions                                  */
1415
1416 /* Note: dx9 supplies a format. Calls from d3d8 supply WINED3DFMT_UNKNOWN */
1417 static UINT     WINAPI IWineD3DImpl_GetAdapterModeCount(IWineD3D *iface, UINT Adapter, WINED3DFORMAT Format) {
1418     IWineD3DImpl *This = (IWineD3DImpl *)iface;
1419     TRACE_(d3d_caps)("(%p}->(Adapter: %d, Format: %s)\n", This, Adapter, debug_d3dformat(Format));
1420
1421     if (Adapter >= IWineD3D_GetAdapterCount(iface)) {
1422         return 0;
1423     }
1424
1425     /* TODO: Store modes per adapter and read it from the adapter structure */
1426     if (Adapter == 0) { /* Display */
1427         int i = 0;
1428         int j = 0;
1429
1430         if (!DEBUG_SINGLE_MODE) {
1431             DEVMODEW DevModeW;
1432
1433             ZeroMemory(&DevModeW, sizeof(DevModeW));
1434             DevModeW.dmSize = sizeof(DevModeW);
1435             while (EnumDisplaySettingsExW(NULL, j, &DevModeW, 0)) {
1436                 j++;
1437                 switch (Format)
1438                 {
1439                     case WINED3DFMT_UNKNOWN:
1440                         /* This is for D3D8, do not enumerate P8 here */
1441                         if (DevModeW.dmBitsPerPel == 32 ||
1442                             DevModeW.dmBitsPerPel == 16) i++;
1443                         break;
1444                     case WINED3DFMT_X8R8G8B8:
1445                         if (DevModeW.dmBitsPerPel == 32) i++;
1446                         break;
1447                     case WINED3DFMT_R5G6B5:
1448                         if (DevModeW.dmBitsPerPel == 16) i++;
1449                         break;
1450                     case WINED3DFMT_P8:
1451                         if (DevModeW.dmBitsPerPel == 8) i++;
1452                         break;
1453                     default:
1454                         /* Skip other modes as they do not match the requested format */
1455                         break;
1456                 }
1457             }
1458         } else {
1459             i = 1;
1460             j = 1;
1461         }
1462
1463         TRACE_(d3d_caps)("(%p}->(Adapter: %d) => %d (out of %d)\n", This, Adapter, i, j);
1464         return i;
1465     } else {
1466         FIXME_(d3d_caps)("Adapter not primary display\n");
1467     }
1468     return 0;
1469 }
1470
1471 /* Note: dx9 supplies a format. Calls from d3d8 supply WINED3DFMT_UNKNOWN */
1472 static HRESULT WINAPI IWineD3DImpl_EnumAdapterModes(IWineD3D *iface, UINT Adapter, WINED3DFORMAT Format, UINT Mode, WINED3DDISPLAYMODE* pMode) {
1473     IWineD3DImpl *This = (IWineD3DImpl *)iface;
1474     TRACE_(d3d_caps)("(%p}->(Adapter:%d, mode:%d, pMode:%p, format:%s)\n", This, Adapter, Mode, pMode, debug_d3dformat(Format));
1475
1476     /* Validate the parameters as much as possible */
1477     if (NULL == pMode ||
1478         Adapter >= IWineD3DImpl_GetAdapterCount(iface) ||
1479         Mode    >= IWineD3DImpl_GetAdapterModeCount(iface, Adapter, Format)) {
1480         return WINED3DERR_INVALIDCALL;
1481     }
1482
1483     /* TODO: Store modes per adapter and read it from the adapter structure */
1484     if (Adapter == 0 && !DEBUG_SINGLE_MODE) { /* Display */
1485         DEVMODEW DevModeW;
1486         int ModeIdx = 0;
1487         int i = 0;
1488         int j = 0;
1489
1490         ZeroMemory(&DevModeW, sizeof(DevModeW));
1491         DevModeW.dmSize = sizeof(DevModeW);
1492
1493         /* If we are filtering to a specific format (D3D9), then need to skip
1494            all unrelated modes, but if mode is irrelevant (D3D8), then we can
1495            just count through the ones with valid bit depths */
1496         while ((i<=Mode) && EnumDisplaySettingsExW(NULL, j++, &DevModeW, 0)) {
1497             switch (Format)
1498             {
1499                 case WINED3DFMT_UNKNOWN:
1500                     /* This is D3D8. Do not enumerate P8 here */
1501                     if (DevModeW.dmBitsPerPel == 32 ||
1502                         DevModeW.dmBitsPerPel == 16) i++;
1503                     break;
1504                 case WINED3DFMT_X8R8G8B8:
1505                     if (DevModeW.dmBitsPerPel == 32) i++;
1506                     break;
1507                 case WINED3DFMT_R5G6B5:
1508                     if (DevModeW.dmBitsPerPel == 16) i++;
1509                     break;
1510                 case WINED3DFMT_P8:
1511                     if (DevModeW.dmBitsPerPel == 8) i++;
1512                     break;
1513                 default:
1514                     /* Modes that don't match what we support can get an early-out */
1515                     TRACE_(d3d_caps)("Searching for %s, returning D3DERR_INVALIDCALL\n", debug_d3dformat(Format));
1516                     return WINED3DERR_INVALIDCALL;
1517             }
1518         }
1519
1520         if (i == 0) {
1521             TRACE_(d3d_caps)("No modes found for format (%x - %s)\n", Format, debug_d3dformat(Format));
1522             return WINED3DERR_INVALIDCALL;
1523         }
1524         ModeIdx = j - 1;
1525
1526         /* Now get the display mode via the calculated index */
1527         if (EnumDisplaySettingsExW(NULL, ModeIdx, &DevModeW, 0)) {
1528             pMode->Width        = DevModeW.dmPelsWidth;
1529             pMode->Height       = DevModeW.dmPelsHeight;
1530             pMode->RefreshRate  = WINED3DADAPTER_DEFAULT;
1531             if (DevModeW.dmFields & DM_DISPLAYFREQUENCY)
1532                 pMode->RefreshRate = DevModeW.dmDisplayFrequency;
1533
1534             if (Format == WINED3DFMT_UNKNOWN) {
1535                 pMode->Format = pixelformat_for_depth(DevModeW.dmBitsPerPel);
1536             } else {
1537                 pMode->Format = Format;
1538             }
1539         } else {
1540             TRACE_(d3d_caps)("Requested mode out of range %d\n", Mode);
1541             return WINED3DERR_INVALIDCALL;
1542         }
1543
1544         TRACE_(d3d_caps)("W %d H %d rr %d fmt (%x - %s) bpp %u\n", pMode->Width, pMode->Height,
1545                 pMode->RefreshRate, pMode->Format, debug_d3dformat(pMode->Format),
1546                 DevModeW.dmBitsPerPel);
1547
1548     } else if (DEBUG_SINGLE_MODE) {
1549         /* Return one setting of the format requested */
1550         if (Mode > 0) return WINED3DERR_INVALIDCALL;
1551         pMode->Width        = 800;
1552         pMode->Height       = 600;
1553         pMode->RefreshRate  = 60;
1554         pMode->Format       = (Format == WINED3DFMT_UNKNOWN) ? WINED3DFMT_X8R8G8B8 : Format;
1555     } else {
1556         FIXME_(d3d_caps)("Adapter not primary display\n");
1557     }
1558
1559     return WINED3D_OK;
1560 }
1561
1562 static HRESULT WINAPI IWineD3DImpl_GetAdapterDisplayMode(IWineD3D *iface, UINT Adapter, WINED3DDISPLAYMODE* pMode) {
1563     IWineD3DImpl *This = (IWineD3DImpl *)iface;
1564     TRACE_(d3d_caps)("(%p}->(Adapter: %d, pMode: %p)\n", This, Adapter, pMode);
1565
1566     if (NULL == pMode ||
1567         Adapter >= IWineD3D_GetAdapterCount(iface)) {
1568         return WINED3DERR_INVALIDCALL;
1569     }
1570
1571     if (Adapter == 0) { /* Display */
1572         int bpp = 0;
1573         DEVMODEW DevModeW;
1574
1575         ZeroMemory(&DevModeW, sizeof(DevModeW));
1576         DevModeW.dmSize = sizeof(DevModeW);
1577
1578         EnumDisplaySettingsExW(NULL, ENUM_CURRENT_SETTINGS, &DevModeW, 0);
1579         pMode->Width        = DevModeW.dmPelsWidth;
1580         pMode->Height       = DevModeW.dmPelsHeight;
1581         bpp                 = DevModeW.dmBitsPerPel;
1582         pMode->RefreshRate  = WINED3DADAPTER_DEFAULT;
1583         if (DevModeW.dmFields&DM_DISPLAYFREQUENCY)
1584         {
1585             pMode->RefreshRate = DevModeW.dmDisplayFrequency;
1586         }
1587
1588         pMode->Format = pixelformat_for_depth(bpp);
1589     } else {
1590         FIXME_(d3d_caps)("Adapter not primary display\n");
1591     }
1592
1593     TRACE_(d3d_caps)("returning w:%d, h:%d, ref:%d, fmt:%s\n", pMode->Width,
1594           pMode->Height, pMode->RefreshRate, debug_d3dformat(pMode->Format));
1595     return WINED3D_OK;
1596 }
1597
1598 /* NOTE: due to structure differences between dx8 and dx9 D3DADAPTER_IDENTIFIER,
1599    and fields being inserted in the middle, a new structure is used in place    */
1600 static HRESULT WINAPI IWineD3DImpl_GetAdapterIdentifier(IWineD3D *iface, UINT Adapter, DWORD Flags,
1601                                                    WINED3DADAPTER_IDENTIFIER* pIdentifier) {
1602     IWineD3DImpl *This = (IWineD3DImpl *)iface;
1603
1604     TRACE_(d3d_caps)("(%p}->(Adapter: %d, Flags: %x, pId=%p)\n", This, Adapter, Flags, pIdentifier);
1605
1606     if (Adapter >= IWineD3D_GetAdapterCount(iface)) {
1607         return WINED3DERR_INVALIDCALL;
1608     }
1609
1610     /* Return the information requested */
1611     TRACE_(d3d_caps)("device/Vendor Name and Version detection using FillGLCaps\n");
1612     strcpy(pIdentifier->Driver, Adapters[Adapter].driver);
1613     strcpy(pIdentifier->Description, Adapters[Adapter].description);
1614
1615     /* Note dx8 doesn't supply a DeviceName */
1616     if (NULL != pIdentifier->DeviceName) strcpy(pIdentifier->DeviceName, "\\\\.\\DISPLAY"); /* FIXME: May depend on desktop? */
1617     pIdentifier->DriverVersion->u.HighPart = Adapters[Adapter].gl_info.driver_version_hipart;
1618     pIdentifier->DriverVersion->u.LowPart = Adapters[Adapter].gl_info.driver_version;
1619     *(pIdentifier->VendorId) = Adapters[Adapter].gl_info.gl_vendor;
1620     *(pIdentifier->DeviceId) = Adapters[Adapter].gl_info.gl_card;
1621     *(pIdentifier->SubSysId) = 0;
1622     *(pIdentifier->Revision) = 0;
1623     *pIdentifier->DeviceIdentifier = IID_D3DDEVICE_D3DUID;
1624
1625     if (Flags & WINED3DENUM_NO_WHQL_LEVEL) {
1626         *(pIdentifier->WHQLLevel) = 0;
1627     } else {
1628         *(pIdentifier->WHQLLevel) = 1;
1629     }
1630
1631     return WINED3D_OK;
1632 }
1633
1634 static BOOL IWineD3DImpl_IsPixelFormatCompatibleWithRenderFmt(const WineD3D_PixelFormat *cfg, WINED3DFORMAT Format) {
1635     short redSize, greenSize, blueSize, alphaSize, colorBits;
1636
1637     if(!cfg)
1638         return FALSE;
1639
1640     if(cfg->iPixelType == WGL_TYPE_RGBA_ARB) { /* Integer RGBA formats */
1641         if(!getColorBits(Format, &redSize, &greenSize, &blueSize, &alphaSize, &colorBits)) {
1642             ERR("Unable to check compatibility for Format=%s\n", debug_d3dformat(Format));
1643             return FALSE;
1644         }
1645
1646         if(cfg->redSize < redSize)
1647             return FALSE;
1648
1649         if(cfg->greenSize < greenSize)
1650             return FALSE;
1651
1652         if(cfg->blueSize < blueSize)
1653             return FALSE;
1654
1655         if(cfg->alphaSize < alphaSize)
1656             return FALSE;
1657
1658         return TRUE;
1659     } else if(cfg->iPixelType == WGL_TYPE_RGBA_FLOAT_ARB) { /* Float RGBA formats; TODO: WGL_NV_float_buffer */
1660         if(Format == WINED3DFMT_R16F)
1661             return (cfg->redSize == 16 && cfg->greenSize == 0 && cfg->blueSize == 0 && cfg->alphaSize == 0);
1662         if(Format == WINED3DFMT_G16R16F)
1663             return (cfg->redSize == 16 && cfg->greenSize == 16 && cfg->blueSize == 0 && cfg->alphaSize == 0);
1664         if(Format == WINED3DFMT_A16B16G16R16F)
1665             return (cfg->redSize == 16 && cfg->greenSize == 16 && cfg->blueSize == 16 && cfg->alphaSize == 16);
1666         if(Format == WINED3DFMT_R32F)
1667             return (cfg->redSize == 32 && cfg->greenSize == 0 && cfg->blueSize == 0 && cfg->alphaSize == 0);
1668         if(Format == WINED3DFMT_G32R32F)
1669             return (cfg->redSize == 32 && cfg->greenSize == 32 && cfg->blueSize == 0 && cfg->alphaSize == 0);
1670         if(Format == WINED3DFMT_A32B32G32R32F)
1671             return (cfg->redSize == 32 && cfg->greenSize == 32 && cfg->blueSize == 32 && cfg->alphaSize == 32);
1672     } else {
1673         /* Probably a color index mode */
1674         return FALSE;
1675     }
1676
1677     return FALSE;
1678 }
1679
1680 static BOOL IWineD3DImpl_IsPixelFormatCompatibleWithDepthFmt(const WineD3D_PixelFormat *cfg, WINED3DFORMAT Format) {
1681     short depthSize, stencilSize;
1682     BOOL lockable = FALSE;
1683
1684     if(!cfg)
1685         return FALSE;
1686
1687     if(!getDepthStencilBits(Format, &depthSize, &stencilSize)) {
1688         ERR("Unable to check compatibility for Format=%s\n", debug_d3dformat(Format));
1689         return FALSE;
1690     }
1691
1692     if((Format == WINED3DFMT_D16_LOCKABLE) || (Format == WINED3DFMT_D32F_LOCKABLE))
1693         lockable = TRUE;
1694
1695     /* On some modern cards like the Geforce8/9 GLX doesn't offer some dephthstencil formats which D3D9 reports.
1696      * We can safely report 'compatible' formats (e.g. D24 can be used for D16) as long as we aren't dealing with
1697      * a lockable format. This also helps D3D <= 7 as they expect D16 which isn't offered without this on Geforce8 cards. */
1698     if(!(cfg->depthSize == depthSize || (!lockable && cfg->depthSize > depthSize)))
1699         return FALSE;
1700
1701     if(cfg->stencilSize != stencilSize)
1702         return FALSE;
1703
1704     return TRUE;
1705 }
1706
1707 static HRESULT WINAPI IWineD3DImpl_CheckDepthStencilMatch(IWineD3D *iface, UINT Adapter, WINED3DDEVTYPE DeviceType,
1708                                                    WINED3DFORMAT AdapterFormat,
1709                                                    WINED3DFORMAT RenderTargetFormat,
1710                                                    WINED3DFORMAT DepthStencilFormat) {
1711     IWineD3DImpl *This = (IWineD3DImpl *)iface;
1712     int nCfgs;
1713     WineD3D_PixelFormat *cfgs;
1714     int it;
1715
1716     WARN_(d3d_caps)("(%p)-> (STUB) (Adptr:%d, DevType:(%x,%s), AdptFmt:(%x,%s), RendrTgtFmt:(%x,%s), DepthStencilFmt:(%x,%s))\n",
1717            This, Adapter,
1718            DeviceType, debug_d3ddevicetype(DeviceType),
1719            AdapterFormat, debug_d3dformat(AdapterFormat),
1720            RenderTargetFormat, debug_d3dformat(RenderTargetFormat),
1721            DepthStencilFormat, debug_d3dformat(DepthStencilFormat));
1722
1723     if (Adapter >= IWineD3D_GetAdapterCount(iface)) {
1724         TRACE("(%p) Failed: Atapter (%u) higher than supported adapters (%u) returning WINED3DERR_INVALIDCALL\n", This, Adapter, IWineD3D_GetAdapterCount(iface));
1725         return WINED3DERR_INVALIDCALL;
1726     }
1727
1728     cfgs = Adapters[Adapter].cfgs;
1729     nCfgs = Adapters[Adapter].nCfgs;
1730     for (it = 0; it < nCfgs; ++it) {
1731         if (IWineD3DImpl_IsPixelFormatCompatibleWithRenderFmt(&cfgs[it], RenderTargetFormat)) {
1732             if (IWineD3DImpl_IsPixelFormatCompatibleWithDepthFmt(&cfgs[it], DepthStencilFormat)) {
1733                 TRACE_(d3d_caps)("(%p) : Formats matched\n", This);
1734                 return WINED3D_OK;
1735             }
1736         }
1737     }
1738     WARN_(d3d_caps)("unsupported format pair: %s and %s\n", debug_d3dformat(RenderTargetFormat), debug_d3dformat(DepthStencilFormat));
1739
1740     return WINED3DERR_NOTAVAILABLE;
1741 }
1742
1743 static HRESULT WINAPI IWineD3DImpl_CheckDeviceMultiSampleType(IWineD3D *iface, UINT Adapter, WINED3DDEVTYPE DeviceType, 
1744                                                        WINED3DFORMAT SurfaceFormat,
1745                                                        BOOL Windowed, WINED3DMULTISAMPLE_TYPE MultiSampleType, DWORD*   pQualityLevels) {
1746
1747     IWineD3DImpl *This = (IWineD3DImpl *)iface;
1748     TRACE_(d3d_caps)("(%p)-> (STUB) (Adptr:%d, DevType:(%x,%s), SurfFmt:(%x,%s), Win?%d, MultiSamp:%x, pQual:%p)\n",
1749           This,
1750           Adapter,
1751           DeviceType, debug_d3ddevicetype(DeviceType),
1752           SurfaceFormat, debug_d3dformat(SurfaceFormat),
1753           Windowed,
1754           MultiSampleType,
1755           pQualityLevels);
1756
1757     if (Adapter >= IWineD3D_GetAdapterCount(iface)) {
1758         return WINED3DERR_INVALIDCALL;
1759     }
1760
1761     /* TODO: Store in Adapter structure */
1762     if (pQualityLevels != NULL) {
1763         static int s_single_shot = 0;
1764         if (!s_single_shot) {
1765             FIXME("Quality levels unsupported at present\n");
1766             s_single_shot = 1;
1767         }
1768         *pQualityLevels = 1; /* Guess at a value! */
1769     }
1770
1771     if (WINED3DMULTISAMPLE_NONE == MultiSampleType) return WINED3D_OK;
1772     return WINED3DERR_NOTAVAILABLE;
1773 }
1774
1775 static HRESULT WINAPI IWineD3DImpl_CheckDeviceType(IWineD3D *iface, UINT Adapter, WINED3DDEVTYPE DeviceType,
1776                                             WINED3DFORMAT DisplayFormat, WINED3DFORMAT BackBufferFormat, BOOL Windowed) {
1777
1778     IWineD3DImpl *This = (IWineD3DImpl *)iface;
1779     HRESULT hr = WINED3DERR_NOTAVAILABLE;
1780     UINT nmodes;
1781
1782     TRACE_(d3d_caps)("(%p)-> (STUB) (Adptr:%d, CheckType:(%x,%s), DispFmt:(%x,%s), BackBuf:(%x,%s), Win?%d): stub\n",
1783           This,
1784           Adapter,
1785           DeviceType, debug_d3ddevicetype(DeviceType),
1786           DisplayFormat, debug_d3dformat(DisplayFormat),
1787           BackBufferFormat, debug_d3dformat(BackBufferFormat),
1788           Windowed);
1789
1790     if (Adapter >= IWineD3D_GetAdapterCount(iface)) {
1791         WARN_(d3d_caps)("Adapter >= IWineD3D_GetAdapterCount(iface), returning WINED3DERR_INVALIDCALL\n");
1792         return WINED3DERR_INVALIDCALL;
1793     }
1794
1795     /* The task of this function is to check whether a certain display / backbuffer format
1796      * combination is available on the given adapter. In fullscreen mode microsoft specified
1797      * that the display format shouldn't provide alpha and that ignoring alpha the backbuffer
1798      * and display format should match exactly.
1799      * In windowed mode format conversion can occur and this depends on the driver. When format
1800      * conversion is done, this function should nevertheless fail and applications need to use
1801      * CheckDeviceFormatConversion.
1802      * At the moment we assume that fullscreen and windowed have the same capabilities */
1803
1804     /* There are only 4 display formats */
1805     if(!((DisplayFormat == WINED3DFMT_R5G6B5) ||
1806          (DisplayFormat == WINED3DFMT_X1R5G5B5) ||
1807          (DisplayFormat == WINED3DFMT_X8R8G8B8) ||
1808          (DisplayFormat == WINED3DFMT_A2R10G10B10)))
1809     {
1810         TRACE_(d3d_caps)("Format %s unsupported as display format\n", debug_d3dformat(DisplayFormat));
1811         return WINED3DERR_NOTAVAILABLE;
1812     }
1813
1814     /* If the requested DisplayFormat is not available, don't continue */
1815     nmodes = IWineD3DImpl_GetAdapterModeCount(iface, Adapter, DisplayFormat);
1816     if(!nmodes) {
1817         TRACE_(d3d_caps)("No available modes for display format %s\n", debug_d3dformat(DisplayFormat));
1818         return WINED3DERR_NOTAVAILABLE;
1819     }
1820
1821     /* Windowed mode allows you to specify WINED3DFMT_UNKNOWN for the backbufferformat, it means 'reuse' the display format for the backbuffer */
1822     if(!Windowed && BackBufferFormat == WINED3DFMT_UNKNOWN) {
1823         TRACE_(d3d_caps)("BackBufferFormat WINED3FMT_UNKNOWN not available in Windowed mode\n");
1824         return WINED3DERR_NOTAVAILABLE;
1825     }
1826
1827     /* In FULLSCREEN mode R5G6B5 can only be mixed with backbuffer format R5G6B5 */
1828     if( (DisplayFormat == WINED3DFMT_R5G6B5) && (BackBufferFormat != WINED3DFMT_R5G6B5) ) {
1829         TRACE_(d3d_caps)("Unsupported display/backbuffer format combination %s/%s\n", debug_d3dformat(DisplayFormat), debug_d3dformat(BackBufferFormat));
1830         return WINED3DERR_NOTAVAILABLE;
1831     }
1832
1833     /* In FULLSCREEN mode X1R5G5B5 can only be mixed with backbuffer format *1R5G5B5 */
1834     if( (DisplayFormat == WINED3DFMT_X1R5G5B5) && !((BackBufferFormat == WINED3DFMT_X1R5G5B5) || (BackBufferFormat == WINED3DFMT_A1R5G5B5)) ) {
1835         TRACE_(d3d_caps)("Unsupported display/backbuffer format combination %s/%s\n", debug_d3dformat(DisplayFormat), debug_d3dformat(BackBufferFormat));
1836         return WINED3DERR_NOTAVAILABLE;
1837     }
1838
1839     /* In FULLSCREEN mode X8R8G8B8 can only be mixed with backbuffer format *8R8G8B8 */
1840     if( (DisplayFormat == WINED3DFMT_X8R8G8B8) && !((BackBufferFormat == WINED3DFMT_X8R8G8B8) || (BackBufferFormat == WINED3DFMT_A8R8G8B8)) ) {
1841         TRACE_(d3d_caps)("Unsupported display/backbuffer format combination %s/%s\n", debug_d3dformat(DisplayFormat), debug_d3dformat(BackBufferFormat));
1842         return WINED3DERR_NOTAVAILABLE;
1843     }
1844
1845     /* A2R10G10B10 is only allowed in fullscreen mode and it can only be mixed with backbuffer format A2R10G10B10 */
1846     if( (DisplayFormat == WINED3DFMT_A2R10G10B10) && ((BackBufferFormat != WINED3DFMT_A2R10G10B10) || Windowed)) {
1847         TRACE_(d3d_caps)("Unsupported display/backbuffer format combination %s/%s\n", debug_d3dformat(DisplayFormat), debug_d3dformat(BackBufferFormat));
1848         return WINED3DERR_NOTAVAILABLE;
1849     }
1850
1851     /* Use CheckDeviceFormat to see if the BackBufferFormat is usable with the given DisplayFormat */
1852     hr = IWineD3DImpl_CheckDeviceFormat(iface, Adapter, DeviceType, DisplayFormat, WINED3DUSAGE_RENDERTARGET, WINED3DRTYPE_SURFACE, BackBufferFormat);
1853     if(FAILED(hr))
1854         TRACE_(d3d_caps)("Unsupported display/backbuffer format combination %s/%s\n", debug_d3dformat(DisplayFormat), debug_d3dformat(BackBufferFormat));
1855
1856     return hr;
1857 }
1858
1859
1860 #define GLINFO_LOCATION Adapters[Adapter].gl_info
1861 /* Check if we support bumpmapping for a format */
1862 static BOOL CheckBumpMapCapability(UINT Adapter, WINED3DFORMAT CheckFormat)
1863 {
1864     if(GL_SUPPORT(NV_REGISTER_COMBINERS) && GL_SUPPORT(NV_TEXTURE_SHADER2)) {
1865         switch (CheckFormat) {
1866             case WINED3DFMT_V8U8:
1867                 TRACE_(d3d_caps)("[OK]\n");
1868                 return TRUE;
1869             /* TODO: Other bump map formats */
1870             default:
1871                 TRACE_(d3d_caps)("[FAILED]\n");
1872                 return FALSE;
1873         }
1874     }
1875     if(GL_SUPPORT(ATI_ENVMAP_BUMPMAP) || GL_SUPPORT(ATI_FRAGMENT_SHADER)) {
1876         switch (CheckFormat) {
1877             case WINED3DFMT_V8U8:
1878                 TRACE_(d3d_caps)("[OK]\n");
1879                 return TRUE;
1880             default:
1881                 TRACE_(d3d_caps)("[FAILED]\n");
1882                 return FALSE;
1883         }
1884     }
1885     TRACE_(d3d_caps)("[FAILED]\n");
1886     return FALSE;
1887 }
1888
1889 /* Check if the given DisplayFormat + DepthStencilFormat combination is valid for the Adapter */
1890 static BOOL CheckDepthStencilCapability(UINT Adapter, WINED3DFORMAT DisplayFormat,
1891 WINED3DFORMAT DepthStencilFormat)
1892 {
1893     int it=0;
1894     WineD3D_PixelFormat *cfgs = Adapters[Adapter].cfgs;
1895
1896     /* Only allow depth/stencil formats */
1897     switch (DepthStencilFormat) {
1898         case WINED3DFMT_D16_LOCKABLE:
1899         case WINED3DFMT_D16:
1900         case WINED3DFMT_D15S1:
1901         case WINED3DFMT_D24X8:
1902         case WINED3DFMT_D24X4S4:
1903         case WINED3DFMT_D24S8:
1904         case WINED3DFMT_D24FS8:
1905         case WINED3DFMT_D32:
1906         case WINED3DFMT_D32F_LOCKABLE:
1907             break;
1908
1909         default:
1910             return FALSE;
1911     }
1912
1913     /* Walk through all WGL pixel formats to find a match */
1914     cfgs = Adapters[Adapter].cfgs;
1915     for (it = 0; it < Adapters[Adapter].nCfgs; ++it) {
1916         if (IWineD3DImpl_IsPixelFormatCompatibleWithRenderFmt(&cfgs[it], DisplayFormat)) {
1917             if (IWineD3DImpl_IsPixelFormatCompatibleWithDepthFmt(&cfgs[it], DepthStencilFormat)) {
1918                 return TRUE;
1919             }
1920         }
1921     }
1922
1923     return FALSE;
1924 }
1925
1926 static BOOL CheckFilterCapability(WINED3DFORMAT CheckFormat)
1927 {
1928     switch (CheckFormat) {
1929         /* Filtering not supported */
1930         case WINED3DFMT_R32F:
1931         case WINED3DFMT_A32B32G32R32F:
1932             TRACE_(d3d_caps)("[FAILED]\n");
1933             return FALSE;
1934         default:
1935             break;
1936     }
1937
1938     return TRUE;
1939 }
1940
1941 /* Check the render target capabilities of a format */
1942 static BOOL CheckRenderTargetCapability(WINED3DFORMAT AdapterFormat, WINED3DFORMAT CheckFormat)
1943 {
1944     UINT Adapter = 0;
1945
1946     /* Filter out non-RT formats */
1947     switch(CheckFormat)
1948     {
1949         /* Don't offer 8bit, windows doesn't either although we could emulate it */
1950         case WINED3DFMT_A8P8:
1951         case WINED3DFMT_P8:
1952
1953         /* No DXTC render targets */
1954         case WINED3DFMT_DXT1:
1955         case WINED3DFMT_DXT2:
1956         case WINED3DFMT_DXT3:
1957         case WINED3DFMT_DXT4:
1958         case WINED3DFMT_DXT5:
1959             return FALSE;
1960         default:
1961             break;
1962     }
1963
1964     if(wined3d_settings.offscreen_rendering_mode == ORM_BACKBUFFER) {
1965         WineD3D_PixelFormat *cfgs = Adapters[Adapter].cfgs;
1966         int it;
1967         short AdapterRed, AdapterGreen, AdapterBlue, AdapterAlpha, AdapterTotalSize;
1968         short CheckRed, CheckGreen, CheckBlue, CheckAlpha, CheckTotalSize;
1969
1970         getColorBits(AdapterFormat, &AdapterRed, &AdapterGreen, &AdapterBlue, &AdapterAlpha, &AdapterTotalSize);
1971         getColorBits(CheckFormat, &CheckRed, &CheckGreen, &CheckBlue, &CheckAlpha, &CheckTotalSize);
1972
1973         /* In backbuffer mode the front and backbuffer share the same WGL pixelformat.
1974          * The format must match in RGB, alpha is allowed to be different. (Only the backbuffer can have alpha) */
1975         if(!((AdapterRed == CheckRed) && (AdapterGreen == CheckGreen) && (AdapterBlue == CheckBlue))) {
1976             TRACE_(d3d_caps)("[FAILED]\n");
1977             return FALSE;
1978         }
1979
1980         /* Check if there is a WGL pixel format matching the requirements, the format should also be window
1981          * drawable (not offscreen; e.g. Nvidia offers R5G6B5 for pbuffers even when X is running at 24bit) */
1982         for (it = 0; it < Adapters[Adapter].nCfgs; ++it) {
1983             if (cfgs[it].windowDrawable && IWineD3DImpl_IsPixelFormatCompatibleWithRenderFmt(&cfgs[it], CheckFormat)) {
1984                 TRACE_(d3d_caps)("iPixelFormat=%d is compatible with CheckFormat=%s\n", cfgs[it].iPixelFormat, debug_d3dformat(CheckFormat));
1985                 return TRUE;
1986             }
1987         }
1988     } else if(wined3d_settings.offscreen_rendering_mode == ORM_PBUFFER) {
1989         /* We can propably use this function in FBO mode too on some drivers to get some basic indication of the capabilities. */
1990         WineD3D_PixelFormat *cfgs = Adapters[Adapter].cfgs;
1991         int it;
1992
1993         /* Check if there is a WGL pixel format matching the requirements, the pixel format should also be usable with pbuffers */
1994         for (it = 0; it < Adapters[Adapter].nCfgs; ++it) {
1995             if (cfgs[it].pbufferDrawable && IWineD3DImpl_IsPixelFormatCompatibleWithRenderFmt(&cfgs[it], CheckFormat)) {
1996                 TRACE_(d3d_caps)("iPixelFormat=%d is compatible with CheckFormat=%s\n", cfgs[it].iPixelFormat, debug_d3dformat(CheckFormat));
1997                 return TRUE;
1998             }
1999         }
2000     } else if(wined3d_settings.offscreen_rendering_mode == ORM_FBO){
2001         /* For now return TRUE for FBOs until we have some proper checks.
2002          * Note that this function will only be called when the format is around for texturing. */
2003         return TRUE;
2004     }
2005     return FALSE;
2006 }
2007
2008 static BOOL CheckSrgbReadCapability(UINT Adapter, WINED3DFORMAT CheckFormat)
2009 {
2010     /* Check for supported sRGB formats (Texture loading and framebuffer) */
2011     if(!GL_SUPPORT(EXT_TEXTURE_SRGB)) {
2012         TRACE_(d3d_caps)("[FAILED] GL_EXT_texture_sRGB not supported\n");
2013         return FALSE;
2014     }
2015
2016     switch (CheckFormat) {
2017         case WINED3DFMT_A8R8G8B8:
2018         case WINED3DFMT_X8R8G8B8:
2019         case WINED3DFMT_A4R4G4B4:
2020         case WINED3DFMT_L8:
2021         case WINED3DFMT_A8L8:
2022         case WINED3DFMT_DXT1:
2023         case WINED3DFMT_DXT2:
2024         case WINED3DFMT_DXT3:
2025         case WINED3DFMT_DXT4:
2026         case WINED3DFMT_DXT5:
2027             TRACE_(d3d_caps)("[OK]\n");
2028             return TRUE;
2029
2030         default:
2031             TRACE_(d3d_caps)("[FAILED] Gamma texture format %s not supported.\n", debug_d3dformat(CheckFormat));
2032             return FALSE;
2033     }
2034     return FALSE;
2035 }
2036
2037 static BOOL CheckSrgbWriteCapability(UINT Adapter, WINED3DDEVTYPE DeviceType, WINED3DFORMAT CheckFormat)
2038 {
2039     /* Only offer SRGB writing on X8R8G8B8/A8R8G8B8 when we use ARB or GLSL shaders as we are
2040      * doing the color fixup in shaders.
2041      * Note Windows drivers (at least on the Geforce 8800) also offer this on R5G6B5. */
2042     if((CheckFormat == WINED3DFMT_X8R8G8B8) || (CheckFormat == WINED3DFMT_A8R8G8B8)) {
2043         int vs_selected_mode;
2044         int ps_selected_mode;
2045         select_shader_mode(&GLINFO_LOCATION, DeviceType, &ps_selected_mode, &vs_selected_mode);
2046
2047         if((ps_selected_mode == SHADER_ARB) || (ps_selected_mode == SHADER_GLSL)) {
2048             TRACE_(d3d_caps)("[OK]\n");
2049             return TRUE;
2050         }
2051     }
2052
2053     TRACE_(d3d_caps)("[FAILED] - no SRGB writing support on format=%s\n", debug_d3dformat(CheckFormat));
2054     return FALSE;
2055 }
2056
2057 /* Check if a texture format is supported on the given adapter */
2058 static BOOL CheckTextureCapability(UINT Adapter, WINED3DFORMAT CheckFormat)
2059 {
2060     switch (CheckFormat) {
2061
2062         /*****
2063          *  supported: RGB(A) formats
2064          */
2065         case WINED3DFMT_R8G8B8: /* Enable for dx7, blacklisted for 8 and 9 above */
2066         case WINED3DFMT_A8R8G8B8:
2067         case WINED3DFMT_X8R8G8B8:
2068         case WINED3DFMT_R5G6B5:
2069         case WINED3DFMT_X1R5G5B5:
2070         case WINED3DFMT_A1R5G5B5:
2071         case WINED3DFMT_A4R4G4B4:
2072         case WINED3DFMT_R3G3B2:
2073         case WINED3DFMT_A8:
2074         case WINED3DFMT_X4R4G4B4:
2075         case WINED3DFMT_A8B8G8R8:
2076         case WINED3DFMT_X8B8G8R8:
2077         case WINED3DFMT_A2R10G10B10:
2078         case WINED3DFMT_A2B10G10R10:
2079         case WINED3DFMT_G16R16:
2080             TRACE_(d3d_caps)("[OK]\n");
2081             return TRUE;
2082
2083         /*****
2084          *  supported: Palettized
2085          */
2086         case WINED3DFMT_P8:
2087             TRACE_(d3d_caps)("[OK]\n");
2088             return TRUE;
2089         /* No Windows driver offers A8P8, so don't offer it either */
2090         case WINED3DFMT_A8P8:
2091             return FALSE;
2092
2093         /*****
2094          *  Supported: (Alpha)-Luminance
2095          */
2096         case WINED3DFMT_L8:
2097         case WINED3DFMT_A8L8:
2098         case WINED3DFMT_A4L4:
2099         case WINED3DFMT_L16:
2100             TRACE_(d3d_caps)("[OK]\n");
2101             return TRUE;
2102
2103         /* Depth/stencil is handled using checkDepthStencilCapability, return FALSE here */
2104         case WINED3DFMT_D16_LOCKABLE:
2105         case WINED3DFMT_D16:
2106         case WINED3DFMT_D15S1:
2107         case WINED3DFMT_D24X8:
2108         case WINED3DFMT_D24X4S4:
2109         case WINED3DFMT_D24S8:
2110         case WINED3DFMT_D24FS8:
2111         case WINED3DFMT_D32:
2112         case WINED3DFMT_D32F_LOCKABLE:
2113             return FALSE;
2114
2115         /*****
2116          *  Not supported everywhere(depends on GL_ATI_envmap_bumpmap or
2117          *  GL_NV_texture_shader), but advertized to make apps happy.
2118          *  Enable some because games often fail when they are not available
2119          *  and are still playable even without bump mapping
2120          */
2121         case WINED3DFMT_V8U8:
2122             if(GL_SUPPORT(NV_TEXTURE_SHADER) || GL_SUPPORT(ATI_ENVMAP_BUMPMAP) ||
2123                GL_SUPPORT(ATI_FRAGMENT_SHADER)) {
2124                 return TRUE;
2125             }
2126             TRACE_(d3d_caps)("[FAILED] - No converted formats on volumes\n");
2127             return FALSE;
2128
2129         case WINED3DFMT_X8L8V8U8:
2130         case WINED3DFMT_L6V5U5:
2131             WARN_(d3d_caps)("[FAILED]\n");
2132             return FALSE;
2133
2134         case WINED3DFMT_Q8W8V8U8:
2135         case WINED3DFMT_V16U16:
2136             if(GL_SUPPORT(NV_TEXTURE_SHADER)) {
2137                 WARN_(d3d_caps)("[Not supported, but pretended to do]\n");
2138                 return TRUE;
2139             }
2140             TRACE_(d3d_caps)("[FAILED] - No converted formats on volumes\n");
2141             return FALSE;
2142
2143         /* Those are not advertized by the nvidia windows driver, and not
2144          * supported natively by GL_NV_texture_shader or GL_ATI_envmap_bumpmap.
2145          * WINED3DFMT_A2W10V10U10 could be loaded into shaders using the unsigned
2146          * ARGB format if needed
2147          */
2148         case WINED3DFMT_W11V11U10:
2149         case WINED3DFMT_A2W10V10U10:
2150             WARN_(d3d_caps)("[FAILED]\n");
2151             return FALSE;
2152
2153         case WINED3DFMT_DXT1:
2154         case WINED3DFMT_DXT2:
2155         case WINED3DFMT_DXT3:
2156         case WINED3DFMT_DXT4:
2157         case WINED3DFMT_DXT5:
2158             if (GL_SUPPORT(EXT_TEXTURE_COMPRESSION_S3TC)) {
2159                 TRACE_(d3d_caps)("[OK]\n");
2160                 return TRUE;
2161             }
2162             TRACE_(d3d_caps)("[FAILED]\n");
2163             return FALSE;
2164
2165
2166         /*****
2167          *  Odd formats - not supported
2168          */
2169         case WINED3DFMT_VERTEXDATA:
2170         case WINED3DFMT_INDEX16:
2171         case WINED3DFMT_INDEX32:
2172         case WINED3DFMT_Q16W16V16U16:
2173             TRACE_(d3d_caps)("[FAILED]\n"); /* Enable when implemented */
2174             return FALSE;
2175
2176         /*****
2177          *  WINED3DFMT_CxV8U8: Not supported right now
2178          */
2179         case WINED3DFMT_CxV8U8:
2180             TRACE_(d3d_caps)("[FAILED]\n"); /* Enable when implemented */
2181             return FALSE;
2182
2183         /* YUV formats, not supported for now */
2184         case WINED3DFMT_UYVY:
2185         case WINED3DFMT_YUY2:
2186             TRACE_(d3d_caps)("[FAILED]\n"); /* Enable when implemented */
2187             return FALSE;
2188
2189             /* Not supported */
2190         case WINED3DFMT_A16B16G16R16:
2191         case WINED3DFMT_A8R3G3B2:
2192             TRACE_(d3d_caps)("[FAILED]\n"); /* Enable when implemented */
2193             return FALSE;
2194
2195             /* Floating point formats */
2196         case WINED3DFMT_R16F:
2197         case WINED3DFMT_A16B16G16R16F:
2198             if(GL_SUPPORT(ARB_HALF_FLOAT_PIXEL)) {
2199                 TRACE_(d3d_caps)("[OK]\n");
2200                 return TRUE;
2201             }
2202             TRACE_(d3d_caps)("[FAILED]\n");
2203             return FALSE;
2204
2205         case WINED3DFMT_R32F:
2206         case WINED3DFMT_A32B32G32R32F:
2207             if (GL_SUPPORT(ARB_TEXTURE_FLOAT)) {
2208                 TRACE_(d3d_caps)("[OK]\n");
2209                 return TRUE;
2210             }
2211             TRACE_(d3d_caps)("[FAILED]\n");
2212             return FALSE;
2213
2214         case WINED3DFMT_G16R16F:
2215         case WINED3DFMT_G32R32F:
2216             TRACE_(d3d_caps)("[FAILED]\n");
2217             return FALSE;
2218
2219         /* ATI instancing hack: Although ATI cards do not support Shader Model 3.0, they support
2220          * instancing. To query if the card supports instancing CheckDeviceFormat with the special format
2221          * MAKEFOURCC('I','N','S','T') is used. Should a (broken) app check for this provide a proper return value.
2222          * We can do instancing with all shader versions, but we need vertex shaders.
2223          *
2224          * Additionally applications have to set the D3DRS_POINTSIZE render state to MAKEFOURCC('I','N','S','T') once
2225          * to enable instancing. WineD3D doesn't need that and just ignores it.
2226          *
2227          * With Shader Model 3.0 capable cards Instancing 'just works' in Windows.
2228          */
2229         case WINEMAKEFOURCC('I','N','S','T'):
2230             TRACE("ATI Instancing check hack\n");
2231             if(GL_SUPPORT(ARB_VERTEX_PROGRAM) || GL_SUPPORT(ARB_VERTEX_SHADER)) {
2232                 TRACE_(d3d_caps)("[OK]\n");
2233                 return TRUE;
2234             }
2235             TRACE_(d3d_caps)("[FAILED]\n");
2236             return FALSE;
2237
2238         /* Some weird FOURCC formats */
2239         case WINED3DFMT_R8G8_B8G8:
2240         case WINED3DFMT_G8R8_G8B8:
2241         case WINED3DFMT_MULTI2_ARGB8:
2242             TRACE_(d3d_caps)("[FAILED]\n");
2243             return FALSE;
2244
2245         case WINED3DFMT_UNKNOWN:
2246             return FALSE;
2247
2248         default:
2249             ERR("Unhandled format=%s\n", debug_d3dformat(CheckFormat));
2250             break;
2251     }
2252     return FALSE;
2253 }
2254
2255 static BOOL CheckVertexTextureCapability(UINT Adapter, WINED3DFORMAT CheckFormat)
2256 {
2257     if (!GL_LIMITS(vertex_samplers)) {
2258         TRACE_(d3d_caps)("[FAILED]\n");
2259         return FALSE;
2260     }
2261
2262     switch (CheckFormat) {
2263         case WINED3DFMT_A32B32G32R32F:
2264             if (!GL_SUPPORT(ARB_TEXTURE_FLOAT)) {
2265                 TRACE_(d3d_caps)("[FAILED]\n");
2266                 return FALSE;
2267             }
2268             TRACE_(d3d_caps)("[OK]\n");
2269             return TRUE;
2270
2271         default:
2272             TRACE_(d3d_caps)("[FAILED]\n");
2273             return FALSE;
2274     }
2275     return FALSE;
2276 }
2277
2278 static HRESULT WINAPI IWineD3DImpl_CheckDeviceFormat(IWineD3D *iface, UINT Adapter, WINED3DDEVTYPE DeviceType, 
2279                                               WINED3DFORMAT AdapterFormat, DWORD Usage, WINED3DRESOURCETYPE RType, WINED3DFORMAT CheckFormat) {
2280     IWineD3DImpl *This = (IWineD3DImpl *)iface;
2281     DWORD UsageCaps = 0;
2282
2283     TRACE_(d3d_caps)("(%p)-> (STUB) (Adptr:%d, DevType:(%u,%s), AdptFmt:(%u,%s), Use:(%u,%s,%s), ResTyp:(%x,%s), CheckFmt:(%u,%s))\n",
2284           This,
2285           Adapter,
2286           DeviceType, debug_d3ddevicetype(DeviceType),
2287           AdapterFormat, debug_d3dformat(AdapterFormat),
2288           Usage, debug_d3dusage(Usage), debug_d3dusagequery(Usage),
2289           RType, debug_d3dresourcetype(RType),
2290           CheckFormat, debug_d3dformat(CheckFormat));
2291
2292     if (Adapter >= IWineD3D_GetAdapterCount(iface)) {
2293         return WINED3DERR_INVALIDCALL;
2294     }
2295
2296     if(RType == WINED3DRTYPE_CUBETEXTURE) {
2297         /* Cubetexture allows:
2298          *                    - D3DUSAGE_AUTOGENMIPMAP
2299          *                    - D3DUSAGE_DEPTHSTENCIL
2300          *                    - D3DUSAGE_DYNAMIC
2301          *                    - D3DUSAGE_NONSECURE (d3d9ex)
2302          *                    - D3DUSAGE_RENDERTARGET
2303          *                    - D3DUSAGE_SOFTWAREPROCESSING
2304          */
2305         if(GL_SUPPORT(ARB_TEXTURE_CUBE_MAP)) {
2306             /* Check if the texture format is around */
2307             if(CheckTextureCapability(Adapter, CheckFormat)) {
2308                 if(Usage & WINED3DUSAGE_AUTOGENMIPMAP) {
2309                     /* Check for automatic mipmap generation support */
2310                     if(GL_SUPPORT(SGIS_GENERATE_MIPMAP)) {
2311                         UsageCaps |= WINED3DUSAGE_AUTOGENMIPMAP;
2312                     } else {
2313                         /* When autogenmipmap isn't around continue and return WINED3DOK_NOAUOTGEN instead of D3D_OK */
2314                         TRACE_(d3d_caps)("[FAILED] - No autogenmipmap support, but continuing\n");
2315                     }
2316                 }
2317
2318                 /* Always report dynamic locking */
2319                 if(Usage & WINED3DUSAGE_DYNAMIC)
2320                     UsageCaps |= WINED3DUSAGE_DYNAMIC;
2321
2322                 if(Usage & WINED3DUSAGE_RENDERTARGET) {
2323                     if(CheckRenderTargetCapability(AdapterFormat, CheckFormat)) {
2324                         UsageCaps |= WINED3DUSAGE_RENDERTARGET;
2325                     } else {
2326                         TRACE_(d3d_caps)("[FAILED] - No rendertarget support\n");
2327                         return WINED3DERR_NOTAVAILABLE;
2328                     }
2329                 }
2330
2331                 /* Always report software processing */
2332                 if(Usage & WINED3DUSAGE_SOFTWAREPROCESSING)
2333                     UsageCaps |= WINED3DUSAGE_SOFTWAREPROCESSING;
2334
2335                 /* Check QUERY_FILTER support */
2336                 if(Usage & WINED3DUSAGE_QUERY_FILTER) {
2337                     if(CheckFilterCapability(CheckFormat)) {
2338                         UsageCaps |= WINED3DUSAGE_QUERY_FILTER;
2339                     } else {
2340                         TRACE_(d3d_caps)("[FAILED] - No query filter support\n");
2341                         return WINED3DERR_NOTAVAILABLE;
2342                     }
2343                 }
2344
2345                 /* Check QUERY_SRGBREAD support */
2346                 if(Usage & WINED3DUSAGE_QUERY_SRGBREAD) {
2347                     if(CheckSrgbReadCapability(Adapter, CheckFormat)) {
2348                         UsageCaps |= WINED3DUSAGE_QUERY_SRGBREAD;
2349                     } else {
2350                         TRACE_(d3d_caps)("[FAILED] - No query srgbread support\n");
2351                         return WINED3DERR_NOTAVAILABLE;
2352                     }
2353                 }
2354
2355                 /* Check QUERY_SRGBWRITE support */
2356                 if(Usage & WINED3DUSAGE_QUERY_SRGBWRITE) {
2357                     if(CheckSrgbWriteCapability(Adapter, DeviceType, CheckFormat)) {
2358                         UsageCaps |= WINED3DUSAGE_QUERY_SRGBWRITE;
2359                     } else {
2360                         TRACE_(d3d_caps)("[FAILED] - No query srgbwrite support\n");
2361                         return WINED3DERR_NOTAVAILABLE;
2362                     }
2363                 }
2364
2365                 /* Check QUERY_VERTEXTEXTURE support */
2366                 if(Usage & WINED3DUSAGE_QUERY_VERTEXTEXTURE) {
2367                     if(CheckVertexTextureCapability(Adapter, CheckFormat)) {
2368                         UsageCaps |= WINED3DUSAGE_QUERY_VERTEXTEXTURE;
2369                     } else {
2370                         TRACE_(d3d_caps)("[FAILED] - No query vertextexture support\n");
2371                         return WINED3DERR_NOTAVAILABLE;
2372                     }
2373                 }
2374             } else {
2375                 TRACE_(d3d_caps)("[FAILED] - Cube texture format not supported\n");
2376                 return WINED3DERR_NOTAVAILABLE;
2377             }
2378         } else {
2379             TRACE_(d3d_caps)("[FAILED] - No cube texture support\n");
2380             return WINED3DERR_NOTAVAILABLE;
2381         }
2382     } else if(RType == WINED3DRTYPE_SURFACE) {
2383         /* Surface allows:
2384          *                - D3DUSAGE_DEPTHSTENCIL
2385          *                - D3DUSAGE_NONSECURE (d3d9ex)
2386          *                - D3DUSAGE_RENDERTARGET
2387          */
2388
2389         if(Usage & WINED3DUSAGE_DEPTHSTENCIL) {
2390             if(CheckDepthStencilCapability(Adapter, AdapterFormat, CheckFormat)) {
2391                 UsageCaps |= WINED3DUSAGE_DEPTHSTENCIL;
2392             } else {
2393                 TRACE_(d3d_caps)("[FAILED] - No depthstencil support\n");
2394                 return WINED3DERR_NOTAVAILABLE;
2395             }
2396         }
2397
2398         if(Usage & WINED3DUSAGE_RENDERTARGET) {
2399             if(CheckRenderTargetCapability(AdapterFormat, CheckFormat)) {
2400                 UsageCaps |= WINED3DUSAGE_RENDERTARGET;
2401             } else {
2402                 TRACE_(d3d_caps)("[FAILED] - No rendertarget support\n");
2403                  return WINED3DERR_NOTAVAILABLE;
2404             }
2405         }
2406     } else if(RType == WINED3DRTYPE_TEXTURE) {
2407         /* Texture allows:
2408          *                - D3DUSAGE_AUTOGENMIPMAP
2409          *                - D3DUSAGE_DEPTHSTENCIL
2410          *                - D3DUSAGE_DMAP
2411          *                - D3DUSAGE_DYNAMIC
2412          *                - D3DUSAGE_NONSECURE (d3d9ex)
2413          *                - D3DUSAGE_RENDERTARGET
2414          *                - D3DUSAGE_SOFTWAREPROCESSING
2415          *                - D3DUSAGE_TEXTAPI (d3d9ex)
2416          */
2417
2418         /* Check if the texture format is around */
2419         if(CheckTextureCapability(Adapter, CheckFormat)) {
2420             if(Usage & WINED3DUSAGE_AUTOGENMIPMAP) {
2421                 /* Check for automatic mipmap generation support */
2422                 if(GL_SUPPORT(SGIS_GENERATE_MIPMAP)) {
2423                     UsageCaps |= WINED3DUSAGE_AUTOGENMIPMAP;
2424                 } else {
2425                     /* When autogenmipmap isn't around continue and return WINED3DOK_NOAUOTGEN instead of D3D_OK */
2426                     TRACE_(d3d_caps)("[FAILED] - No autogenmipmap support, but continuing\n");
2427                 }
2428             }
2429
2430             /* Always report dynamic locking */
2431             if(Usage & WINED3DUSAGE_DYNAMIC)
2432                 UsageCaps |= WINED3DUSAGE_DYNAMIC;
2433
2434             if(Usage & WINED3DUSAGE_RENDERTARGET) {
2435                 if(CheckRenderTargetCapability(AdapterFormat, CheckFormat)) {
2436                     UsageCaps |= WINED3DUSAGE_RENDERTARGET;
2437                 } else {
2438                     TRACE_(d3d_caps)("[FAILED] - No rendertarget support\n");
2439                      return WINED3DERR_NOTAVAILABLE;
2440                  }
2441             }
2442
2443             /* Always report software processing */
2444             if(Usage & WINED3DUSAGE_SOFTWAREPROCESSING)
2445                 UsageCaps |= WINED3DUSAGE_SOFTWAREPROCESSING;
2446
2447             /* Check QUERY_FILTER support */
2448             if(Usage & WINED3DUSAGE_QUERY_FILTER) {
2449                 if(CheckFilterCapability(CheckFormat)) {
2450                     UsageCaps |= WINED3DUSAGE_QUERY_FILTER;
2451                 } else {
2452                     TRACE_(d3d_caps)("[FAILED] - No query filter support\n");
2453                     return WINED3DERR_NOTAVAILABLE;
2454                 }
2455             }
2456
2457             /* Check QUERY_LEGACYBUMPMAP support */
2458             if(Usage & WINED3DUSAGE_QUERY_LEGACYBUMPMAP) {
2459                 if(CheckBumpMapCapability(Adapter, CheckFormat)) {
2460                     UsageCaps |= WINED3DUSAGE_QUERY_LEGACYBUMPMAP;
2461                 } else {
2462                     TRACE_(d3d_caps)("[FAILED] - No legacy bumpmap support\n");
2463                     return WINED3DERR_NOTAVAILABLE;
2464                 }
2465             }
2466
2467             /* Check QUERY_SRGBREAD support */
2468             if(Usage & WINED3DUSAGE_QUERY_SRGBREAD) {
2469                 if(CheckSrgbReadCapability(Adapter, CheckFormat)) {
2470                     UsageCaps |= WINED3DUSAGE_QUERY_SRGBREAD;
2471                 } else {
2472                     TRACE_(d3d_caps)("[FAILED] - No query srgbread support\n");
2473                     return WINED3DERR_NOTAVAILABLE;
2474                 }
2475             }
2476
2477             /* Check QUERY_SRGBWRITE support */
2478             if(Usage & WINED3DUSAGE_QUERY_SRGBWRITE) {
2479                 if(CheckSrgbWriteCapability(Adapter, DeviceType, CheckFormat)) {
2480                     UsageCaps |= WINED3DUSAGE_QUERY_SRGBWRITE;
2481                 } else {
2482                     TRACE_(d3d_caps)("[FAILED] - No query srgbwrite support\n");
2483                     return WINED3DERR_NOTAVAILABLE;
2484                 }
2485             }
2486
2487             /* Check QUERY_VERTEXTEXTURE support */
2488             if(Usage & WINED3DUSAGE_QUERY_VERTEXTEXTURE) {
2489                 if(CheckVertexTextureCapability(Adapter, CheckFormat)) {
2490                     UsageCaps |= WINED3DUSAGE_QUERY_VERTEXTEXTURE;
2491                 } else {
2492                     TRACE_(d3d_caps)("[FAILED] - No query vertextexture support\n");
2493                     return WINED3DERR_NOTAVAILABLE;
2494                 }
2495             }
2496         } else if(CheckDepthStencilCapability(Adapter, AdapterFormat, CheckFormat)) {
2497             if(Usage & WINED3DUSAGE_DEPTHSTENCIL)
2498                 UsageCaps |= WINED3DUSAGE_DEPTHSTENCIL;
2499         } else {
2500             TRACE_(d3d_caps)("[FAILED] - Texture format not supported\n");
2501             return WINED3DERR_NOTAVAILABLE;
2502         }
2503     } else if((RType == WINED3DRTYPE_VOLUME) || (RType == WINED3DRTYPE_VOLUMETEXTURE)) {
2504         /* Volume is to VolumeTexture what Surface is to Texture but its usage caps are not documented.
2505          * Most driver seem to offer (nearly) the same on Volume and VolumeTexture, so do that too.
2506          *
2507          * Volumetexture allows:
2508          *                      - D3DUSAGE_DYNAMIC
2509          *                      - D3DUSAGE_NONSECURE (d3d9ex)
2510          *                      - D3DUSAGE_SOFTWAREPROCESSING
2511          */
2512
2513         /* Check volume texture and volume usage caps */
2514         if(GL_SUPPORT(EXT_TEXTURE3D)) {
2515             if(CheckTextureCapability(Adapter, CheckFormat) == FALSE) {
2516                 TRACE_(d3d_caps)("[FAILED] - Format not supported\n");
2517                 return WINED3DERR_NOTAVAILABLE;
2518             }
2519
2520             /* Always report dynamic locking */
2521             if(Usage & WINED3DUSAGE_DYNAMIC)
2522                 UsageCaps |= WINED3DUSAGE_DYNAMIC;
2523
2524             /* Always report software processing */
2525             if(Usage & WINED3DUSAGE_SOFTWAREPROCESSING)
2526                 UsageCaps |= WINED3DUSAGE_SOFTWAREPROCESSING;
2527
2528             /* Check QUERY_FILTER support */
2529             if(Usage & WINED3DUSAGE_QUERY_FILTER) {
2530                 if(CheckFilterCapability(CheckFormat)) {
2531                     UsageCaps |= WINED3DUSAGE_QUERY_FILTER;
2532                 } else {
2533                     TRACE_(d3d_caps)("[FAILED] - No query filter support\n");
2534                     return WINED3DERR_NOTAVAILABLE;
2535                 }
2536             }
2537
2538             /* Check QUERY_SRGBREAD support */
2539             if(Usage & WINED3DUSAGE_QUERY_SRGBREAD) {
2540                 if(CheckSrgbReadCapability(Adapter, CheckFormat)) {
2541                     UsageCaps |= WINED3DUSAGE_QUERY_SRGBREAD;
2542                 } else {
2543                     TRACE_(d3d_caps)("[FAILED] - No query srgbread support\n");
2544                     return WINED3DERR_NOTAVAILABLE;
2545                 }
2546             }
2547
2548             /* Check QUERY_SRGBWRITE support */
2549             if(Usage & WINED3DUSAGE_QUERY_SRGBWRITE) {
2550                 if(CheckSrgbWriteCapability(Adapter, DeviceType, CheckFormat)) {
2551                     UsageCaps |= WINED3DUSAGE_QUERY_SRGBWRITE;
2552                 } else {
2553                     TRACE_(d3d_caps)("[FAILED] - No query srgbwrite support\n");
2554                     return WINED3DERR_NOTAVAILABLE;
2555                 }
2556             }
2557
2558             /* Check QUERY_VERTEXTEXTURE support */
2559             if(Usage & WINED3DUSAGE_QUERY_VERTEXTEXTURE) {
2560                 if(CheckVertexTextureCapability(Adapter, CheckFormat)) {
2561                     UsageCaps |= WINED3DUSAGE_QUERY_VERTEXTEXTURE;
2562                 } else {
2563                     TRACE_(d3d_caps)("[FAILED] - No query vertextexture support\n");
2564                     return WINED3DERR_NOTAVAILABLE;
2565                 }
2566             }
2567         } else {
2568             TRACE_(d3d_caps)("[FAILED] - No volume texture support\n");
2569             return WINED3DERR_NOTAVAILABLE;
2570         }
2571
2572         /* Filter formats that need conversion; For one part, this conversion is unimplemented,
2573          * and volume textures are huge, so it would be a big performance hit. Unless we hit an
2574          * app needing one of those formats, don't advertize them to avoid leading apps into
2575          * temptation. The windows drivers don't support most of those formats on volumes anyway,
2576          * except of R32F.
2577          */
2578         switch(CheckFormat) {
2579             case WINED3DFMT_P8:
2580             case WINED3DFMT_A4L4:
2581             case WINED3DFMT_R32F:
2582             case WINED3DFMT_R16F:
2583             case WINED3DFMT_X8L8V8U8:
2584             case WINED3DFMT_L6V5U5:
2585             case WINED3DFMT_G16R16:
2586                 TRACE_(d3d_caps)("[FAILED] - No converted formats on volumes\n");
2587                 return WINED3DERR_NOTAVAILABLE;
2588
2589             case WINED3DFMT_Q8W8V8U8:
2590             case WINED3DFMT_V16U16:
2591             if(!GL_SUPPORT(NV_TEXTURE_SHADER)) {
2592                 TRACE_(d3d_caps)("[FAILED] - No converted formats on volumes\n");
2593                 return WINED3DERR_NOTAVAILABLE;
2594             }
2595             break;
2596
2597             case WINED3DFMT_V8U8:
2598             if(!GL_SUPPORT(NV_TEXTURE_SHADER) || !GL_SUPPORT(ATI_ENVMAP_BUMPMAP)) {
2599                 TRACE_(d3d_caps)("[FAILED] - No converted formats on volumes\n");
2600                 return WINED3DERR_NOTAVAILABLE;
2601             }
2602             break;
2603
2604             case WINED3DFMT_DXT1:
2605             case WINED3DFMT_DXT2:
2606             case WINED3DFMT_DXT3:
2607             case WINED3DFMT_DXT4:
2608             case WINED3DFMT_DXT5:
2609                 /* The GL_EXT_texture_compression_s3tc spec requires that loading an s3tc
2610                  * compressed texture results in an error. While the D3D refrast does
2611                  * support s3tc volumes, at least the nvidia windows driver does not, so
2612                  * we're free not to support this format.
2613                  */
2614                 TRACE_(d3d_caps)("[FAILED] - DXTn does not support 3D textures\n");
2615                 return WINED3DERR_NOTAVAILABLE;
2616
2617             default:
2618                 /* Do nothing, continue with checking the format below */
2619                 break;
2620         }
2621     } else if((RType == WINED3DRTYPE_INDEXBUFFER) || (RType == WINED3DRTYPE_VERTEXBUFFER)){
2622         /* For instance vertexbuffer/indexbuffer aren't supported yet because no Windows drivers seem to offer it */
2623         TRACE_(d3d_caps)("Unhandled resource type D3DRTYPE_INDEXBUFFER / D3DRTYPE_VERTEXBUFFER\n");
2624         return WINED3DERR_NOTAVAILABLE;
2625      }
2626
2627     /* This format is nothing special and it is supported perfectly.
2628      * However, ati and nvidia driver on windows do not mark this format as
2629      * supported (tested with the dxCapsViewer) and pretending to
2630      * support this format uncovers a bug in Battlefield 1942 (fonts are missing)
2631      * So do the same as Windows drivers and pretend not to support it on dx8 and 9
2632      * Enable it on dx7. It will need additional checking on dx10 when we support it.
2633      */
2634     if(This->dxVersion > 7 && CheckFormat == WINED3DFMT_R8G8B8) {
2635         TRACE_(d3d_caps)("[FAILED]\n");
2636         return WINED3DERR_NOTAVAILABLE;
2637     }
2638
2639     /* When the UsageCaps exactly matches Usage return WINED3D_OK except for the situation in which
2640      * WINED3DUSAGE_AUTOGENMIPMAP isn't around, then WINED3DOK_NOAUTOGEN is returned if all the other
2641      * usage flags match. */
2642     if(UsageCaps == Usage) {
2643         return WINED3D_OK;
2644     } else if((UsageCaps == (Usage & ~WINED3DUSAGE_AUTOGENMIPMAP)) && (Usage & WINED3DUSAGE_AUTOGENMIPMAP)){
2645         return WINED3DOK_NOAUTOGEN;
2646     } else {
2647         TRACE_(d3d_caps)("[FAILED] - Usage=%#08x requested for CheckFormat=%s and RType=%d but only %#08x is available\n", Usage, debug_d3dformat(CheckFormat), RType, UsageCaps);
2648         return WINED3DERR_NOTAVAILABLE;
2649     }
2650 }
2651
2652 static HRESULT  WINAPI IWineD3DImpl_CheckDeviceFormatConversion(IWineD3D *iface, UINT Adapter, WINED3DDEVTYPE DeviceType,
2653                                                           WINED3DFORMAT SourceFormat, WINED3DFORMAT TargetFormat) {
2654     IWineD3DImpl *This = (IWineD3DImpl *)iface;
2655
2656     FIXME_(d3d_caps)("(%p)-> (STUB) (Adptr:%d, DevType:(%u,%s), SrcFmt:(%u,%s), TgtFmt:(%u,%s))\n",
2657           This,
2658           Adapter,
2659           DeviceType, debug_d3ddevicetype(DeviceType),
2660           SourceFormat, debug_d3dformat(SourceFormat),
2661           TargetFormat, debug_d3dformat(TargetFormat));
2662     return WINED3D_OK;
2663 }
2664
2665 static const shader_backend_t *select_shader_backend(UINT Adapter, WINED3DDEVTYPE DeviceType) {
2666     const shader_backend_t *ret;
2667     int vs_selected_mode;
2668     int ps_selected_mode;
2669
2670     select_shader_mode(&GLINFO_LOCATION, DeviceType, &ps_selected_mode, &vs_selected_mode);
2671     if (vs_selected_mode == SHADER_GLSL || ps_selected_mode == SHADER_GLSL) {
2672         ret = &glsl_shader_backend;
2673     } else if (vs_selected_mode == SHADER_ARB && ps_selected_mode != SHADER_NONE &&
2674               !GL_SUPPORT(ARB_FRAGMENT_PROGRAM)) {
2675         ret = &atifs_shader_backend;
2676     } else if (vs_selected_mode == SHADER_ARB || ps_selected_mode == SHADER_ARB) {
2677         ret = &arb_program_shader_backend;
2678     } else {
2679         ret = &none_shader_backend;
2680     }
2681     return ret;
2682 }
2683
2684 /* Note: d3d8 passes in a pointer to a D3DCAPS8 structure, which is a true
2685       subset of a D3DCAPS9 structure. However, it has to come via a void *
2686       as the d3d8 interface cannot import the d3d9 header                  */
2687 static HRESULT WINAPI IWineD3DImpl_GetDeviceCaps(IWineD3D *iface, UINT Adapter, WINED3DDEVTYPE DeviceType, WINED3DCAPS* pCaps) {
2688
2689     IWineD3DImpl    *This = (IWineD3DImpl *)iface;
2690     int vs_selected_mode;
2691     int ps_selected_mode;
2692     struct shader_caps shader_caps;
2693     const shader_backend_t *shader_backend;
2694
2695     TRACE_(d3d_caps)("(%p)->(Adptr:%d, DevType: %x, pCaps: %p)\n", This, Adapter, DeviceType, pCaps);
2696
2697     if (Adapter >= IWineD3D_GetAdapterCount(iface)) {
2698         return WINED3DERR_INVALIDCALL;
2699     }
2700
2701     select_shader_mode(&Adapters[Adapter].gl_info, DeviceType, &ps_selected_mode, &vs_selected_mode);
2702
2703     /* This function should *not* be modifying GL caps
2704      * TODO: move the functionality where it belongs */
2705     select_shader_max_constants(ps_selected_mode, vs_selected_mode, &Adapters[Adapter].gl_info);
2706
2707     /* ------------------------------------------------
2708        The following fields apply to both d3d8 and d3d9
2709        ------------------------------------------------ */
2710     pCaps->DeviceType              = (DeviceType == WINED3DDEVTYPE_HAL) ? WINED3DDEVTYPE_HAL : WINED3DDEVTYPE_REF;  /* Not quite true, but use h/w supported by opengl I suppose */
2711     pCaps->AdapterOrdinal          = Adapter;
2712
2713     pCaps->Caps                    = 0;
2714     pCaps->Caps2                   = WINED3DCAPS2_CANRENDERWINDOWED |
2715                                      WINED3DCAPS2_FULLSCREENGAMMA |
2716                                      WINED3DCAPS2_DYNAMICTEXTURES;
2717     if(GL_SUPPORT(SGIS_GENERATE_MIPMAP)) {
2718         pCaps->Caps2 |= WINED3DCAPS2_CANAUTOGENMIPMAP;
2719     }
2720     pCaps->Caps3                   = WINED3DCAPS3_ALPHA_FULLSCREEN_FLIP_OR_DISCARD;
2721     pCaps->PresentationIntervals   = WINED3DPRESENT_INTERVAL_IMMEDIATE  |
2722                                      WINED3DPRESENT_INTERVAL_ONE;
2723
2724     pCaps->CursorCaps              = WINED3DCURSORCAPS_COLOR            |
2725                                      WINED3DCURSORCAPS_LOWRES;
2726
2727     pCaps->DevCaps                 = WINED3DDEVCAPS_FLOATTLVERTEX       |
2728                                      WINED3DDEVCAPS_EXECUTESYSTEMMEMORY |
2729                                      WINED3DDEVCAPS_TLVERTEXSYSTEMMEMORY|
2730                                      WINED3DDEVCAPS_TLVERTEXVIDEOMEMORY |
2731                                      WINED3DDEVCAPS_DRAWPRIMTLVERTEX    |
2732                                      WINED3DDEVCAPS_HWTRANSFORMANDLIGHT |
2733                                      WINED3DDEVCAPS_EXECUTEVIDEOMEMORY  |
2734                                      WINED3DDEVCAPS_PUREDEVICE          |
2735                                      WINED3DDEVCAPS_HWRASTERIZATION     |
2736                                      WINED3DDEVCAPS_TEXTUREVIDEOMEMORY  |
2737                                      WINED3DDEVCAPS_TEXTURESYSTEMMEMORY |
2738                                      WINED3DDEVCAPS_CANRENDERAFTERFLIP  |
2739                                      WINED3DDEVCAPS_DRAWPRIMITIVES2     |
2740                                      WINED3DDEVCAPS_DRAWPRIMITIVES2EX   |
2741                                      WINED3DDEVCAPS_RTPATCHES;
2742
2743     pCaps->PrimitiveMiscCaps       = WINED3DPMISCCAPS_CULLNONE              |
2744                                      WINED3DPMISCCAPS_CULLCCW               |
2745                                      WINED3DPMISCCAPS_CULLCW                |
2746                                      WINED3DPMISCCAPS_COLORWRITEENABLE      |
2747                                      WINED3DPMISCCAPS_CLIPTLVERTS           |
2748                                      WINED3DPMISCCAPS_CLIPPLANESCALEDPOINTS |
2749                                      WINED3DPMISCCAPS_MASKZ                 |
2750                                      WINED3DPMISCCAPS_BLENDOP;
2751                                     /* TODO:
2752                                         WINED3DPMISCCAPS_NULLREFERENCE
2753                                         WINED3DPMISCCAPS_INDEPENDENTWRITEMASKS
2754                                         WINED3DPMISCCAPS_FOGANDSPECULARALPHA
2755                                         WINED3DPMISCCAPS_MRTINDEPENDENTBITDEPTHS
2756                                         WINED3DPMISCCAPS_MRTPOSTPIXELSHADERBLENDING
2757                                         WINED3DPMISCCAPS_FOGVERTEXCLAMPED */
2758
2759     if(GL_SUPPORT(EXT_BLEND_EQUATION_SEPARATE) && GL_SUPPORT(EXT_BLEND_FUNC_SEPARATE))
2760         pCaps->PrimitiveMiscCaps |= WINED3DPMISCCAPS_SEPARATEALPHABLEND;
2761
2762 /* The caps below can be supported but aren't handled yet in utils.c 'd3dta_to_combiner_input', disable them until support is fixed */
2763 #if 0
2764     if (GL_SUPPORT(NV_REGISTER_COMBINERS))
2765         pCaps->PrimitiveMiscCaps |=  WINED3DPMISCCAPS_TSSARGTEMP;
2766     if (GL_SUPPORT(NV_REGISTER_COMBINERS2))
2767         pCaps->PrimitiveMiscCaps |=  WINED3DPMISCCAPS_PERSTAGECONSTANT;
2768 #endif
2769
2770     pCaps->RasterCaps              = WINED3DPRASTERCAPS_DITHER    |
2771                                      WINED3DPRASTERCAPS_PAT       |
2772                                      WINED3DPRASTERCAPS_WFOG      |
2773                                      WINED3DPRASTERCAPS_ZFOG      |
2774                                      WINED3DPRASTERCAPS_FOGVERTEX |
2775                                      WINED3DPRASTERCAPS_FOGTABLE  |
2776                                      WINED3DPRASTERCAPS_STIPPLE   |
2777                                      WINED3DPRASTERCAPS_SUBPIXEL  |
2778                                      WINED3DPRASTERCAPS_ZTEST     |
2779                                      WINED3DPRASTERCAPS_SCISSORTEST   |
2780                                      WINED3DPRASTERCAPS_SLOPESCALEDEPTHBIAS |
2781                                      WINED3DPRASTERCAPS_DEPTHBIAS;
2782
2783     if (GL_SUPPORT(EXT_TEXTURE_FILTER_ANISOTROPIC)) {
2784         pCaps->RasterCaps |= WINED3DPRASTERCAPS_ANISOTROPY    |
2785                              WINED3DPRASTERCAPS_ZBIAS         |
2786                              WINED3DPRASTERCAPS_MIPMAPLODBIAS;
2787     }
2788     if(GL_SUPPORT(NV_FOG_DISTANCE)) {
2789         pCaps->RasterCaps         |= WINED3DPRASTERCAPS_FOGRANGE;
2790     }
2791                         /* FIXME Add:
2792                            WINED3DPRASTERCAPS_COLORPERSPECTIVE
2793                            WINED3DPRASTERCAPS_STRETCHBLTMULTISAMPLE
2794                            WINED3DPRASTERCAPS_ANTIALIASEDGES
2795                            WINED3DPRASTERCAPS_ZBUFFERLESSHSR
2796                            WINED3DPRASTERCAPS_WBUFFER */
2797
2798     pCaps->ZCmpCaps = WINED3DPCMPCAPS_ALWAYS       |
2799                       WINED3DPCMPCAPS_EQUAL        |
2800                       WINED3DPCMPCAPS_GREATER      |
2801                       WINED3DPCMPCAPS_GREATEREQUAL |
2802                       WINED3DPCMPCAPS_LESS         |
2803                       WINED3DPCMPCAPS_LESSEQUAL    |
2804                       WINED3DPCMPCAPS_NEVER        |
2805                       WINED3DPCMPCAPS_NOTEQUAL;
2806
2807     pCaps->SrcBlendCaps  = WINED3DPBLENDCAPS_BOTHINVSRCALPHA |
2808                            WINED3DPBLENDCAPS_BOTHSRCALPHA    |
2809                            WINED3DPBLENDCAPS_DESTALPHA       |
2810                            WINED3DPBLENDCAPS_DESTCOLOR       |
2811                            WINED3DPBLENDCAPS_INVDESTALPHA    |
2812                            WINED3DPBLENDCAPS_INVDESTCOLOR    |
2813                            WINED3DPBLENDCAPS_INVSRCALPHA     |
2814                            WINED3DPBLENDCAPS_INVSRCCOLOR     |
2815                            WINED3DPBLENDCAPS_ONE             |
2816                            WINED3DPBLENDCAPS_SRCALPHA        |
2817                            WINED3DPBLENDCAPS_SRCALPHASAT     |
2818                            WINED3DPBLENDCAPS_SRCCOLOR        |
2819                            WINED3DPBLENDCAPS_ZERO;
2820
2821     pCaps->DestBlendCaps = WINED3DPBLENDCAPS_DESTALPHA       |
2822                            WINED3DPBLENDCAPS_DESTCOLOR       |
2823                            WINED3DPBLENDCAPS_INVDESTALPHA    |
2824                            WINED3DPBLENDCAPS_INVDESTCOLOR    |
2825                            WINED3DPBLENDCAPS_INVSRCALPHA     |
2826                            WINED3DPBLENDCAPS_INVSRCCOLOR     |
2827                            WINED3DPBLENDCAPS_ONE             |
2828                            WINED3DPBLENDCAPS_SRCALPHA        |
2829                            WINED3DPBLENDCAPS_SRCCOLOR        |
2830                            WINED3DPBLENDCAPS_ZERO;
2831     /* NOTE: WINED3DPBLENDCAPS_SRCALPHASAT is not supported as dest blend factor,
2832      * according to the glBlendFunc manpage
2833      *
2834      * WINED3DPBLENDCAPS_BOTHINVSRCALPHA and WINED3DPBLENDCAPS_BOTHSRCALPHA are
2835      * legacy settings for srcblend only
2836      */
2837
2838     if( GL_SUPPORT(EXT_BLEND_COLOR)) {
2839         pCaps->SrcBlendCaps |= WINED3DPBLENDCAPS_BLENDFACTOR;
2840         pCaps->DestBlendCaps |= WINED3DPBLENDCAPS_BLENDFACTOR;
2841     }
2842
2843
2844     pCaps->AlphaCmpCaps = WINED3DPCMPCAPS_ALWAYS       |
2845                           WINED3DPCMPCAPS_EQUAL        |
2846                           WINED3DPCMPCAPS_GREATER      |
2847                           WINED3DPCMPCAPS_GREATEREQUAL |
2848                           WINED3DPCMPCAPS_LESS         |
2849                           WINED3DPCMPCAPS_LESSEQUAL    |
2850                           WINED3DPCMPCAPS_NEVER        |
2851                           WINED3DPCMPCAPS_NOTEQUAL;
2852
2853     pCaps->ShadeCaps     = WINED3DPSHADECAPS_SPECULARGOURAUDRGB |
2854                            WINED3DPSHADECAPS_COLORGOURAUDRGB    |
2855                            WINED3DPSHADECAPS_ALPHAFLATBLEND     |
2856                            WINED3DPSHADECAPS_ALPHAGOURAUDBLEND  |
2857                            WINED3DPSHADECAPS_COLORFLATRGB       |
2858                            WINED3DPSHADECAPS_FOGFLAT            |
2859                            WINED3DPSHADECAPS_FOGGOURAUD         |
2860                            WINED3DPSHADECAPS_SPECULARFLATRGB;
2861
2862     pCaps->TextureCaps =  WINED3DPTEXTURECAPS_ALPHA              |
2863                           WINED3DPTEXTURECAPS_ALPHAPALETTE       |
2864                           WINED3DPTEXTURECAPS_BORDER             |
2865                           WINED3DPTEXTURECAPS_MIPMAP             |
2866                           WINED3DPTEXTURECAPS_PROJECTED          |
2867                           WINED3DPTEXTURECAPS_PERSPECTIVE;
2868
2869     if( !GL_SUPPORT(ARB_TEXTURE_NON_POWER_OF_TWO)) {
2870         pCaps->TextureCaps |= WINED3DPTEXTURECAPS_POW2 |
2871                               WINED3DPTEXTURECAPS_NONPOW2CONDITIONAL;
2872     }
2873
2874     if( GL_SUPPORT(EXT_TEXTURE3D)) {
2875         pCaps->TextureCaps |=  WINED3DPTEXTURECAPS_VOLUMEMAP      |
2876                                WINED3DPTEXTURECAPS_MIPVOLUMEMAP   |
2877                                WINED3DPTEXTURECAPS_VOLUMEMAP_POW2;
2878     }
2879
2880     if (GL_SUPPORT(ARB_TEXTURE_CUBE_MAP)) {
2881         pCaps->TextureCaps |= WINED3DPTEXTURECAPS_CUBEMAP     |
2882                               WINED3DPTEXTURECAPS_MIPCUBEMAP    |
2883                               WINED3DPTEXTURECAPS_CUBEMAP_POW2;
2884
2885     }
2886
2887     pCaps->TextureFilterCaps = WINED3DPTFILTERCAPS_MAGFLINEAR       |
2888                                WINED3DPTFILTERCAPS_MAGFPOINT        |
2889                                WINED3DPTFILTERCAPS_MINFLINEAR       |
2890                                WINED3DPTFILTERCAPS_MINFPOINT        |
2891                                WINED3DPTFILTERCAPS_MIPFLINEAR       |
2892                                WINED3DPTFILTERCAPS_MIPFPOINT        |
2893                                WINED3DPTFILTERCAPS_LINEAR           |
2894                                WINED3DPTFILTERCAPS_LINEARMIPLINEAR  |
2895                                WINED3DPTFILTERCAPS_LINEARMIPNEAREST |
2896                                WINED3DPTFILTERCAPS_MIPLINEAR        |
2897                                WINED3DPTFILTERCAPS_MIPNEAREST       |
2898                                WINED3DPTFILTERCAPS_NEAREST;
2899
2900     if (GL_SUPPORT(EXT_TEXTURE_FILTER_ANISOTROPIC)) {
2901         pCaps->TextureFilterCaps |= WINED3DPTFILTERCAPS_MAGFANISOTROPIC |
2902                                     WINED3DPTFILTERCAPS_MINFANISOTROPIC;
2903     }
2904
2905     if (GL_SUPPORT(ARB_TEXTURE_CUBE_MAP)) {
2906         pCaps->CubeTextureFilterCaps = WINED3DPTFILTERCAPS_MAGFLINEAR       |
2907                                        WINED3DPTFILTERCAPS_MAGFPOINT        |
2908                                        WINED3DPTFILTERCAPS_MINFLINEAR       |
2909                                        WINED3DPTFILTERCAPS_MINFPOINT        |
2910                                        WINED3DPTFILTERCAPS_MIPFLINEAR       |
2911                                        WINED3DPTFILTERCAPS_MIPFPOINT        |
2912                                        WINED3DPTFILTERCAPS_LINEAR           |
2913                                        WINED3DPTFILTERCAPS_LINEARMIPLINEAR  |
2914                                        WINED3DPTFILTERCAPS_LINEARMIPNEAREST |
2915                                        WINED3DPTFILTERCAPS_MIPLINEAR        |
2916                                        WINED3DPTFILTERCAPS_MIPNEAREST       |
2917                                        WINED3DPTFILTERCAPS_NEAREST;
2918
2919         if (GL_SUPPORT(EXT_TEXTURE_FILTER_ANISOTROPIC)) {
2920             pCaps->CubeTextureFilterCaps |= WINED3DPTFILTERCAPS_MAGFANISOTROPIC |
2921                                             WINED3DPTFILTERCAPS_MINFANISOTROPIC;
2922         }
2923     } else
2924         pCaps->CubeTextureFilterCaps = 0;
2925
2926     if (GL_SUPPORT(EXT_TEXTURE3D)) {
2927         pCaps->VolumeTextureFilterCaps = WINED3DPTFILTERCAPS_MAGFLINEAR       |
2928                                          WINED3DPTFILTERCAPS_MAGFPOINT        |
2929                                          WINED3DPTFILTERCAPS_MINFLINEAR       |
2930                                          WINED3DPTFILTERCAPS_MINFPOINT        |
2931                                          WINED3DPTFILTERCAPS_MIPFLINEAR       |
2932                                          WINED3DPTFILTERCAPS_MIPFPOINT        |
2933                                          WINED3DPTFILTERCAPS_LINEAR           |
2934                                          WINED3DPTFILTERCAPS_LINEARMIPLINEAR  |
2935                                          WINED3DPTFILTERCAPS_LINEARMIPNEAREST |
2936                                          WINED3DPTFILTERCAPS_MIPLINEAR        |
2937                                          WINED3DPTFILTERCAPS_MIPNEAREST       |
2938                                          WINED3DPTFILTERCAPS_NEAREST;
2939     } else
2940         pCaps->VolumeTextureFilterCaps = 0;
2941
2942     pCaps->TextureAddressCaps =  WINED3DPTADDRESSCAPS_INDEPENDENTUV |
2943                                  WINED3DPTADDRESSCAPS_CLAMP  |
2944                                  WINED3DPTADDRESSCAPS_WRAP;
2945
2946     if (GL_SUPPORT(ARB_TEXTURE_BORDER_CLAMP)) {
2947         pCaps->TextureAddressCaps |= WINED3DPTADDRESSCAPS_BORDER;
2948     }
2949     if (GL_SUPPORT(ARB_TEXTURE_MIRRORED_REPEAT)) {
2950         pCaps->TextureAddressCaps |= WINED3DPTADDRESSCAPS_MIRROR;
2951     }
2952     if (GL_SUPPORT(ATI_TEXTURE_MIRROR_ONCE)) {
2953         pCaps->TextureAddressCaps |= WINED3DPTADDRESSCAPS_MIRRORONCE;
2954     }
2955
2956     if (GL_SUPPORT(EXT_TEXTURE3D)) {
2957         pCaps->VolumeTextureAddressCaps =  WINED3DPTADDRESSCAPS_INDEPENDENTUV |
2958                                            WINED3DPTADDRESSCAPS_CLAMP  |
2959                                            WINED3DPTADDRESSCAPS_WRAP;
2960         if (GL_SUPPORT(ARB_TEXTURE_BORDER_CLAMP)) {
2961             pCaps->VolumeTextureAddressCaps |= WINED3DPTADDRESSCAPS_BORDER;
2962         }
2963         if (GL_SUPPORT(ARB_TEXTURE_MIRRORED_REPEAT)) {
2964             pCaps->VolumeTextureAddressCaps |= WINED3DPTADDRESSCAPS_MIRROR;
2965         }
2966         if (GL_SUPPORT(ATI_TEXTURE_MIRROR_ONCE)) {
2967             pCaps->VolumeTextureAddressCaps |= WINED3DPTADDRESSCAPS_MIRRORONCE;
2968         }
2969     } else
2970         pCaps->VolumeTextureAddressCaps = 0;
2971
2972     pCaps->LineCaps = WINED3DLINECAPS_TEXTURE |
2973                       WINED3DLINECAPS_ZTEST;
2974                       /* FIXME: Add
2975                         WINED3DLINECAPS_BLEND
2976                         WINED3DLINECAPS_ALPHACMP
2977                         WINED3DLINECAPS_FOG */
2978
2979     pCaps->MaxTextureWidth  = GL_LIMITS(texture_size);
2980     pCaps->MaxTextureHeight = GL_LIMITS(texture_size);
2981
2982     if(GL_SUPPORT(EXT_TEXTURE3D))
2983         pCaps->MaxVolumeExtent = GL_LIMITS(texture3d_size);
2984     else
2985         pCaps->MaxVolumeExtent = 0;
2986
2987     pCaps->MaxTextureRepeat = 32768;
2988     pCaps->MaxTextureAspectRatio = GL_LIMITS(texture_size);
2989     pCaps->MaxVertexW = 1.0;
2990
2991     pCaps->GuardBandLeft = 0;
2992     pCaps->GuardBandTop = 0;
2993     pCaps->GuardBandRight = 0;
2994     pCaps->GuardBandBottom = 0;
2995
2996     pCaps->ExtentsAdjust = 0;
2997
2998     pCaps->StencilCaps =  WINED3DSTENCILCAPS_DECRSAT |
2999                           WINED3DSTENCILCAPS_INCRSAT |
3000                           WINED3DSTENCILCAPS_INVERT  |
3001                           WINED3DSTENCILCAPS_KEEP    |
3002                           WINED3DSTENCILCAPS_REPLACE |
3003                           WINED3DSTENCILCAPS_ZERO;
3004     if (GL_SUPPORT(EXT_STENCIL_WRAP)) {
3005         pCaps->StencilCaps |= WINED3DSTENCILCAPS_DECR  |
3006                               WINED3DSTENCILCAPS_INCR;
3007     }
3008     if ( This->dxVersion > 8 &&
3009         ( GL_SUPPORT(EXT_STENCIL_TWO_SIDE) ||
3010             GL_SUPPORT(ATI_SEPARATE_STENCIL) ) ) {
3011         pCaps->StencilCaps |= WINED3DSTENCILCAPS_TWOSIDED;
3012     }
3013
3014     pCaps->FVFCaps = WINED3DFVFCAPS_PSIZE | 0x0008; /* 8 texture coords */
3015
3016     pCaps->MaxUserClipPlanes       = GL_LIMITS(clipplanes);
3017     pCaps->MaxActiveLights         = GL_LIMITS(lights);
3018
3019     pCaps->MaxVertexBlendMatrices      = GL_LIMITS(blends);
3020     pCaps->MaxVertexBlendMatrixIndex   = 0;
3021
3022     pCaps->MaxAnisotropy   = GL_LIMITS(anisotropy);
3023     pCaps->MaxPointSize    = GL_LIMITS(pointsize);
3024
3025
3026     pCaps->VertexProcessingCaps = WINED3DVTXPCAPS_DIRECTIONALLIGHTS |
3027                                   WINED3DVTXPCAPS_MATERIALSOURCE7   |
3028                                   WINED3DVTXPCAPS_POSITIONALLIGHTS  |
3029                                   WINED3DVTXPCAPS_LOCALVIEWER       |
3030                                   WINED3DVTXPCAPS_VERTEXFOG         |
3031                                   WINED3DVTXPCAPS_TEXGEN;
3032                                   /* FIXME: Add 
3033                                      D3DVTXPCAPS_TWEENING, D3DVTXPCAPS_TEXGEN_SPHEREMAP */
3034
3035     pCaps->MaxPrimitiveCount   = 0xFFFFF; /* For now set 2^20-1 which is used by most >=Geforce3/Radeon8500 cards */
3036     pCaps->MaxVertexIndex      = 0xFFFFF;
3037     pCaps->MaxStreams          = MAX_STREAMS;
3038     pCaps->MaxStreamStride     = 1024;
3039
3040     /* d3d9.dll sets D3DDEVCAPS2_CAN_STRETCHRECT_FROM_TEXTURES here because StretchRects is implemented in d3d9 */
3041     pCaps->DevCaps2                          = WINED3DDEVCAPS2_STREAMOFFSET;
3042     /* TODO: VS3.0 needs at least D3DDEVCAPS2_VERTEXELEMENTSCANSHARESTREAMOFFSET */
3043     pCaps->MaxNpatchTessellationLevel        = 0;
3044     pCaps->MasterAdapterOrdinal              = 0;
3045     pCaps->AdapterOrdinalInGroup             = 0;
3046     pCaps->NumberOfAdaptersInGroup           = 1;
3047
3048     pCaps->NumSimultaneousRTs = GL_LIMITS(buffers);
3049
3050     pCaps->StretchRectFilterCaps             = WINED3DPTFILTERCAPS_MINFPOINT  |
3051                                                 WINED3DPTFILTERCAPS_MAGFPOINT  |
3052                                                 WINED3DPTFILTERCAPS_MINFLINEAR |
3053                                                 WINED3DPTFILTERCAPS_MAGFLINEAR;
3054     pCaps->VertexTextureFilterCaps           = 0;
3055
3056     memset(&shader_caps, 0, sizeof(shader_caps));
3057     shader_backend = select_shader_backend(Adapter, DeviceType);
3058     shader_backend->shader_get_caps(DeviceType, &GLINFO_LOCATION, &shader_caps);
3059
3060     /* This takes care for disabling vertex shader or pixel shader caps while leaving the other one enabled.
3061      * Ignore shader model capabilities if disabled in config
3062      */
3063     if(vs_selected_mode == SHADER_NONE) {
3064         TRACE_(d3d_caps)("Vertex shader disabled in config, reporting version 0.0\n");
3065         pCaps->VertexShaderVersion          = WINED3DVS_VERSION(0,0);
3066         pCaps->MaxVertexShaderConst         = 0;
3067     } else {
3068         pCaps->VertexShaderVersion          = shader_caps.VertexShaderVersion;
3069         pCaps->MaxVertexShaderConst         = shader_caps.MaxVertexShaderConst;
3070     }
3071
3072     if(ps_selected_mode == SHADER_NONE) {
3073         TRACE_(d3d_caps)("Pixel shader disabled in config, reporting version 0.0\n");
3074         pCaps->PixelShaderVersion           = WINED3DPS_VERSION(0,0);
3075         pCaps->PixelShader1xMaxValue        = 0.0;
3076     } else {
3077         pCaps->PixelShaderVersion           = shader_caps.PixelShaderVersion;
3078         pCaps->PixelShader1xMaxValue        = shader_caps.PixelShader1xMaxValue;
3079     }
3080
3081     pCaps->TextureOpCaps                    = shader_caps.TextureOpCaps;
3082     pCaps->MaxTextureBlendStages            = shader_caps.MaxTextureBlendStages;
3083     pCaps->MaxSimultaneousTextures          = shader_caps.MaxSimultaneousTextures;
3084     pCaps->VS20Caps                         = shader_caps.VS20Caps;
3085     pCaps->MaxVShaderInstructionsExecuted   = shader_caps.MaxVShaderInstructionsExecuted;
3086     pCaps->MaxVertexShader30InstructionSlots= shader_caps.MaxVertexShader30InstructionSlots;
3087     pCaps->PS20Caps                         = shader_caps.PS20Caps;
3088     pCaps->MaxPShaderInstructionsExecuted   = shader_caps.MaxPShaderInstructionsExecuted;
3089     pCaps->MaxPixelShader30InstructionSlots = shader_caps.MaxPixelShader30InstructionSlots;
3090
3091     /* The following caps are shader specific, but they are things we cannot detect, or which
3092      * are the same among all shader models. So to avoid code duplication set the shader version
3093      * specific, but otherwise constant caps here
3094      */
3095     if(pCaps->VertexShaderVersion == WINED3DVS_VERSION(3,0)) {
3096         /* Where possible set the caps based on OpenGL extensions and if they aren't set (in case of software rendering)
3097         use the VS 3.0 from MSDN or else if there's OpenGL spec use a hardcoded value minimum VS3.0 value. */
3098         pCaps->VS20Caps.Caps                     = WINED3DVS20CAPS_PREDICATION;
3099         pCaps->VS20Caps.DynamicFlowControlDepth  = WINED3DVS20_MAX_DYNAMICFLOWCONTROLDEPTH; /* VS 3.0 requires MAX_DYNAMICFLOWCONTROLDEPTH (24) */
3100         pCaps->VS20Caps.NumTemps                 = max(32, GLINFO_LOCATION.vs_arb_max_temps);
3101         pCaps->VS20Caps.StaticFlowControlDepth   = WINED3DVS20_MAX_STATICFLOWCONTROLDEPTH ; /* level of nesting in loops / if-statements; VS 3.0 requires MAX (4) */
3102
3103         pCaps->MaxVShaderInstructionsExecuted    = 65535; /* VS 3.0 needs at least 65535, some cards even use 2^32-1 */
3104         pCaps->MaxVertexShader30InstructionSlots = max(512, GLINFO_LOCATION.vs_arb_max_instructions);
3105     } else if(pCaps->VertexShaderVersion == WINED3DVS_VERSION(2,0)) {
3106         pCaps->VS20Caps.Caps                     = 0;
3107         pCaps->VS20Caps.DynamicFlowControlDepth  = WINED3DVS20_MIN_DYNAMICFLOWCONTROLDEPTH;
3108         pCaps->VS20Caps.NumTemps                 = max(12, GLINFO_LOCATION.vs_arb_max_temps);
3109         pCaps->VS20Caps.StaticFlowControlDepth   = 1;
3110
3111         pCaps->MaxVShaderInstructionsExecuted    = 65535;
3112         pCaps->MaxVertexShader30InstructionSlots = 0;
3113     } else { /* VS 1.x */
3114         pCaps->VS20Caps.Caps                     = 0;
3115         pCaps->VS20Caps.DynamicFlowControlDepth  = 0;
3116         pCaps->VS20Caps.NumTemps                 = 0;
3117         pCaps->VS20Caps.StaticFlowControlDepth   = 0;
3118
3119         pCaps->MaxVShaderInstructionsExecuted    = 0;
3120         pCaps->MaxVertexShader30InstructionSlots = 0;
3121     }
3122
3123     if(pCaps->PixelShaderVersion == WINED3DPS_VERSION(3,0)) {
3124         /* Where possible set the caps based on OpenGL extensions and if they aren't set (in case of software rendering)
3125         use the PS 3.0 from MSDN or else if there's OpenGL spec use a hardcoded value minimum PS 3.0 value. */
3126
3127         /* 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 */
3128         pCaps->PS20Caps.Caps                     = WINED3DPS20CAPS_ARBITRARYSWIZZLE     |
3129                 WINED3DPS20CAPS_GRADIENTINSTRUCTIONS |
3130                 WINED3DPS20CAPS_PREDICATION          |
3131                 WINED3DPS20CAPS_NODEPENDENTREADLIMIT |
3132                 WINED3DPS20CAPS_NOTEXINSTRUCTIONLIMIT;
3133         pCaps->PS20Caps.DynamicFlowControlDepth  = WINED3DPS20_MAX_DYNAMICFLOWCONTROLDEPTH; /* PS 3.0 requires MAX_DYNAMICFLOWCONTROLDEPTH (24) */
3134         pCaps->PS20Caps.NumTemps                 = max(32, GLINFO_LOCATION.ps_arb_max_temps);
3135         pCaps->PS20Caps.StaticFlowControlDepth   = WINED3DPS20_MAX_STATICFLOWCONTROLDEPTH; /* PS 3.0 requires MAX_STATICFLOWCONTROLDEPTH (4) */
3136         pCaps->PS20Caps.NumInstructionSlots      = WINED3DPS20_MAX_NUMINSTRUCTIONSLOTS; /* PS 3.0 requires MAX_NUMINSTRUCTIONSLOTS (512) */
3137
3138         pCaps->MaxPShaderInstructionsExecuted    = 65535;
3139         pCaps->MaxPixelShader30InstructionSlots  = max(WINED3DMIN30SHADERINSTRUCTIONS, GLINFO_LOCATION.ps_arb_max_instructions);
3140     } else if(pCaps->PixelShaderVersion == WINED3DPS_VERSION(2,0)) {
3141         /* Below we assume PS2.0 specs, not extended 2.0a(GeforceFX)/2.0b(Radeon R3xx) ones */
3142         pCaps->PS20Caps.Caps                     = 0;
3143         pCaps->PS20Caps.DynamicFlowControlDepth  = 0; /* WINED3DVS20_MIN_DYNAMICFLOWCONTROLDEPTH = 0 */
3144         pCaps->PS20Caps.NumTemps                 = max(12, GLINFO_LOCATION.ps_arb_max_temps);
3145         pCaps->PS20Caps.StaticFlowControlDepth   = WINED3DPS20_MIN_STATICFLOWCONTROLDEPTH; /* Minimum: 1 */
3146         pCaps->PS20Caps.NumInstructionSlots      = WINED3DPS20_MIN_NUMINSTRUCTIONSLOTS; /* Minimum number (64 ALU + 32 Texture), a GeforceFX uses 512 */
3147
3148         pCaps->MaxPShaderInstructionsExecuted    = 512; /* Minimum value, a GeforceFX uses 1024 */
3149         pCaps->MaxPixelShader30InstructionSlots  = 0;
3150     } else { /* PS 1.x */
3151         pCaps->PS20Caps.Caps                     = 0;
3152         pCaps->PS20Caps.DynamicFlowControlDepth  = 0;
3153         pCaps->PS20Caps.NumTemps                 = 0;
3154         pCaps->PS20Caps.StaticFlowControlDepth   = 0;
3155         pCaps->PS20Caps.NumInstructionSlots      = 0;
3156
3157         pCaps->MaxPShaderInstructionsExecuted    = 0;
3158         pCaps->MaxPixelShader30InstructionSlots  = 0;
3159     }
3160
3161     if(pCaps->VertexShaderVersion >= WINED3DVS_VERSION(2,0)) {
3162         /* OpenGL supports all the formats below, perhaps not always
3163          * without conversion, but it supports them.
3164          * Further GLSL doesn't seem to have an official unsigned type so
3165          * don't advertise it yet as I'm not sure how we handle it.
3166          * We might need to add some clamping in the shader engine to
3167          * support it.
3168          * TODO: WINED3DDTCAPS_USHORT2N, WINED3DDTCAPS_USHORT4N, WINED3DDTCAPS_UDEC3, WINED3DDTCAPS_DEC3N */
3169         pCaps->DeclTypes = WINED3DDTCAPS_UBYTE4    |
3170                            WINED3DDTCAPS_UBYTE4N   |
3171                            WINED3DDTCAPS_SHORT2N   |
3172                            WINED3DDTCAPS_SHORT4N;
3173         if (GL_SUPPORT(NV_HALF_FLOAT)) {
3174             pCaps->DeclTypes |= WINED3DDTCAPS_FLOAT16_2 |
3175                                 WINED3DDTCAPS_FLOAT16_4;
3176         }
3177     } else
3178         pCaps->DeclTypes                         = 0;
3179
3180     return WINED3D_OK;
3181 }
3182
3183 /* Note due to structure differences between dx8 and dx9 D3DPRESENT_PARAMETERS,
3184    and fields being inserted in the middle, a new structure is used in place    */
3185 static HRESULT  WINAPI IWineD3DImpl_CreateDevice(IWineD3D *iface, UINT Adapter, WINED3DDEVTYPE DeviceType, HWND hFocusWindow,
3186                                            DWORD BehaviourFlags, IWineD3DDevice** ppReturnedDeviceInterface,
3187                                            IUnknown *parent) {
3188
3189     IWineD3DDeviceImpl *object  = NULL;
3190     IWineD3DImpl       *This    = (IWineD3DImpl *)iface;
3191     WINED3DDISPLAYMODE  mode;
3192     int i;
3193
3194     /* Validate the adapter number. If no adapters are available(no GL), ignore the adapter
3195      * number and create a device without a 3D adapter for 2D only operation.
3196      */
3197     if (IWineD3D_GetAdapterCount(iface) && Adapter >= IWineD3D_GetAdapterCount(iface)) {
3198         return WINED3DERR_INVALIDCALL;
3199     }
3200
3201     /* Create a WineD3DDevice object */
3202     object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IWineD3DDeviceImpl));
3203     *ppReturnedDeviceInterface = (IWineD3DDevice *)object;
3204     TRACE("Created WineD3DDevice object @ %p\n", object);
3205     if (NULL == object) {
3206       return WINED3DERR_OUTOFVIDEOMEMORY;
3207     }
3208
3209     /* Set up initial COM information */
3210     object->lpVtbl  = &IWineD3DDevice_Vtbl;
3211     object->ref     = 1;
3212     object->wineD3D = iface;
3213     object->adapter = numAdapters ? &Adapters[Adapter] : NULL;
3214     IWineD3D_AddRef(object->wineD3D);
3215     object->parent  = parent;
3216     list_init(&object->resources);
3217     list_init(&object->shaders);
3218
3219     if(This->dxVersion == 7) {
3220         object->surface_alignment = 8;
3221     } else {
3222         object->surface_alignment = 4;
3223     }
3224     object->posFixup[0] = 1.0; /* This is needed to get the x coord unmodified through a MAD */
3225
3226     /* Set the state up as invalid until the device is fully created */
3227     object->state   = WINED3DERR_DRIVERINTERNALERROR;
3228
3229     TRACE("(%p)->(Adptr:%d, DevType: %x, FocusHwnd: %p, BehFlags: %x, RetDevInt: %p)\n", This, Adapter, DeviceType,
3230           hFocusWindow, BehaviourFlags, ppReturnedDeviceInterface);
3231
3232     /* Save the creation parameters */
3233     object->createParms.AdapterOrdinal = Adapter;
3234     object->createParms.DeviceType     = DeviceType;
3235     object->createParms.hFocusWindow   = hFocusWindow;
3236     object->createParms.BehaviorFlags  = BehaviourFlags;
3237
3238     /* Initialize other useful values */
3239     object->adapterNo                    = Adapter;
3240     object->devType                      = DeviceType;
3241
3242     select_shader_mode(&GLINFO_LOCATION, DeviceType, &object->ps_selected_mode, &object->vs_selected_mode);
3243     object->shader_backend = select_shader_backend(Adapter, DeviceType);
3244
3245     /* Prefer the vtable with functions optimized for single dirtifyable objects if the shader
3246      * model can deal with that. It is essentially the same, just with adjusted
3247      * Set*ShaderConstantF implementations
3248      */
3249     if(object->shader_backend->shader_dirtifyable_constants((IWineD3DDevice *) object)) {
3250         object->lpVtbl  = &IWineD3DDevice_DirtyConst_Vtbl;
3251     }
3252
3253     /* set the state of the device to valid */
3254     object->state = WINED3D_OK;
3255
3256     /* Get the initial screen setup for ddraw */
3257     IWineD3DImpl_GetAdapterDisplayMode(iface, Adapter, &mode);
3258
3259     object->ddraw_width = mode.Width;
3260     object->ddraw_height = mode.Height;
3261     object->ddraw_format = mode.Format;
3262
3263     for(i = 0; i < PATCHMAP_SIZE; i++) {
3264         list_init(&object->patches[i]);
3265     }
3266     return WINED3D_OK;
3267 }
3268 #undef GLINFO_LOCATION
3269
3270 static HRESULT WINAPI IWineD3DImpl_GetParent(IWineD3D *iface, IUnknown **pParent) {
3271     IWineD3DImpl *This = (IWineD3DImpl *)iface;
3272     IUnknown_AddRef(This->parent);
3273     *pParent = This->parent;
3274     return WINED3D_OK;
3275 }
3276
3277 ULONG WINAPI D3DCB_DefaultDestroySurface(IWineD3DSurface *pSurface) {
3278     IUnknown* surfaceParent;
3279     TRACE("(%p) call back\n", pSurface);
3280
3281     /* Now, release the parent, which will take care of cleaning up the surface for us */
3282     IWineD3DSurface_GetParent(pSurface, &surfaceParent);
3283     IUnknown_Release(surfaceParent);
3284     return IUnknown_Release(surfaceParent);
3285 }
3286
3287 ULONG WINAPI D3DCB_DefaultDestroyVolume(IWineD3DVolume *pVolume) {
3288     IUnknown* volumeParent;
3289     TRACE("(%p) call back\n", pVolume);
3290
3291     /* Now, release the parent, which will take care of cleaning up the volume for us */
3292     IWineD3DVolume_GetParent(pVolume, &volumeParent);
3293     IUnknown_Release(volumeParent);
3294     return IUnknown_Release(volumeParent);
3295 }
3296
3297 static BOOL implementation_is_apple(WineD3D_GL_Info *gl_info) {
3298     /* MacOS has various specialities in the extensions it advertises. Some have to be loaded from
3299      * the opengl 1.2+ core, while other extensions are advertised, but software emulated. So try to
3300      * detect the Apple OpenGL implementation to apply some extension fixups afterwards.
3301      *
3302      * Detecting this isn't really easy. The vendor string doesn't mention Apple. Compile-time checks
3303      * aren't sufficient either because a Linux binary may display on a macos X server via remote X11.
3304      * So try to detect the GL implementation by looking at certain Apple extensions. Some extensions
3305      * like client storage might be supported on other implementations too, but GL_APPLE_flush_render
3306      * is specific to the Mac OS X window management, and GL_APPLE_ycbcr_422 is QuickTime specific. So
3307      * the chance that other implementations support them is rather small since Win32 QuickTime uses
3308      * DirectDraw, not OpenGL.
3309      */
3310     if(gl_info->supported[APPLE_FENCE] &&
3311        gl_info->supported[APPLE_CLIENT_STORAGE] &&
3312        gl_info->supported[APPLE_FLUSH_RENDER] &&
3313        gl_info->supported[APPLE_YCBCR_422]) {
3314         TRACE_(d3d_caps)("GL_APPLE_fence, GL_APPLE_client_storage, GL_APPLE_flush_render and GL_ycbcr_422 are supported\n");
3315         TRACE_(d3d_caps)("Activating MacOS fixups\n");
3316         return TRUE;
3317     } else {
3318         TRACE_(d3d_caps)("Apple extensions are not supported\n");
3319         TRACE_(d3d_caps)("Not activating MacOS fixups\n");
3320         return FALSE;
3321     }
3322 }
3323
3324 #define GLINFO_LOCATION (*gl_info)
3325 static void test_pbo_functionality(WineD3D_GL_Info *gl_info) {
3326     /* Some OpenGL implementations, namely Apple's Geforce 8 driver, advertises PBOs,
3327      * but glTexSubImage from a PBO fails miserably, with the first line repeated over
3328      * all the texture. This function detects this bug by its symptom and disables PBOs
3329      * if the test fails.
3330      *
3331      * The test uplaods a 4x4 texture via the PBO in the "native" format GL_BGRA,
3332      * GL_UNSIGNED_INT_8_8_8_8_REV. This format triggers the bug, and it is what we use
3333      * for D3DFMT_A8R8G8B8. Then the texture is read back without any PBO and the data
3334      * read back is compared to the original. If they are equal PBOs are assumed to work,
3335      * otherwise the PBO extension is disabled.
3336      */
3337     GLuint texture, pbo;
3338     static const unsigned int pattern[] = {
3339         0x00000000, 0x000000ff, 0x0000ff00, 0x40ff0000,
3340         0x80ffffff, 0x40ffff00, 0x00ff00ff, 0x0000ffff,
3341         0x00ffff00, 0x00ff00ff, 0x0000ffff, 0x000000ff,
3342         0x80ff00ff, 0x0000ffff, 0x00ff00ff, 0x40ff00ff
3343     };
3344     unsigned int check[sizeof(pattern) / sizeof(pattern[0])];
3345
3346     if(!gl_info->supported[ARB_PIXEL_BUFFER_OBJECT]) {
3347         /* No PBO -> No point in testing them */
3348         return;
3349     }
3350
3351     while(glGetError());
3352     glGenTextures(1, &texture);
3353     glBindTexture(GL_TEXTURE_2D, texture);
3354     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 4, 4, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, 0);
3355     checkGLcall("Specifying the PBO test texture\n");
3356
3357     GL_EXTCALL(glGenBuffersARB(1, &pbo));
3358     GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, pbo));
3359     GL_EXTCALL(glBufferDataARB(GL_PIXEL_UNPACK_BUFFER_ARB, sizeof(pattern), pattern, GL_STREAM_DRAW_ARB));
3360     checkGLcall("Specifying the PBO test pbo\n");
3361
3362     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 4, 4, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL);
3363     checkGLcall("Loading the PBO test texture\n");
3364
3365     GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0));
3366     glFinish(); /* just to be sure */
3367
3368     memset(check, 0, sizeof(check));
3369     glGetTexImage(GL_TEXTURE_2D, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, check);
3370     checkGLcall("Reading back the PBO test texture\n");
3371
3372     glDeleteTextures(1, &texture);
3373     GL_EXTCALL(glDeleteBuffersARB(1, &pbo));
3374     checkGLcall("PBO test cleanup\n");
3375
3376     if(memcmp(check, pattern, sizeof(check)) != 0) {
3377         WARN_(d3d_caps)("PBO test failed, read back data doesn't match original\n");
3378         WARN_(d3d_caps)("Disabling PBOs. This may result in slower performance\n");
3379         gl_info->supported[ARB_PIXEL_BUFFER_OBJECT] = FALSE;
3380     } else {
3381         TRACE_(d3d_caps)("PBO test successful\n");
3382     }
3383 }
3384 #undef GLINFO_LOCATION
3385
3386 /* Certain applications(Steam) complain if we report an outdated driver version. In general,
3387  * reporting a driver version is moot because we are not the Windows driver, and we have different
3388  * bugs, features, etc.
3389  *
3390  * If a card is not found in this table, the gl driver version is reported
3391  */
3392 struct driver_version_information {
3393     WORD vendor;                        /* reported PCI card vendor ID  */
3394     WORD card;                          /* reported PCI card device ID  */
3395     WORD hipart_hi, hipart_lo;          /* driver hiword to report      */
3396     WORD lopart_hi, lopart_lo;          /* driver loword to report      */
3397 };
3398
3399 static const struct driver_version_information driver_version_table[] = {
3400     /* Nvidia drivers. Geforce FX and newer cards are supported by the current driver */
3401     {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCEFX_5200,     7,  15, 10, 16921   },
3402     {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCEFX_5600,     7,  15, 10, 16921   },
3403     {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCEFX_5800,     7,  15, 10, 16921   },
3404     {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_6200,       7,  15, 10, 16921   },
3405     {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_6600GT,     7,  15, 10, 16921   },
3406     {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_6800,       7,  15, 10, 16921   },
3407     {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_7400,       7,  15, 10, 16921   },
3408     {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_7300,       7,  15, 10, 16921   },
3409     {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_7600,       7,  15, 10, 16921   },
3410     {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_7800GT,     7,  15, 10, 16921   },
3411     {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_8300GS,     7,  15, 10, 16921   },
3412     {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_8600GT,     7,  15, 10, 16921   },
3413     {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_8600MGT,    7,  15, 10, 16921   },
3414     {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_8800GTS,    7,  15, 10, 16921   },
3415
3416     /* ATI cards. The driver versions are somewhat similar, but not quite the same. Let's hardcode */
3417     {VENDOR_ATI,        CARD_ATI_RADEON_9500,           6,  14, 10, 6764    },
3418     {VENDOR_ATI,        CARD_ATI_RADEON_X700,           6,  14, 10, 6764    },
3419     {VENDOR_ATI,        CARD_ATI_RADEON_X1600,          6,  14, 10, 6764    },
3420     {VENDOR_ATI,        CARD_ATI_RADEON_HD2300,         6,  14, 10, 6764    },
3421     {VENDOR_ATI,        CARD_ATI_RADEON_HD2600,         6,  14, 10, 6764    },
3422     {VENDOR_ATI,        CARD_ATI_RADEON_HD2900,         6,  14, 10, 6764    },
3423
3424     /* TODO: Add information about legacy nvidia and ATI hardware, Intel and other cards */
3425 };
3426
3427 static void fixup_extensions(WineD3D_GL_Info *gl_info) {
3428     unsigned int i;
3429     BOOL apple = implementation_is_apple(gl_info);
3430
3431     if(apple) {
3432         /* MacOS advertises more GLSL vertex shader uniforms than supported by the hardware, and if more are
3433          * used it falls back to software. While the compiler can detect if the shader uses all declared
3434          * uniforms, the optimization fails if the shader uses relative addressing. So any GLSL shader
3435          * using relative addressing falls back to software.
3436          *
3437          * ARB vp gives the correct amount of uniforms, so use it instead of GLSL
3438          */
3439         if(gl_info->vs_glsl_constantsF <= gl_info->vs_arb_constantsF) {
3440             FIXME("GLSL doesn't advertise more vertex shader uniforms than ARB. Driver fixup outdated?\n");
3441         } else {
3442             TRACE("Driver claims %u GLSL vs uniforms, replacing with %u ARB vp uniforms\n",
3443                   gl_info->vs_glsl_constantsF, gl_info->vs_arb_constantsF);
3444             gl_info->vs_glsl_constantsF = gl_info->vs_arb_constantsF;
3445         }
3446
3447         /* MacOS advertises GL_ARB_texture_non_power_of_two on ATI r500 and earlier cards, although
3448          * these cards only support GL_ARB_texture_rectangle(D3DPTEXTURECAPS_NONPOW2CONDITIONAL).
3449          * If real NP2 textures are used, the driver falls back to software. So remove the supported
3450          * flag for this extension
3451          */
3452         if(gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO] && gl_info->gl_vendor == VENDOR_ATI) {
3453             if(gl_info->gl_card == CARD_ATI_RADEON_X700 || gl_info->gl_card == CARD_ATI_RADEON_X1600 ||
3454                gl_info->gl_card == CARD_ATI_RADEON_9500 || gl_info->gl_card == CARD_ATI_RADEON_8500  ||
3455                gl_info->gl_card == CARD_ATI_RADEON_7200 || gl_info->gl_card == CARD_ATI_RAGE_128PRO) {
3456                 TRACE("GL_ARB_texture_non_power_of_two advertised on R500 or earlier card, removing\n");
3457                 gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO] = FALSE;
3458                 gl_info->supported[ARB_TEXTURE_RECTANGLE] = TRUE;
3459             }
3460         }
3461
3462         /* The Intel GPUs on MacOS set the .w register of texcoords to 0.0 by default, which causes problems
3463          * with fixed function fragment processing. Ideally this flag should be detected with a test shader
3464          * and OpenGL feedback mode, but some GL implementations (MacOS ATI at least, probably all MacOS ones)
3465          * do not like vertex shaders in feedback mode and return an error, even though it should be valid
3466          * according to the spec.
3467          *
3468          * We don't want to enable this on all cards, as it adds an extra instruction per texcoord used. This
3469          * makes the shader slower and eats instruction slots which should be available to the d3d app.
3470          *
3471          * ATI Radeon HD 2xxx cards on MacOS have the issue. Instead of checking for the buggy cards, blacklist
3472          * all radeon cards on Macs and whitelist the good ones. That way we're prepared for the future. If
3473          * this workaround is activated on cards that do not need it, it won't break things, just affect
3474          * performance negatively.
3475          */
3476         if(gl_info->gl_vendor == VENDOR_INTEL ||
3477            (gl_info->gl_vendor == VENDOR_ATI && gl_info->gl_card != CARD_ATI_RADEON_X1600)) {
3478             TRACE("Enabling vertex texture coord fixes in vertex shaders\n");
3479             gl_info->set_texcoord_w = TRUE;
3480         }
3481     }
3482
3483     /* Find out if PBOs work as they are supposed to */
3484     test_pbo_functionality(gl_info);
3485
3486     /* Fixup the driver version */
3487     for(i = 0; i < (sizeof(driver_version_table) / sizeof(driver_version_table[0])); i++) {
3488         if(gl_info->gl_vendor == driver_version_table[i].vendor &&
3489            gl_info->gl_card   == driver_version_table[i].card) {
3490             TRACE_(d3d_caps)("Found card 0x%04x, 0x%04x in driver version DB\n", gl_info->gl_vendor, gl_info->gl_card);
3491
3492             gl_info->driver_version        = MAKEDWORD_VERSION(driver_version_table[i].lopart_hi,
3493                                                                driver_version_table[i].lopart_lo);
3494             gl_info->driver_version_hipart = MAKEDWORD_VERSION(driver_version_table[i].hipart_hi,
3495                                                                driver_version_table[i].hipart_lo);
3496             break;
3497         }
3498     }
3499 }
3500
3501 void invalid_func(void *data) {
3502     ERR("Invalid vertex attribute function called\n");
3503     DebugBreak();
3504 }
3505
3506 #define GLINFO_LOCATION (Adapters[0].gl_info)
3507
3508 /* Helper functions for providing vertex data to opengl. The arrays are initialized based on
3509  * the extension detection and are used in drawStridedSlow
3510  */
3511 static void position_d3dcolor(void *data) {
3512     DWORD pos = *((DWORD *) data);
3513
3514     FIXME("Add a test for fixed function position from d3dcolor type\n");
3515     glVertex4s(D3DCOLOR_B_R(pos),
3516                D3DCOLOR_B_G(pos),
3517                D3DCOLOR_B_B(pos),
3518                D3DCOLOR_B_A(pos));
3519 }
3520 static void position_float4(void *data) {
3521     GLfloat *pos = (float *) data;
3522
3523     if (pos[3] < eps && pos[3] > -eps)
3524         glVertex3fv(pos);
3525     else {
3526         float w = 1.0 / pos[3];
3527
3528         glVertex4f(pos[0] * w, pos[1] * w, pos[2] * w, w);
3529     }
3530 }
3531
3532 static void diffuse_d3dcolor(void *data) {
3533     DWORD diffuseColor = *((DWORD *) data);
3534
3535     glColor4ub(D3DCOLOR_B_R(diffuseColor),
3536                D3DCOLOR_B_G(diffuseColor),
3537                D3DCOLOR_B_B(diffuseColor),
3538                D3DCOLOR_B_A(diffuseColor));
3539 }
3540
3541 static void specular_d3dcolor(void *data) {
3542     DWORD specularColor = *((DWORD *) data);
3543
3544     GL_EXTCALL(glSecondaryColor3ubEXT)(D3DCOLOR_B_R(specularColor),
3545                                        D3DCOLOR_B_G(specularColor),
3546                                        D3DCOLOR_B_B(specularColor));
3547 }
3548 static void warn_no_specular_func(void *data) {
3549     WARN("GL_EXT_secondary_color not supported\n");
3550 }
3551
3552 void fillGLAttribFuncs(WineD3D_GL_Info *gl_info) {
3553     position_funcs[WINED3DDECLTYPE_FLOAT1]      = (void *) invalid_func;
3554     position_funcs[WINED3DDECLTYPE_FLOAT2]      = (void *) invalid_func;
3555     position_funcs[WINED3DDECLTYPE_FLOAT3]      = (void *) glVertex3fv;
3556     position_funcs[WINED3DDECLTYPE_FLOAT4]      = (void *) position_float4;
3557     position_funcs[WINED3DDECLTYPE_D3DCOLOR]    = (void *) position_d3dcolor;
3558     position_funcs[WINED3DDECLTYPE_UBYTE4]      = (void *) invalid_func;
3559     position_funcs[WINED3DDECLTYPE_SHORT2]      = (void *) invalid_func;
3560     position_funcs[WINED3DDECLTYPE_SHORT4]      = (void *) glVertex2sv;
3561     position_funcs[WINED3DDECLTYPE_UBYTE4N]     = (void *) invalid_func;
3562     position_funcs[WINED3DDECLTYPE_SHORT2N]     = (void *) invalid_func;
3563     position_funcs[WINED3DDECLTYPE_SHORT4N]     = (void *) invalid_func;
3564     position_funcs[WINED3DDECLTYPE_USHORT2N]    = (void *) invalid_func;
3565     position_funcs[WINED3DDECLTYPE_USHORT4N]    = (void *) invalid_func;
3566     position_funcs[WINED3DDECLTYPE_UDEC3]       = (void *) invalid_func;
3567     position_funcs[WINED3DDECLTYPE_DEC3N]       = (void *) invalid_func;
3568     position_funcs[WINED3DDECLTYPE_FLOAT16_2]   = (void *) invalid_func;
3569     position_funcs[WINED3DDECLTYPE_FLOAT16_4]   = (void *) invalid_func;
3570
3571     diffuse_funcs[WINED3DDECLTYPE_FLOAT1]       = (void *) invalid_func;
3572     diffuse_funcs[WINED3DDECLTYPE_FLOAT2]       = (void *) invalid_func;
3573     diffuse_funcs[WINED3DDECLTYPE_FLOAT3]       = (void *) glColor3fv;
3574     diffuse_funcs[WINED3DDECLTYPE_FLOAT4]       = (void *) glColor4fv;
3575     diffuse_funcs[WINED3DDECLTYPE_D3DCOLOR]     = (void *) diffuse_d3dcolor;
3576     diffuse_funcs[WINED3DDECLTYPE_UBYTE4]       = (void *) invalid_func;
3577     diffuse_funcs[WINED3DDECLTYPE_SHORT2]       = (void *) invalid_func;
3578     diffuse_funcs[WINED3DDECLTYPE_SHORT4]       = (void *) invalid_func;
3579     diffuse_funcs[WINED3DDECLTYPE_UBYTE4N]      = (void *) glColor4ubv;
3580     diffuse_funcs[WINED3DDECLTYPE_SHORT2N]      = (void *) invalid_func;
3581     diffuse_funcs[WINED3DDECLTYPE_SHORT4N]      = (void *) glColor4sv;
3582     diffuse_funcs[WINED3DDECLTYPE_USHORT2N]     = (void *) invalid_func;
3583     diffuse_funcs[WINED3DDECLTYPE_USHORT4N]     = (void *) glColor4usv;
3584     diffuse_funcs[WINED3DDECLTYPE_UDEC3]        = (void *) invalid_func;
3585     diffuse_funcs[WINED3DDECLTYPE_DEC3N]        = (void *) invalid_func;
3586     diffuse_funcs[WINED3DDECLTYPE_FLOAT16_2]    = (void *) invalid_func;
3587     diffuse_funcs[WINED3DDECLTYPE_FLOAT16_4]    = (void *) invalid_func;
3588
3589     /* No 4 component entry points here */
3590     specular_funcs[WINED3DDECLTYPE_FLOAT1]      = (void *) invalid_func;
3591     specular_funcs[WINED3DDECLTYPE_FLOAT2]      = (void *) invalid_func;
3592     if(GL_SUPPORT(EXT_SECONDARY_COLOR)) {
3593         specular_funcs[WINED3DDECLTYPE_FLOAT3]      = (void *) GL_EXTCALL(glSecondaryColor3fvEXT);
3594     } else {
3595         specular_funcs[WINED3DDECLTYPE_FLOAT3]      = (void *) warn_no_specular_func;
3596     }
3597     specular_funcs[WINED3DDECLTYPE_FLOAT4]      = (void *) invalid_func;
3598     if(GL_SUPPORT(EXT_SECONDARY_COLOR)) {
3599         specular_funcs[WINED3DDECLTYPE_D3DCOLOR]    = (void *) specular_d3dcolor;
3600     } else {
3601         specular_funcs[WINED3DDECLTYPE_D3DCOLOR]      = (void *) warn_no_specular_func;
3602     }
3603     specular_funcs[WINED3DDECLTYPE_UBYTE4]      = (void *) invalid_func;
3604     specular_funcs[WINED3DDECLTYPE_SHORT2]      = (void *) invalid_func;
3605     specular_funcs[WINED3DDECLTYPE_SHORT4]      = (void *) invalid_func;
3606     specular_funcs[WINED3DDECLTYPE_UBYTE4N]     = (void *) invalid_func;
3607     specular_funcs[WINED3DDECLTYPE_SHORT2N]     = (void *) invalid_func;
3608     specular_funcs[WINED3DDECLTYPE_SHORT4N]     = (void *) invalid_func;
3609     specular_funcs[WINED3DDECLTYPE_USHORT2N]    = (void *) invalid_func;
3610     specular_funcs[WINED3DDECLTYPE_USHORT4N]    = (void *) invalid_func;
3611     specular_funcs[WINED3DDECLTYPE_UDEC3]       = (void *) invalid_func;
3612     specular_funcs[WINED3DDECLTYPE_DEC3N]       = (void *) invalid_func;
3613     specular_funcs[WINED3DDECLTYPE_FLOAT16_2]   = (void *) invalid_func;
3614     specular_funcs[WINED3DDECLTYPE_FLOAT16_4]   = (void *) invalid_func;
3615
3616     /* Only 3 component entry points here. Test how others behave. Float4 normals are used
3617      * by one of our tests, trying to pass it to the pixel shader, which fails on Windows.
3618      */
3619     normal_funcs[WINED3DDECLTYPE_FLOAT1]         = (void *) invalid_func;
3620     normal_funcs[WINED3DDECLTYPE_FLOAT2]         = (void *) invalid_func;
3621     normal_funcs[WINED3DDECLTYPE_FLOAT3]         = (void *) glNormal3fv;
3622     normal_funcs[WINED3DDECLTYPE_FLOAT4]         = (void *) glNormal3fv; /* Just ignore the 4th value */
3623     normal_funcs[WINED3DDECLTYPE_D3DCOLOR]       = (void *) invalid_func;
3624     normal_funcs[WINED3DDECLTYPE_UBYTE4]         = (void *) invalid_func;
3625     normal_funcs[WINED3DDECLTYPE_SHORT2]         = (void *) invalid_func;
3626     normal_funcs[WINED3DDECLTYPE_SHORT4]         = (void *) invalid_func;
3627     normal_funcs[WINED3DDECLTYPE_UBYTE4N]        = (void *) invalid_func;
3628     normal_funcs[WINED3DDECLTYPE_SHORT2N]        = (void *) invalid_func;
3629     normal_funcs[WINED3DDECLTYPE_SHORT4N]        = (void *) invalid_func;
3630     normal_funcs[WINED3DDECLTYPE_USHORT2N]       = (void *) invalid_func;
3631     normal_funcs[WINED3DDECLTYPE_USHORT4N]       = (void *) invalid_func;
3632     normal_funcs[WINED3DDECLTYPE_UDEC3]          = (void *) invalid_func;
3633     normal_funcs[WINED3DDECLTYPE_DEC3N]          = (void *) invalid_func;
3634     normal_funcs[WINED3DDECLTYPE_FLOAT16_2]      = (void *) invalid_func;
3635     normal_funcs[WINED3DDECLTYPE_FLOAT16_4]      = (void *) invalid_func;
3636 }
3637
3638 #define PUSH1(att)        attribs[nAttribs++] = (att);
3639 BOOL InitAdapters(void) {
3640     static HMODULE mod_gl;
3641     BOOL ret;
3642     int ps_selected_mode, vs_selected_mode;
3643
3644     /* No need to hold any lock. The calling library makes sure only one thread calls
3645      * wined3d simultaneously
3646      */
3647     if(numAdapters > 0) return TRUE;
3648
3649     TRACE("Initializing adapters\n");
3650
3651     if(!mod_gl) {
3652 #ifdef USE_WIN32_OPENGL
3653 #define USE_GL_FUNC(pfn) pfn = (void*)GetProcAddress(mod_gl, #pfn);
3654         mod_gl = LoadLibraryA("opengl32.dll");
3655         if(!mod_gl) {
3656             ERR("Can't load opengl32.dll!\n");
3657             return FALSE;
3658         }
3659 #else
3660 #define USE_GL_FUNC(pfn) pfn = (void*)pwglGetProcAddress(#pfn);
3661         /* To bypass the opengl32 thunks load wglGetProcAddress from gdi32 (glXGetProcAddress wrapper) instead of opengl32's */
3662         mod_gl = GetModuleHandleA("gdi32.dll");
3663 #endif
3664     }
3665
3666 /* Load WGL core functions from opengl32.dll */
3667 #define USE_WGL_FUNC(pfn) p##pfn = (void*)GetProcAddress(mod_gl, #pfn);
3668     WGL_FUNCS_GEN;
3669 #undef USE_WGL_FUNC
3670
3671     if(!pwglGetProcAddress) {
3672         ERR("Unable to load wglGetProcAddress!\n");
3673         return FALSE;
3674     }
3675
3676 /* Dynamically load all GL core functions */
3677     GL_FUNCS_GEN;
3678 #undef USE_GL_FUNC
3679
3680     /* For now only one default adapter */
3681     {
3682         int iPixelFormat;
3683         int attribs[8];
3684         int values[8];
3685         int nAttribs = 0;
3686         int res;
3687         WineD3D_PixelFormat *cfgs;
3688         int attribute;
3689         DISPLAY_DEVICEW DisplayDevice;
3690         HDC hdc;
3691
3692         TRACE("Initializing default adapter\n");
3693         Adapters[0].num = 0;
3694         Adapters[0].monitorPoint.x = -1;
3695         Adapters[0].monitorPoint.y = -1;
3696
3697         if (!WineD3D_CreateFakeGLContext()) {
3698             ERR("Failed to get a gl context for default adapter\n");
3699             HeapFree(GetProcessHeap(), 0, Adapters);
3700             WineD3D_ReleaseFakeGLContext();
3701             return FALSE;
3702         }
3703
3704         ret = IWineD3DImpl_FillGLCaps(&Adapters[0].gl_info);
3705         if(!ret) {
3706             ERR("Failed to initialize gl caps for default adapter\n");
3707             HeapFree(GetProcessHeap(), 0, Adapters);
3708             WineD3D_ReleaseFakeGLContext();
3709             return FALSE;
3710         }
3711         ret = initPixelFormats(&Adapters[0].gl_info);
3712         if(!ret) {
3713             ERR("Failed to init gl formats\n");
3714             HeapFree(GetProcessHeap(), 0, Adapters);
3715             WineD3D_ReleaseFakeGLContext();
3716             return FALSE;
3717         }
3718
3719         hdc = pwglGetCurrentDC();
3720         if(!hdc) {
3721             ERR("Failed to get gl HDC\n");
3722             HeapFree(GetProcessHeap(), 0, Adapters);
3723             WineD3D_ReleaseFakeGLContext();
3724             return FALSE;
3725         }
3726
3727         Adapters[0].driver = "Display";
3728         Adapters[0].description = "Direct3D HAL";
3729
3730         /* Use the VideoRamSize registry setting when set */
3731         if(wined3d_settings.emulated_textureram)
3732             Adapters[0].TextureRam = wined3d_settings.emulated_textureram;
3733         else
3734             Adapters[0].TextureRam = Adapters[0].gl_info.vidmem;
3735         Adapters[0].UsedTextureRam = 0;
3736         TRACE("Emulating %dMB of texture ram\n", Adapters[0].TextureRam/(1024*1024));
3737
3738         /* Initialize the Adapter's DeviceName which is required for ChangeDisplaySettings and friends */
3739         DisplayDevice.cb = sizeof(DisplayDevice);
3740         EnumDisplayDevicesW(NULL, 0 /* Adapter 0 = iDevNum 0 */, &DisplayDevice, 0);
3741         TRACE("DeviceName: %s\n", debugstr_w(DisplayDevice.DeviceName));
3742         strcpyW(Adapters[0].DeviceName, DisplayDevice.DeviceName);
3743
3744         attribute = WGL_NUMBER_PIXEL_FORMATS_ARB;
3745         GL_EXTCALL(wglGetPixelFormatAttribivARB(hdc, 0, 0, 1, &attribute, &Adapters[0].nCfgs));
3746
3747         Adapters[0].cfgs = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, Adapters[0].nCfgs *sizeof(WineD3D_PixelFormat));
3748         cfgs = Adapters[0].cfgs;
3749         PUSH1(WGL_RED_BITS_ARB)
3750         PUSH1(WGL_GREEN_BITS_ARB)
3751         PUSH1(WGL_BLUE_BITS_ARB)
3752         PUSH1(WGL_ALPHA_BITS_ARB)
3753         PUSH1(WGL_DEPTH_BITS_ARB)
3754         PUSH1(WGL_STENCIL_BITS_ARB)
3755         PUSH1(WGL_DRAW_TO_WINDOW_ARB)
3756         PUSH1(WGL_PIXEL_TYPE_ARB)
3757
3758         for(iPixelFormat=1; iPixelFormat<=Adapters[0].nCfgs; iPixelFormat++) {
3759             res = GL_EXTCALL(wglGetPixelFormatAttribivARB(hdc, iPixelFormat, 0, nAttribs, attribs, values));
3760
3761             if(!res)
3762                 continue;
3763
3764             /* Cache the pixel format */
3765             cfgs->iPixelFormat = iPixelFormat;
3766             cfgs->redSize = values[0];
3767             cfgs->greenSize = values[1];
3768             cfgs->blueSize = values[2];
3769             cfgs->alphaSize = values[3];
3770             cfgs->depthSize = values[4];
3771             cfgs->stencilSize = values[5];
3772             cfgs->windowDrawable = values[6];
3773             cfgs->iPixelType = values[7];
3774
3775             cfgs->pbufferDrawable = FALSE;
3776             /* Check for pbuffer support when it is around as wglGetPixelFormatAttribiv fails for unknown
3777 attributes. */
3778             if(GL_SUPPORT(WGL_ARB_PBUFFER)) {
3779                 int attrib = WGL_DRAW_TO_PBUFFER_ARB;
3780                 int value;
3781                 if(GL_EXTCALL(wglGetPixelFormatAttribivARB(hdc, iPixelFormat, 0, 1, &attrib, &value)))
3782                     cfgs->pbufferDrawable = value;
3783             }
3784
3785             TRACE("iPixelFormat=%d, iPixelType=%#x, RGBA=%d/%d/%d/%d, depth=%d, stencil=%d, windowDrawable=%d, pbufferDrawable=%d\n", cfgs->iPixelFormat, cfgs->iPixelType, cfgs->redSize, cfgs->greenSize, cfgs->blueSize, cfgs->alphaSize, cfgs->depthSize, cfgs->stencilSize, cfgs->windowDrawable, cfgs->pbufferDrawable);
3786             cfgs++;
3787         }
3788
3789         fixup_extensions(&Adapters[0].gl_info);
3790
3791         WineD3D_ReleaseFakeGLContext();
3792
3793         select_shader_mode(&Adapters[0].gl_info, WINED3DDEVTYPE_HAL, &ps_selected_mode, &vs_selected_mode);
3794         select_shader_max_constants(ps_selected_mode, vs_selected_mode, &Adapters[0].gl_info);
3795         fillGLAttribFuncs(&Adapters[0].gl_info);
3796         init_type_lookup(&Adapters[0].gl_info);
3797     }
3798     numAdapters = 1;
3799     TRACE("%d adapters successfully initialized\n", numAdapters);
3800
3801     return TRUE;
3802 }
3803 #undef PUSH1
3804 #undef GLINFO_LOCATION
3805
3806 /**********************************************************
3807  * IWineD3D VTbl follows
3808  **********************************************************/
3809
3810 const IWineD3DVtbl IWineD3D_Vtbl =
3811 {
3812     /* IUnknown */
3813     IWineD3DImpl_QueryInterface,
3814     IWineD3DImpl_AddRef,
3815     IWineD3DImpl_Release,
3816     /* IWineD3D */
3817     IWineD3DImpl_GetParent,
3818     IWineD3DImpl_GetAdapterCount,
3819     IWineD3DImpl_RegisterSoftwareDevice,
3820     IWineD3DImpl_GetAdapterMonitor,
3821     IWineD3DImpl_GetAdapterModeCount,
3822     IWineD3DImpl_EnumAdapterModes,
3823     IWineD3DImpl_GetAdapterDisplayMode,
3824     IWineD3DImpl_GetAdapterIdentifier,
3825     IWineD3DImpl_CheckDeviceMultiSampleType,
3826     IWineD3DImpl_CheckDepthStencilMatch,
3827     IWineD3DImpl_CheckDeviceType,
3828     IWineD3DImpl_CheckDeviceFormat,
3829     IWineD3DImpl_CheckDeviceFormatConversion,
3830     IWineD3DImpl_GetDeviceCaps,
3831     IWineD3DImpl_CreateDevice
3832 };