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