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