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