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