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