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