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