d3d10core: Keep a reference to the wined3d device in the d3d10 device.
[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 Xpress Series - onboard, DX9b, Shader 2.0, 300-400MHz */
1290                 else if(strstr(gl_info->gl_renderer, "Radeon Xpress"))
1291                 {
1292                     gl_info->gl_card = CARD_ATI_RADEON_XPRESS_200M;
1293                     vidmem = 64; /* Shared RAM, BIOS configurable, 64-256M */
1294                 }
1295                 /* Radeon R3xx */ 
1296                 else {
1297                     gl_info->gl_card = CARD_ATI_RADEON_9500; /* Radeon 9500/9550/9600/9700/9800/X300/X550/X600 */
1298                     vidmem = 64; /* Radeon 9500 uses 64MB, higher models use up to 256MB */
1299                 }
1300             } else if(WINE_D3D8_CAPABLE(gl_info)) {
1301                 gl_info->gl_card = CARD_ATI_RADEON_8500; /* Radeon 8500/9000/9100/9200/9300 */
1302                 vidmem = 64; /* 8500/9000 cards use mostly 64MB, though there are 32MB and 128MB models */
1303             } else if(WINE_D3D7_CAPABLE(gl_info)) {
1304                 gl_info->gl_card = CARD_ATI_RADEON_7200; /* Radeon 7000/7100/7200/7500 */
1305                 vidmem = 32; /* There are models with up to 64MB */
1306             } else {
1307                 gl_info->gl_card = CARD_ATI_RAGE_128PRO;
1308                 vidmem = 16; /* There are 16-32MB models */
1309             }
1310             break;
1311         case VENDOR_INTEL:
1312             if (strstr(gl_info->gl_renderer, "GMA 950") ||
1313                 strstr(gl_info->gl_renderer, "945GM")) {
1314                 /* MacOS calls the card GMA 950, but everywhere else the PCI ID is named 945GM */
1315                 gl_info->gl_card = CARD_INTEL_I945GM;
1316                 vidmem = 64;
1317             } else if (strstr(gl_info->gl_renderer, "915GM")) {
1318                 gl_info->gl_card = CARD_INTEL_I915GM;
1319             } else if (strstr(gl_info->gl_renderer, "915G")) {
1320                 gl_info->gl_card = CARD_INTEL_I915G;
1321             } else if (strstr(gl_info->gl_renderer, "865G")) {
1322                 gl_info->gl_card = CARD_INTEL_I865G;
1323             } else if (strstr(gl_info->gl_renderer, "855G")) {
1324                 gl_info->gl_card = CARD_INTEL_I855G;
1325             } else if (strstr(gl_info->gl_renderer, "830G")) {
1326                 gl_info->gl_card = CARD_INTEL_I830G;
1327             } else {
1328                 gl_info->gl_card = CARD_INTEL_I915G;
1329             }
1330             break;
1331         case VENDOR_MESA:
1332         case VENDOR_WINE:
1333         default:
1334             /* Default to generic Nvidia hardware based on the supported OpenGL extensions. The choice 
1335              * for Nvidia was because the hardware and drivers they make are of good quality. This makes
1336              * them a good generic choice.
1337              */
1338             gl_info->gl_vendor = VENDOR_NVIDIA;
1339             if(WINE_D3D9_CAPABLE(gl_info))
1340                 gl_info->gl_card = CARD_NVIDIA_GEFORCEFX_5600;
1341             else if(WINE_D3D8_CAPABLE(gl_info))
1342                 gl_info->gl_card = CARD_NVIDIA_GEFORCE3;
1343             else if(WINE_D3D7_CAPABLE(gl_info))
1344                 gl_info->gl_card = CARD_NVIDIA_GEFORCE;
1345             else if(WINE_D3D6_CAPABLE(gl_info))
1346                 gl_info->gl_card = CARD_NVIDIA_RIVA_TNT;
1347             else
1348                 gl_info->gl_card = CARD_NVIDIA_RIVA_128;
1349     }
1350     TRACE_(d3d_caps)("FOUND (fake) card: 0x%x (vendor id), 0x%x (device id)\n", gl_info->gl_vendor, gl_info->gl_card);
1351
1352     /* If we have an estimate use it, else default to 64MB;  */
1353     if(vidmem)
1354         gl_info->vidmem = vidmem*1024*1024; /* convert from MBs to bytes */
1355     else
1356         gl_info->vidmem = WINE_DEFAULT_VIDMEM;
1357
1358     /* Load all the lookup tables */
1359     for (i = 0; i < MAX_LOOKUPS; i++) {
1360         stateLookup[i] = HeapAlloc(GetProcessHeap(), 0, sizeof(*stateLookup[i]) * (1 + maxLookup[i] - minLookup[i]) );
1361     }
1362
1363     stateLookup[WINELOOKUP_WARPPARAM][WINED3DTADDRESS_WRAP   - minLookup[WINELOOKUP_WARPPARAM]] = GL_REPEAT;
1364     stateLookup[WINELOOKUP_WARPPARAM][WINED3DTADDRESS_CLAMP  - minLookup[WINELOOKUP_WARPPARAM]] = GL_CLAMP_TO_EDGE;
1365     stateLookup[WINELOOKUP_WARPPARAM][WINED3DTADDRESS_BORDER - minLookup[WINELOOKUP_WARPPARAM]] =
1366              gl_info->supported[ARB_TEXTURE_BORDER_CLAMP] ? GL_CLAMP_TO_BORDER_ARB : GL_REPEAT;
1367     stateLookup[WINELOOKUP_WARPPARAM][WINED3DTADDRESS_BORDER - minLookup[WINELOOKUP_WARPPARAM]] =
1368              gl_info->supported[ARB_TEXTURE_BORDER_CLAMP] ? GL_CLAMP_TO_BORDER_ARB : GL_REPEAT;
1369     stateLookup[WINELOOKUP_WARPPARAM][WINED3DTADDRESS_MIRROR - minLookup[WINELOOKUP_WARPPARAM]] =
1370              gl_info->supported[ARB_TEXTURE_MIRRORED_REPEAT] ? GL_MIRRORED_REPEAT_ARB : GL_REPEAT;
1371     stateLookup[WINELOOKUP_WARPPARAM][WINED3DTADDRESS_MIRRORONCE - minLookup[WINELOOKUP_WARPPARAM]] =
1372              gl_info->supported[ATI_TEXTURE_MIRROR_ONCE] ? GL_MIRROR_CLAMP_TO_EDGE_ATI : GL_REPEAT;
1373
1374     magLookup[WINED3DTEXF_NONE        - WINED3DTEXF_NONE]  = GL_NEAREST;
1375     magLookup[WINED3DTEXF_POINT       - WINED3DTEXF_NONE] = GL_NEAREST;
1376     magLookup[WINED3DTEXF_LINEAR      - WINED3DTEXF_NONE] = GL_LINEAR;
1377     magLookup[WINED3DTEXF_ANISOTROPIC - WINED3DTEXF_NONE] =
1378              gl_info->supported[EXT_TEXTURE_FILTER_ANISOTROPIC] ? GL_LINEAR : GL_NEAREST;
1379
1380
1381     minMipLookup[WINED3DTEXF_NONE].mip[WINED3DTEXF_NONE]     = GL_LINEAR;
1382     minMipLookup[WINED3DTEXF_NONE].mip[WINED3DTEXF_POINT]    = GL_LINEAR;
1383     minMipLookup[WINED3DTEXF_NONE].mip[WINED3DTEXF_LINEAR]   = GL_LINEAR;
1384     minMipLookup[WINED3DTEXF_POINT].mip[WINED3DTEXF_NONE]    = GL_NEAREST;
1385     minMipLookup[WINED3DTEXF_POINT].mip[WINED3DTEXF_POINT]   = GL_NEAREST_MIPMAP_NEAREST;
1386     minMipLookup[WINED3DTEXF_POINT].mip[WINED3DTEXF_LINEAR]  = GL_NEAREST_MIPMAP_LINEAR;
1387     minMipLookup[WINED3DTEXF_LINEAR].mip[WINED3DTEXF_NONE]   = GL_LINEAR;
1388     minMipLookup[WINED3DTEXF_LINEAR].mip[WINED3DTEXF_POINT]  = GL_LINEAR_MIPMAP_NEAREST;
1389     minMipLookup[WINED3DTEXF_LINEAR].mip[WINED3DTEXF_LINEAR] = GL_LINEAR_MIPMAP_LINEAR;
1390     minMipLookup[WINED3DTEXF_ANISOTROPIC].mip[WINED3DTEXF_NONE]
1391             = gl_info->supported[EXT_TEXTURE_FILTER_ANISOTROPIC] ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR;
1392     minMipLookup[WINED3DTEXF_ANISOTROPIC].mip[WINED3DTEXF_POINT]
1393             = gl_info->supported[EXT_TEXTURE_FILTER_ANISOTROPIC] ? GL_LINEAR_MIPMAP_NEAREST : GL_LINEAR;
1394     minMipLookup[WINED3DTEXF_ANISOTROPIC].mip[WINED3DTEXF_LINEAR]
1395             = gl_info->supported[EXT_TEXTURE_FILTER_ANISOTROPIC] ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR;
1396
1397 /* TODO: config lookups */
1398
1399     /* Make sure there's an active HDC else the WGL extensions will fail */
1400     hdc = pwglGetCurrentDC();
1401     if (hdc) {
1402         WGL_Extensions = GL_EXTCALL(wglGetExtensionsStringARB(hdc));
1403         TRACE_(d3d_caps)("WGL_Extensions reported:\n");
1404
1405         if (NULL == WGL_Extensions) {
1406             ERR("   WGL_Extensions returns NULL\n");
1407         } else {
1408             while (*WGL_Extensions != 0x00) {
1409                 const char *Start;
1410                 char ThisExtn[256];
1411                 size_t len;
1412
1413                 while (isspace(*WGL_Extensions)) WGL_Extensions++;
1414                 Start = WGL_Extensions;
1415                 while (!isspace(*WGL_Extensions) && *WGL_Extensions != 0x00) {
1416                     WGL_Extensions++;
1417                 }
1418
1419                 len = WGL_Extensions - Start;
1420                 if (len == 0 || len >= sizeof(ThisExtn))
1421                     continue;
1422
1423                 memcpy(ThisExtn, Start, len);
1424                 ThisExtn[len] = '\0';
1425                 TRACE_(d3d_caps)("- %s\n", ThisExtn);
1426
1427                 if (!strcmp(ThisExtn, "WGL_ARB_pbuffer")) {
1428                     gl_info->supported[WGL_ARB_PBUFFER] = TRUE;
1429                     TRACE_(d3d_caps)("FOUND: WGL_ARB_pbuffer support\n");
1430                 }
1431                 if (!strcmp(ThisExtn, "WGL_WINE_pixel_format_passthrough")) {
1432                     gl_info->supported[WGL_WINE_PIXEL_FORMAT_PASSTHROUGH] = TRUE;
1433                     TRACE_(d3d_caps)("FOUND: WGL_WINE_pixel_format_passthrough support\n");
1434                 }
1435             }
1436         }
1437     }
1438     LEAVE_GL();
1439
1440     return return_value;
1441 }
1442 #undef GLINFO_LOCATION
1443
1444 /**********************************************************
1445  * IWineD3D implementation follows
1446  **********************************************************/
1447
1448 static UINT     WINAPI IWineD3DImpl_GetAdapterCount (IWineD3D *iface) {
1449     IWineD3DImpl *This = (IWineD3DImpl *)iface;
1450
1451     TRACE_(d3d_caps)("(%p): Reporting %d adapters\n", This, numAdapters);
1452     return numAdapters;
1453 }
1454
1455 static HRESULT  WINAPI IWineD3DImpl_RegisterSoftwareDevice(IWineD3D *iface, void* pInitializeFunction) {
1456     IWineD3DImpl *This = (IWineD3DImpl *)iface;
1457     FIXME("(%p)->(%p): stub\n", This, pInitializeFunction);
1458     return WINED3D_OK;
1459 }
1460
1461 static HMONITOR WINAPI IWineD3DImpl_GetAdapterMonitor(IWineD3D *iface, UINT Adapter) {
1462     IWineD3DImpl *This = (IWineD3DImpl *)iface;
1463
1464     TRACE_(d3d_caps)("(%p)->(%d)\n", This, Adapter);
1465
1466     if (Adapter >= IWineD3DImpl_GetAdapterCount(iface)) {
1467         return NULL;
1468     }
1469
1470     return MonitorFromPoint(Adapters[Adapter].monitorPoint, MONITOR_DEFAULTTOPRIMARY);
1471 }
1472
1473 /* FIXME: GetAdapterModeCount and EnumAdapterModes currently only returns modes
1474      of the same bpp but different resolutions                                  */
1475
1476 /* Note: dx9 supplies a format. Calls from d3d8 supply WINED3DFMT_UNKNOWN */
1477 static UINT     WINAPI IWineD3DImpl_GetAdapterModeCount(IWineD3D *iface, UINT Adapter, WINED3DFORMAT Format) {
1478     IWineD3DImpl *This = (IWineD3DImpl *)iface;
1479     TRACE_(d3d_caps)("(%p}->(Adapter: %d, Format: %s)\n", This, Adapter, debug_d3dformat(Format));
1480
1481     if (Adapter >= IWineD3D_GetAdapterCount(iface)) {
1482         return 0;
1483     }
1484
1485     /* TODO: Store modes per adapter and read it from the adapter structure */
1486     if (Adapter == 0) { /* Display */
1487         int i = 0;
1488         int j = 0;
1489
1490         if (!DEBUG_SINGLE_MODE) {
1491             DEVMODEW DevModeW;
1492
1493             ZeroMemory(&DevModeW, sizeof(DevModeW));
1494             DevModeW.dmSize = sizeof(DevModeW);
1495             while (EnumDisplaySettingsExW(NULL, j, &DevModeW, 0)) {
1496                 j++;
1497                 switch (Format)
1498                 {
1499                     case WINED3DFMT_UNKNOWN:
1500                         /* This is for D3D8, do not enumerate P8 here */
1501                         if (DevModeW.dmBitsPerPel == 32 ||
1502                             DevModeW.dmBitsPerPel == 16) i++;
1503                         break;
1504                     case WINED3DFMT_X8R8G8B8:
1505                         if (DevModeW.dmBitsPerPel == 32) i++;
1506                         break;
1507                     case WINED3DFMT_R5G6B5:
1508                         if (DevModeW.dmBitsPerPel == 16) i++;
1509                         break;
1510                     case WINED3DFMT_P8:
1511                         if (DevModeW.dmBitsPerPel == 8) i++;
1512                         break;
1513                     default:
1514                         /* Skip other modes as they do not match the requested format */
1515                         break;
1516                 }
1517             }
1518         } else {
1519             i = 1;
1520             j = 1;
1521         }
1522
1523         TRACE_(d3d_caps)("(%p}->(Adapter: %d) => %d (out of %d)\n", This, Adapter, i, j);
1524         return i;
1525     } else {
1526         FIXME_(d3d_caps)("Adapter not primary display\n");
1527     }
1528     return 0;
1529 }
1530
1531 /* Note: dx9 supplies a format. Calls from d3d8 supply WINED3DFMT_UNKNOWN */
1532 static HRESULT WINAPI IWineD3DImpl_EnumAdapterModes(IWineD3D *iface, UINT Adapter, WINED3DFORMAT Format, UINT Mode, WINED3DDISPLAYMODE* pMode) {
1533     IWineD3DImpl *This = (IWineD3DImpl *)iface;
1534     TRACE_(d3d_caps)("(%p}->(Adapter:%d, mode:%d, pMode:%p, format:%s)\n", This, Adapter, Mode, pMode, debug_d3dformat(Format));
1535
1536     /* Validate the parameters as much as possible */
1537     if (NULL == pMode ||
1538         Adapter >= IWineD3DImpl_GetAdapterCount(iface) ||
1539         Mode    >= IWineD3DImpl_GetAdapterModeCount(iface, Adapter, Format)) {
1540         return WINED3DERR_INVALIDCALL;
1541     }
1542
1543     /* TODO: Store modes per adapter and read it from the adapter structure */
1544     if (Adapter == 0 && !DEBUG_SINGLE_MODE) { /* Display */
1545         DEVMODEW DevModeW;
1546         int ModeIdx = 0;
1547         UINT i = 0;
1548         int j = 0;
1549
1550         ZeroMemory(&DevModeW, sizeof(DevModeW));
1551         DevModeW.dmSize = sizeof(DevModeW);
1552
1553         /* If we are filtering to a specific format (D3D9), then need to skip
1554            all unrelated modes, but if mode is irrelevant (D3D8), then we can
1555            just count through the ones with valid bit depths */
1556         while ((i<=Mode) && EnumDisplaySettingsExW(NULL, j++, &DevModeW, 0)) {
1557             switch (Format)
1558             {
1559                 case WINED3DFMT_UNKNOWN:
1560                     /* This is D3D8. Do not enumerate P8 here */
1561                     if (DevModeW.dmBitsPerPel == 32 ||
1562                         DevModeW.dmBitsPerPel == 16) i++;
1563                     break;
1564                 case WINED3DFMT_X8R8G8B8:
1565                     if (DevModeW.dmBitsPerPel == 32) i++;
1566                     break;
1567                 case WINED3DFMT_R5G6B5:
1568                     if (DevModeW.dmBitsPerPel == 16) i++;
1569                     break;
1570                 case WINED3DFMT_P8:
1571                     if (DevModeW.dmBitsPerPel == 8) i++;
1572                     break;
1573                 default:
1574                     /* Modes that don't match what we support can get an early-out */
1575                     TRACE_(d3d_caps)("Searching for %s, returning D3DERR_INVALIDCALL\n", debug_d3dformat(Format));
1576                     return WINED3DERR_INVALIDCALL;
1577             }
1578         }
1579
1580         if (i == 0) {
1581             TRACE_(d3d_caps)("No modes found for format (%x - %s)\n", Format, debug_d3dformat(Format));
1582             return WINED3DERR_INVALIDCALL;
1583         }
1584         ModeIdx = j - 1;
1585
1586         /* Now get the display mode via the calculated index */
1587         if (EnumDisplaySettingsExW(NULL, ModeIdx, &DevModeW, 0)) {
1588             pMode->Width        = DevModeW.dmPelsWidth;
1589             pMode->Height       = DevModeW.dmPelsHeight;
1590             pMode->RefreshRate  = WINED3DADAPTER_DEFAULT;
1591             if (DevModeW.dmFields & DM_DISPLAYFREQUENCY)
1592                 pMode->RefreshRate = DevModeW.dmDisplayFrequency;
1593
1594             if (Format == WINED3DFMT_UNKNOWN) {
1595                 pMode->Format = pixelformat_for_depth(DevModeW.dmBitsPerPel);
1596             } else {
1597                 pMode->Format = Format;
1598             }
1599         } else {
1600             TRACE_(d3d_caps)("Requested mode out of range %d\n", Mode);
1601             return WINED3DERR_INVALIDCALL;
1602         }
1603
1604         TRACE_(d3d_caps)("W %d H %d rr %d fmt (%x - %s) bpp %u\n", pMode->Width, pMode->Height,
1605                 pMode->RefreshRate, pMode->Format, debug_d3dformat(pMode->Format),
1606                 DevModeW.dmBitsPerPel);
1607
1608     } else if (DEBUG_SINGLE_MODE) {
1609         /* Return one setting of the format requested */
1610         if (Mode > 0) return WINED3DERR_INVALIDCALL;
1611         pMode->Width        = 800;
1612         pMode->Height       = 600;
1613         pMode->RefreshRate  = 60;
1614         pMode->Format       = (Format == WINED3DFMT_UNKNOWN) ? WINED3DFMT_X8R8G8B8 : Format;
1615     } else {
1616         FIXME_(d3d_caps)("Adapter not primary display\n");
1617     }
1618
1619     return WINED3D_OK;
1620 }
1621
1622 static HRESULT WINAPI IWineD3DImpl_GetAdapterDisplayMode(IWineD3D *iface, UINT Adapter, WINED3DDISPLAYMODE* pMode) {
1623     IWineD3DImpl *This = (IWineD3DImpl *)iface;
1624     TRACE_(d3d_caps)("(%p}->(Adapter: %d, pMode: %p)\n", This, Adapter, pMode);
1625
1626     if (NULL == pMode ||
1627         Adapter >= IWineD3D_GetAdapterCount(iface)) {
1628         return WINED3DERR_INVALIDCALL;
1629     }
1630
1631     if (Adapter == 0) { /* Display */
1632         int bpp = 0;
1633         DEVMODEW DevModeW;
1634
1635         ZeroMemory(&DevModeW, sizeof(DevModeW));
1636         DevModeW.dmSize = sizeof(DevModeW);
1637
1638         EnumDisplaySettingsExW(NULL, ENUM_CURRENT_SETTINGS, &DevModeW, 0);
1639         pMode->Width        = DevModeW.dmPelsWidth;
1640         pMode->Height       = DevModeW.dmPelsHeight;
1641         bpp                 = DevModeW.dmBitsPerPel;
1642         pMode->RefreshRate  = WINED3DADAPTER_DEFAULT;
1643         if (DevModeW.dmFields&DM_DISPLAYFREQUENCY)
1644         {
1645             pMode->RefreshRate = DevModeW.dmDisplayFrequency;
1646         }
1647
1648         pMode->Format = pixelformat_for_depth(bpp);
1649     } else {
1650         FIXME_(d3d_caps)("Adapter not primary display\n");
1651     }
1652
1653     TRACE_(d3d_caps)("returning w:%d, h:%d, ref:%d, fmt:%s\n", pMode->Width,
1654           pMode->Height, pMode->RefreshRate, debug_d3dformat(pMode->Format));
1655     return WINED3D_OK;
1656 }
1657
1658 /* NOTE: due to structure differences between dx8 and dx9 D3DADAPTER_IDENTIFIER,
1659    and fields being inserted in the middle, a new structure is used in place    */
1660 static HRESULT WINAPI IWineD3DImpl_GetAdapterIdentifier(IWineD3D *iface, UINT Adapter, DWORD Flags,
1661                                                    WINED3DADAPTER_IDENTIFIER* pIdentifier) {
1662     IWineD3DImpl *This = (IWineD3DImpl *)iface;
1663
1664     TRACE_(d3d_caps)("(%p}->(Adapter: %d, Flags: %x, pId=%p)\n", This, Adapter, Flags, pIdentifier);
1665
1666     if (Adapter >= IWineD3D_GetAdapterCount(iface)) {
1667         return WINED3DERR_INVALIDCALL;
1668     }
1669
1670     /* Return the information requested */
1671     TRACE_(d3d_caps)("device/Vendor Name and Version detection using FillGLCaps\n");
1672     strcpy(pIdentifier->Driver, Adapters[Adapter].driver);
1673     strcpy(pIdentifier->Description, Adapters[Adapter].description);
1674
1675     /* Note dx8 doesn't supply a DeviceName */
1676     if (NULL != pIdentifier->DeviceName) strcpy(pIdentifier->DeviceName, "\\\\.\\DISPLAY"); /* FIXME: May depend on desktop? */
1677     pIdentifier->DriverVersion->u.HighPart = Adapters[Adapter].gl_info.driver_version_hipart;
1678     pIdentifier->DriverVersion->u.LowPart = Adapters[Adapter].gl_info.driver_version;
1679     *(pIdentifier->VendorId) = Adapters[Adapter].gl_info.gl_vendor;
1680     *(pIdentifier->DeviceId) = Adapters[Adapter].gl_info.gl_card;
1681     *(pIdentifier->SubSysId) = 0;
1682     *(pIdentifier->Revision) = 0;
1683     *pIdentifier->DeviceIdentifier = IID_D3DDEVICE_D3DUID;
1684
1685     if(wined3d_settings.pci_device_id != PCI_DEVICE_NONE)
1686     {
1687         TRACE_(d3d_caps)("Overriding pci device id with: %x\n", wined3d_settings.pci_device_id);
1688         *(pIdentifier->DeviceId) = wined3d_settings.pci_device_id;
1689     }
1690
1691     if(wined3d_settings.pci_vendor_id != PCI_VENDOR_NONE)
1692     {
1693         TRACE_(d3d_caps)("Overriding pci vendor id with: %x\n", wined3d_settings.pci_vendor_id);
1694         *(pIdentifier->VendorId) = wined3d_settings.pci_vendor_id;
1695     }
1696
1697     if (Flags & WINED3DENUM_NO_WHQL_LEVEL) {
1698         *(pIdentifier->WHQLLevel) = 0;
1699     } else {
1700         *(pIdentifier->WHQLLevel) = 1;
1701     }
1702
1703     return WINED3D_OK;
1704 }
1705
1706 static BOOL IWineD3DImpl_IsPixelFormatCompatibleWithRenderFmt(const WineD3D_PixelFormat *cfg, WINED3DFORMAT Format) {
1707     short redSize, greenSize, blueSize, alphaSize, colorBits;
1708
1709     if(!cfg)
1710         return FALSE;
1711
1712     if(cfg->iPixelType == WGL_TYPE_RGBA_ARB) { /* Integer RGBA formats */
1713         if(!getColorBits(Format, &redSize, &greenSize, &blueSize, &alphaSize, &colorBits)) {
1714             ERR("Unable to check compatibility for Format=%s\n", debug_d3dformat(Format));
1715             return FALSE;
1716         }
1717
1718         if(cfg->redSize < redSize)
1719             return FALSE;
1720
1721         if(cfg->greenSize < greenSize)
1722             return FALSE;
1723
1724         if(cfg->blueSize < blueSize)
1725             return FALSE;
1726
1727         if(cfg->alphaSize < alphaSize)
1728             return FALSE;
1729
1730         return TRUE;
1731     } else if(cfg->iPixelType == WGL_TYPE_RGBA_FLOAT_ARB) { /* Float RGBA formats; TODO: WGL_NV_float_buffer */
1732         if(Format == WINED3DFMT_R16_FLOAT)
1733             return (cfg->redSize == 16 && cfg->greenSize == 0 && cfg->blueSize == 0 && cfg->alphaSize == 0);
1734         if(Format == WINED3DFMT_R16G16_FLOAT)
1735             return (cfg->redSize == 16 && cfg->greenSize == 16 && cfg->blueSize == 0 && cfg->alphaSize == 0);
1736         if(Format == WINED3DFMT_R16G16B16A16_FLOAT)
1737             return (cfg->redSize == 16 && cfg->greenSize == 16 && cfg->blueSize == 16 && cfg->alphaSize == 16);
1738         if(Format == WINED3DFMT_R32_FLOAT)
1739             return (cfg->redSize == 32 && cfg->greenSize == 0 && cfg->blueSize == 0 && cfg->alphaSize == 0);
1740         if(Format == WINED3DFMT_R32G32_FLOAT)
1741             return (cfg->redSize == 32 && cfg->greenSize == 32 && cfg->blueSize == 0 && cfg->alphaSize == 0);
1742         if(Format == WINED3DFMT_R32G32B32A32_FLOAT)
1743             return (cfg->redSize == 32 && cfg->greenSize == 32 && cfg->blueSize == 32 && cfg->alphaSize == 32);
1744     } else {
1745         /* Probably a color index mode */
1746         return FALSE;
1747     }
1748
1749     return FALSE;
1750 }
1751
1752 static BOOL IWineD3DImpl_IsPixelFormatCompatibleWithDepthFmt(const WineD3D_PixelFormat *cfg, WINED3DFORMAT Format) {
1753     short depthSize, stencilSize;
1754     BOOL lockable = FALSE;
1755
1756     if(!cfg)
1757         return FALSE;
1758
1759     if(!getDepthStencilBits(Format, &depthSize, &stencilSize)) {
1760         ERR("Unable to check compatibility for Format=%s\n", debug_d3dformat(Format));
1761         return FALSE;
1762     }
1763
1764     if((Format == WINED3DFMT_D16_LOCKABLE) || (Format == WINED3DFMT_D32F_LOCKABLE))
1765         lockable = TRUE;
1766
1767     /* On some modern cards like the Geforce8/9 GLX doesn't offer some dephthstencil formats which D3D9 reports.
1768      * We can safely report 'compatible' formats (e.g. D24 can be used for D16) as long as we aren't dealing with
1769      * a lockable format. This also helps D3D <= 7 as they expect D16 which isn't offered without this on Geforce8 cards. */
1770     if(!(cfg->depthSize == depthSize || (!lockable && cfg->depthSize > depthSize)))
1771         return FALSE;
1772
1773     /* Some cards like Intel i915 ones only offer D24S8 but lots of games also need a format without stencil, so
1774      * allow more stencil bits than requested. */
1775     if(cfg->stencilSize < stencilSize)
1776         return FALSE;
1777
1778     return TRUE;
1779 }
1780
1781 static HRESULT WINAPI IWineD3DImpl_CheckDepthStencilMatch(IWineD3D *iface, UINT Adapter, WINED3DDEVTYPE DeviceType,
1782                                                    WINED3DFORMAT AdapterFormat,
1783                                                    WINED3DFORMAT RenderTargetFormat,
1784                                                    WINED3DFORMAT DepthStencilFormat) {
1785     IWineD3DImpl *This = (IWineD3DImpl *)iface;
1786     int nCfgs;
1787     const WineD3D_PixelFormat *cfgs;
1788     int it;
1789
1790     WARN_(d3d_caps)("(%p)-> (STUB) (Adptr:%d, DevType:(%x,%s), AdptFmt:(%x,%s), RendrTgtFmt:(%x,%s), DepthStencilFmt:(%x,%s))\n",
1791            This, Adapter,
1792            DeviceType, debug_d3ddevicetype(DeviceType),
1793            AdapterFormat, debug_d3dformat(AdapterFormat),
1794            RenderTargetFormat, debug_d3dformat(RenderTargetFormat),
1795            DepthStencilFormat, debug_d3dformat(DepthStencilFormat));
1796
1797     if (Adapter >= IWineD3D_GetAdapterCount(iface)) {
1798         TRACE("(%p) Failed: Atapter (%u) higher than supported adapters (%u) returning WINED3DERR_INVALIDCALL\n", This, Adapter, IWineD3D_GetAdapterCount(iface));
1799         return WINED3DERR_INVALIDCALL;
1800     }
1801
1802     cfgs = Adapters[Adapter].cfgs;
1803     nCfgs = Adapters[Adapter].nCfgs;
1804     for (it = 0; it < nCfgs; ++it) {
1805         if (IWineD3DImpl_IsPixelFormatCompatibleWithRenderFmt(&cfgs[it], RenderTargetFormat)) {
1806             if (IWineD3DImpl_IsPixelFormatCompatibleWithDepthFmt(&cfgs[it], DepthStencilFormat)) {
1807                 TRACE_(d3d_caps)("(%p) : Formats matched\n", This);
1808                 return WINED3D_OK;
1809             }
1810         }
1811     }
1812     WARN_(d3d_caps)("unsupported format pair: %s and %s\n", debug_d3dformat(RenderTargetFormat), debug_d3dformat(DepthStencilFormat));
1813
1814     return WINED3DERR_NOTAVAILABLE;
1815 }
1816
1817 static HRESULT WINAPI IWineD3DImpl_CheckDeviceMultiSampleType(IWineD3D *iface, UINT Adapter, WINED3DDEVTYPE DeviceType, 
1818                                                        WINED3DFORMAT SurfaceFormat,
1819                                                        BOOL Windowed, WINED3DMULTISAMPLE_TYPE MultiSampleType, DWORD*   pQualityLevels) {
1820
1821     IWineD3DImpl *This = (IWineD3DImpl *)iface;
1822     const struct GlPixelFormatDesc *glDesc;
1823     const StaticPixelFormatDesc *desc;
1824
1825     TRACE_(d3d_caps)("(%p)-> (Adptr:%d, DevType:(%x,%s), SurfFmt:(%x,%s), Win?%d, MultiSamp:%x, pQual:%p)\n",
1826           This,
1827           Adapter,
1828           DeviceType, debug_d3ddevicetype(DeviceType),
1829           SurfaceFormat, debug_d3dformat(SurfaceFormat),
1830           Windowed,
1831           MultiSampleType,
1832           pQualityLevels);
1833
1834     if (Adapter >= IWineD3D_GetAdapterCount(iface)) {
1835         return WINED3DERR_INVALIDCALL;
1836     }
1837
1838     /* TODO: handle Windowed, add more quality levels */
1839
1840     if (WINED3DMULTISAMPLE_NONE == MultiSampleType) return WINED3D_OK;
1841
1842     /* By default multisampling is disabled right now as it causes issues
1843      * on some Nvidia driver versions and it doesn't work well in combination
1844      * with FBOs yet. */
1845     if(!wined3d_settings.allow_multisampling)
1846         return WINED3DERR_NOTAVAILABLE;
1847
1848     desc = getFormatDescEntry(SurfaceFormat, &Adapters[Adapter].gl_info, &glDesc);
1849     if(!desc || !glDesc) {
1850         return WINED3DERR_INVALIDCALL;
1851     }
1852
1853     if(glDesc->Flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL)) {
1854         int i, nCfgs;
1855         const WineD3D_PixelFormat *cfgs;
1856
1857         cfgs = Adapters[Adapter].cfgs;
1858         nCfgs = Adapters[Adapter].nCfgs;
1859         for(i=0; i<nCfgs; i++) {
1860             if(cfgs[i].numSamples != MultiSampleType)
1861                 continue;
1862
1863             if(!IWineD3DImpl_IsPixelFormatCompatibleWithDepthFmt(&cfgs[i], SurfaceFormat))
1864                 continue;
1865
1866             TRACE("Found iPixelFormat=%d to support MultiSampleType=%d for format %s\n", cfgs[i].iPixelFormat, MultiSampleType, debug_d3dformat(SurfaceFormat));
1867
1868             if(pQualityLevels)
1869                 *pQualityLevels = 1; /* Guess at a value! */
1870             return WINED3D_OK;
1871         }
1872     }
1873     else if(glDesc->Flags & WINED3DFMT_FLAG_RENDERTARGET) {
1874         short redSize, greenSize, blueSize, alphaSize, colorBits;
1875         int i, nCfgs;
1876         const WineD3D_PixelFormat *cfgs;
1877
1878         if(!getColorBits(SurfaceFormat, &redSize, &greenSize, &blueSize, &alphaSize, &colorBits)) {
1879             ERR("Unable to color bits for format %#x, can't check multisampling capability!\n", SurfaceFormat);
1880             return WINED3DERR_NOTAVAILABLE;
1881         }
1882
1883         cfgs = Adapters[Adapter].cfgs;
1884         nCfgs = Adapters[Adapter].nCfgs;
1885         for(i=0; i<nCfgs; i++) {
1886             if(cfgs[i].numSamples != MultiSampleType)
1887                 continue;
1888             if(cfgs[i].redSize != redSize)
1889                 continue;
1890             if(cfgs[i].greenSize != greenSize)
1891                 continue;
1892             if(cfgs[i].blueSize != blueSize)
1893                 continue;
1894             if(cfgs[i].alphaSize != alphaSize)
1895                 continue;
1896
1897             TRACE("Found iPixelFormat=%d to support MultiSampleType=%d for format %s\n", cfgs[i].iPixelFormat, MultiSampleType, debug_d3dformat(SurfaceFormat));
1898
1899             if(pQualityLevels)
1900                 *pQualityLevels = 1; /* Guess at a value! */
1901             return WINED3D_OK;
1902         }
1903     }
1904     return WINED3DERR_NOTAVAILABLE;
1905 }
1906
1907 static HRESULT WINAPI IWineD3DImpl_CheckDeviceType(IWineD3D *iface, UINT Adapter, WINED3DDEVTYPE DeviceType,
1908                                             WINED3DFORMAT DisplayFormat, WINED3DFORMAT BackBufferFormat, BOOL Windowed) {
1909
1910     IWineD3DImpl *This = (IWineD3DImpl *)iface;
1911     HRESULT hr = WINED3DERR_NOTAVAILABLE;
1912     UINT nmodes;
1913
1914     TRACE_(d3d_caps)("(%p)-> (STUB) (Adptr:%d, CheckType:(%x,%s), DispFmt:(%x,%s), BackBuf:(%x,%s), Win?%d): stub\n",
1915           This,
1916           Adapter,
1917           DeviceType, debug_d3ddevicetype(DeviceType),
1918           DisplayFormat, debug_d3dformat(DisplayFormat),
1919           BackBufferFormat, debug_d3dformat(BackBufferFormat),
1920           Windowed);
1921
1922     if (Adapter >= IWineD3D_GetAdapterCount(iface)) {
1923         WARN_(d3d_caps)("Adapter >= IWineD3D_GetAdapterCount(iface), returning WINED3DERR_INVALIDCALL\n");
1924         return WINED3DERR_INVALIDCALL;
1925     }
1926
1927     /* The task of this function is to check whether a certain display / backbuffer format
1928      * combination is available on the given adapter. In fullscreen mode microsoft specified
1929      * that the display format shouldn't provide alpha and that ignoring alpha the backbuffer
1930      * and display format should match exactly.
1931      * In windowed mode format conversion can occur and this depends on the driver. When format
1932      * conversion is done, this function should nevertheless fail and applications need to use
1933      * CheckDeviceFormatConversion.
1934      * At the moment we assume that fullscreen and windowed have the same capabilities */
1935
1936     /* There are only 4 display formats */
1937     if(!((DisplayFormat == WINED3DFMT_R5G6B5) ||
1938          (DisplayFormat == WINED3DFMT_X1R5G5B5) ||
1939          (DisplayFormat == WINED3DFMT_X8R8G8B8) ||
1940          (DisplayFormat == WINED3DFMT_A2R10G10B10)))
1941     {
1942         TRACE_(d3d_caps)("Format %s unsupported as display format\n", debug_d3dformat(DisplayFormat));
1943         return WINED3DERR_NOTAVAILABLE;
1944     }
1945
1946     /* If the requested DisplayFormat is not available, don't continue */
1947     nmodes = IWineD3DImpl_GetAdapterModeCount(iface, Adapter, DisplayFormat);
1948     if(!nmodes) {
1949         TRACE_(d3d_caps)("No available modes for display format %s\n", debug_d3dformat(DisplayFormat));
1950         return WINED3DERR_NOTAVAILABLE;
1951     }
1952
1953     /* Windowed mode allows you to specify WINED3DFMT_UNKNOWN for the backbufferformat, it means 'reuse' the display format for the backbuffer */
1954     if(!Windowed && BackBufferFormat == WINED3DFMT_UNKNOWN) {
1955         TRACE_(d3d_caps)("BackBufferFormat WINED3FMT_UNKNOWN not available in Windowed mode\n");
1956         return WINED3DERR_NOTAVAILABLE;
1957     }
1958
1959     /* In FULLSCREEN mode R5G6B5 can only be mixed with backbuffer format R5G6B5 */
1960     if( (DisplayFormat == WINED3DFMT_R5G6B5) && (BackBufferFormat != WINED3DFMT_R5G6B5) ) {
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 X1R5G5B5 can only be mixed with backbuffer format *1R5G5B5 */
1966     if( (DisplayFormat == WINED3DFMT_X1R5G5B5) && !((BackBufferFormat == WINED3DFMT_X1R5G5B5) || (BackBufferFormat == WINED3DFMT_A1R5G5B5)) ) {
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     /* In FULLSCREEN mode X8R8G8B8 can only be mixed with backbuffer format *8R8G8B8 */
1972     if( (DisplayFormat == WINED3DFMT_X8R8G8B8) && !((BackBufferFormat == WINED3DFMT_X8R8G8B8) || (BackBufferFormat == WINED3DFMT_A8R8G8B8)) ) {
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     /* A2R10G10B10 is only allowed in fullscreen mode and it can only be mixed with backbuffer format A2R10G10B10 */
1978     if( (DisplayFormat == WINED3DFMT_A2R10G10B10) && ((BackBufferFormat != WINED3DFMT_A2R10G10B10) || Windowed)) {
1979         TRACE_(d3d_caps)("Unsupported display/backbuffer format combination %s/%s\n", debug_d3dformat(DisplayFormat), debug_d3dformat(BackBufferFormat));
1980         return WINED3DERR_NOTAVAILABLE;
1981     }
1982
1983     /* Use CheckDeviceFormat to see if the BackBufferFormat is usable with the given DisplayFormat */
1984     hr = IWineD3DImpl_CheckDeviceFormat(iface, Adapter, DeviceType, DisplayFormat, WINED3DUSAGE_RENDERTARGET, WINED3DRTYPE_SURFACE, BackBufferFormat, SURFACE_OPENGL);
1985     if(FAILED(hr))
1986         TRACE_(d3d_caps)("Unsupported display/backbuffer format combination %s/%s\n", debug_d3dformat(DisplayFormat), debug_d3dformat(BackBufferFormat));
1987
1988     return hr;
1989 }
1990
1991
1992 #define GLINFO_LOCATION Adapters[Adapter].gl_info
1993 /* Check if we support bumpmapping for a format */
1994 static BOOL CheckBumpMapCapability(UINT Adapter, WINED3DDEVTYPE DeviceType, WINED3DFORMAT CheckFormat)
1995 {
1996     const struct fragment_pipeline *fp;
1997     const struct GlPixelFormatDesc *glDesc;
1998
1999     switch(CheckFormat) {
2000         case WINED3DFMT_R8G8_SNORM:
2001         case WINED3DFMT_R16G16_SNORM:
2002         case WINED3DFMT_L6V5U5:
2003         case WINED3DFMT_X8L8V8U8:
2004         case WINED3DFMT_R8G8B8A8_SNORM:
2005             /* Ask the fixed function pipeline implementation if it can deal
2006              * with the conversion. If we've got a GL extension giving native
2007              * support this will be an identity conversion. */
2008             getFormatDescEntry(CheckFormat, &GLINFO_LOCATION, &glDesc);
2009             fp = select_fragment_implementation(Adapter, DeviceType);
2010             if (fp->color_fixup_supported(glDesc->color_fixup))
2011             {
2012                 TRACE_(d3d_caps)("[OK]\n");
2013                 return TRUE;
2014             }
2015             TRACE_(d3d_caps)("[FAILED]\n");
2016             return FALSE;
2017
2018         default:
2019             TRACE_(d3d_caps)("[FAILED]\n");
2020             return FALSE;
2021     }
2022 }
2023
2024 /* Check if the given DisplayFormat + DepthStencilFormat combination is valid for the Adapter */
2025 static BOOL CheckDepthStencilCapability(UINT Adapter, WINED3DFORMAT DisplayFormat, WINED3DFORMAT DepthStencilFormat)
2026 {
2027     int it=0;
2028     const struct GlPixelFormatDesc *glDesc;
2029     const StaticPixelFormatDesc *desc = getFormatDescEntry(DepthStencilFormat, &GLINFO_LOCATION, &glDesc);
2030
2031     /* Fail if we weren't able to get a description of the format */
2032     if(!desc || !glDesc)
2033         return FALSE;
2034
2035     /* Only allow depth/stencil formats */
2036     if(!(glDesc->Flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL)))
2037         return FALSE;
2038
2039     /* Walk through all WGL pixel formats to find a match */
2040     for (it = 0; it < Adapters[Adapter].nCfgs; ++it) {
2041         WineD3D_PixelFormat *cfg = &Adapters[Adapter].cfgs[it];
2042         if (IWineD3DImpl_IsPixelFormatCompatibleWithRenderFmt(cfg, DisplayFormat)) {
2043             if (IWineD3DImpl_IsPixelFormatCompatibleWithDepthFmt(cfg, DepthStencilFormat)) {
2044                 return TRUE;
2045             }
2046         }
2047     }
2048
2049     return FALSE;
2050 }
2051
2052 static BOOL CheckFilterCapability(UINT Adapter, WINED3DFORMAT CheckFormat)
2053 {
2054     const struct GlPixelFormatDesc *glDesc;
2055     const StaticPixelFormatDesc *desc = getFormatDescEntry(CheckFormat, &GLINFO_LOCATION, &glDesc);
2056
2057     /* Fail if we weren't able to get a description of the format */
2058     if(!desc || !glDesc)
2059         return FALSE;
2060
2061     /* The flags entry of a format contains the filtering capability */
2062     if(glDesc->Flags & WINED3DFMT_FLAG_FILTERING)
2063         return TRUE;
2064
2065     return FALSE;
2066 }
2067
2068 /* Check the render target capabilities of a format */
2069 static BOOL CheckRenderTargetCapability(WINED3DFORMAT AdapterFormat, WINED3DFORMAT CheckFormat)
2070 {
2071     UINT Adapter = 0;
2072     const struct GlPixelFormatDesc *glDesc;
2073     const StaticPixelFormatDesc *desc = getFormatDescEntry(CheckFormat, &GLINFO_LOCATION, &glDesc);
2074
2075     /* Fail if we weren't able to get a description of the format */
2076     if(!desc || !glDesc)
2077         return FALSE;
2078
2079     /* Filter out non-RT formats */
2080     if(!(glDesc->Flags & WINED3DFMT_FLAG_RENDERTARGET))
2081         return FALSE;
2082
2083     if(wined3d_settings.offscreen_rendering_mode == ORM_BACKBUFFER) {
2084         WineD3D_PixelFormat *cfgs = Adapters[Adapter].cfgs;
2085         int it;
2086         short AdapterRed, AdapterGreen, AdapterBlue, AdapterAlpha, AdapterTotalSize;
2087         short CheckRed, CheckGreen, CheckBlue, CheckAlpha, CheckTotalSize;
2088
2089         getColorBits(AdapterFormat, &AdapterRed, &AdapterGreen, &AdapterBlue, &AdapterAlpha, &AdapterTotalSize);
2090         getColorBits(CheckFormat, &CheckRed, &CheckGreen, &CheckBlue, &CheckAlpha, &CheckTotalSize);
2091
2092         /* In backbuffer mode the front and backbuffer share the same WGL pixelformat.
2093          * The format must match in RGB, alpha is allowed to be different. (Only the backbuffer can have alpha) */
2094         if(!((AdapterRed == CheckRed) && (AdapterGreen == CheckGreen) && (AdapterBlue == CheckBlue))) {
2095             TRACE_(d3d_caps)("[FAILED]\n");
2096             return FALSE;
2097         }
2098
2099         /* Check if there is a WGL pixel format matching the requirements, the format should also be window
2100          * drawable (not offscreen; e.g. Nvidia offers R5G6B5 for pbuffers even when X is running at 24bit) */
2101         for (it = 0; it < Adapters[Adapter].nCfgs; ++it) {
2102             if (cfgs[it].windowDrawable && IWineD3DImpl_IsPixelFormatCompatibleWithRenderFmt(&cfgs[it], CheckFormat)) {
2103                 TRACE_(d3d_caps)("iPixelFormat=%d is compatible with CheckFormat=%s\n", cfgs[it].iPixelFormat, debug_d3dformat(CheckFormat));
2104                 return TRUE;
2105             }
2106         }
2107     } else if(wined3d_settings.offscreen_rendering_mode == ORM_PBUFFER) {
2108         /* We can probably use this function in FBO mode too on some drivers to get some basic indication of the capabilities. */
2109         WineD3D_PixelFormat *cfgs = Adapters[Adapter].cfgs;
2110         int it;
2111
2112         /* Check if there is a WGL pixel format matching the requirements, the pixel format should also be usable with pbuffers */
2113         for (it = 0; it < Adapters[Adapter].nCfgs; ++it) {
2114             if (cfgs[it].pbufferDrawable && IWineD3DImpl_IsPixelFormatCompatibleWithRenderFmt(&cfgs[it], CheckFormat)) {
2115                 TRACE_(d3d_caps)("iPixelFormat=%d is compatible with CheckFormat=%s\n", cfgs[it].iPixelFormat, debug_d3dformat(CheckFormat));
2116                 return TRUE;
2117             }
2118         }
2119     } else if(wined3d_settings.offscreen_rendering_mode == ORM_FBO){
2120         /* For now return TRUE for FBOs until we have some proper checks.
2121          * Note that this function will only be called when the format is around for texturing. */
2122         return TRUE;
2123     }
2124     return FALSE;
2125 }
2126
2127 static BOOL CheckSrgbReadCapability(UINT Adapter, WINED3DFORMAT CheckFormat)
2128 {
2129     /* Check for supported sRGB formats (Texture loading and framebuffer) */
2130     if(!GL_SUPPORT(EXT_TEXTURE_SRGB)) {
2131         TRACE_(d3d_caps)("[FAILED] GL_EXT_texture_sRGB not supported\n");
2132         return FALSE;
2133     }
2134
2135     switch (CheckFormat) {
2136         case WINED3DFMT_A8R8G8B8:
2137         case WINED3DFMT_X8R8G8B8:
2138         case WINED3DFMT_A4R4G4B4:
2139         case WINED3DFMT_L8:
2140         case WINED3DFMT_A8L8:
2141         case WINED3DFMT_DXT1:
2142         case WINED3DFMT_DXT2:
2143         case WINED3DFMT_DXT3:
2144         case WINED3DFMT_DXT4:
2145         case WINED3DFMT_DXT5:
2146             TRACE_(d3d_caps)("[OK]\n");
2147             return TRUE;
2148
2149         default:
2150             TRACE_(d3d_caps)("[FAILED] Gamma texture format %s not supported.\n", debug_d3dformat(CheckFormat));
2151             return FALSE;
2152     }
2153     return FALSE;
2154 }
2155
2156 static BOOL CheckSrgbWriteCapability(UINT Adapter, WINED3DDEVTYPE DeviceType, WINED3DFORMAT CheckFormat)
2157 {
2158     /* Only offer SRGB writing on X8R8G8B8/A8R8G8B8 when we use ARB or GLSL shaders as we are
2159      * doing the color fixup in shaders.
2160      * Note Windows drivers (at least on the Geforce 8800) also offer this on R5G6B5. */
2161     if((CheckFormat == WINED3DFMT_X8R8G8B8) || (CheckFormat == WINED3DFMT_A8R8G8B8)) {
2162         int vs_selected_mode;
2163         int ps_selected_mode;
2164         select_shader_mode(&GLINFO_LOCATION, DeviceType, &ps_selected_mode, &vs_selected_mode);
2165
2166         if((ps_selected_mode == SHADER_ARB) || (ps_selected_mode == SHADER_GLSL)) {
2167             TRACE_(d3d_caps)("[OK]\n");
2168             return TRUE;
2169         }
2170     }
2171
2172     TRACE_(d3d_caps)("[FAILED] - no SRGB writing support on format=%s\n", debug_d3dformat(CheckFormat));
2173     return FALSE;
2174 }
2175
2176 /* Check if a format support blending in combination with pixel shaders */
2177 static BOOL CheckPostPixelShaderBlendingCapability(UINT Adapter, WINED3DFORMAT CheckFormat)
2178 {
2179     const struct GlPixelFormatDesc *glDesc;
2180     const StaticPixelFormatDesc *desc = getFormatDescEntry(CheckFormat, &GLINFO_LOCATION, &glDesc);
2181
2182     /* Fail if we weren't able to get a description of the format */
2183     if(!desc || !glDesc)
2184         return FALSE;
2185
2186     /* The flags entry of a format contains the post pixel shader blending capability */
2187     if(glDesc->Flags & WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING)
2188         return TRUE;
2189
2190     return FALSE;
2191 }
2192
2193 static BOOL CheckWrapAndMipCapability(UINT Adapter, WINED3DFORMAT CheckFormat) {
2194     /* OpenGL supports mipmapping on all formats basically. Wrapping is unsupported,
2195      * but we have to report mipmapping so we cannot reject this flag. Tests show that
2196      * windows reports WRAPANDMIP on unfilterable surfaces as well, apparently to show
2197      * that wrapping is supported. The lack of filtering will sort out the mipmapping
2198      * capability anyway.
2199      *
2200      * For now lets report this on all formats, but in the future we may want to
2201      * restrict it to some should games need that
2202      */
2203     return TRUE;
2204 }
2205
2206 /* Check if a texture format is supported on the given adapter */
2207 static BOOL CheckTextureCapability(UINT Adapter, WINED3DDEVTYPE DeviceType, WINED3DFORMAT CheckFormat)
2208 {
2209     const shader_backend_t *shader_backend;
2210     const struct fragment_pipeline *fp;
2211     const struct GlPixelFormatDesc *glDesc;
2212
2213     switch (CheckFormat) {
2214
2215         /*****
2216          *  supported: RGB(A) formats
2217          */
2218         case WINED3DFMT_R8G8B8: /* Enable for dx7, blacklisted for 8 and 9 above */
2219         case WINED3DFMT_A8R8G8B8:
2220         case WINED3DFMT_X8R8G8B8:
2221         case WINED3DFMT_R5G6B5:
2222         case WINED3DFMT_X1R5G5B5:
2223         case WINED3DFMT_A1R5G5B5:
2224         case WINED3DFMT_A4R4G4B4:
2225         case WINED3DFMT_A8_UNORM:
2226         case WINED3DFMT_X4R4G4B4:
2227         case WINED3DFMT_R8G8B8A8_UNORM:
2228         case WINED3DFMT_X8B8G8R8:
2229         case WINED3DFMT_A2R10G10B10:
2230         case WINED3DFMT_R10G10B10A2_UNORM:
2231         case WINED3DFMT_R16G16_UNORM:
2232             TRACE_(d3d_caps)("[OK]\n");
2233             return TRUE;
2234
2235         case WINED3DFMT_R3G3B2:
2236             TRACE_(d3d_caps)("[FAILED] - Not supported on Windows\n");
2237             return FALSE;
2238
2239         /*****
2240          *  supported: Palettized
2241          */
2242         case WINED3DFMT_P8:
2243             TRACE_(d3d_caps)("[OK]\n");
2244             return TRUE;
2245         /* No Windows driver offers A8P8, so don't offer it either */
2246         case WINED3DFMT_A8P8:
2247             return FALSE;
2248
2249         /*****
2250          *  Supported: (Alpha)-Luminance
2251          */
2252         case WINED3DFMT_L8:
2253         case WINED3DFMT_A8L8:
2254         case WINED3DFMT_L16:
2255             TRACE_(d3d_caps)("[OK]\n");
2256             return TRUE;
2257
2258         /* Not supported on Windows, thus disabled */
2259         case WINED3DFMT_A4L4:
2260             TRACE_(d3d_caps)("[FAILED] - not supported on windows\n");
2261             return FALSE;
2262
2263         /*****
2264          *  Supported: Depth/Stencil formats
2265          */
2266         case WINED3DFMT_D16_LOCKABLE:
2267         case WINED3DFMT_D16_UNORM:
2268         case WINED3DFMT_D15S1:
2269         case WINED3DFMT_D24X8:
2270         case WINED3DFMT_D24X4S4:
2271         case WINED3DFMT_D24S8:
2272         case WINED3DFMT_D24FS8:
2273         case WINED3DFMT_D32:
2274         case WINED3DFMT_D32F_LOCKABLE:
2275             return TRUE;
2276
2277         /*****
2278          *  Not supported everywhere(depends on GL_ATI_envmap_bumpmap or
2279          *  GL_NV_texture_shader). Emulated by shaders
2280          */
2281         case WINED3DFMT_R8G8_SNORM:
2282         case WINED3DFMT_X8L8V8U8:
2283         case WINED3DFMT_L6V5U5:
2284         case WINED3DFMT_R8G8B8A8_SNORM:
2285         case WINED3DFMT_R16G16_SNORM:
2286             /* Ask the shader backend if it can deal with the conversion. If
2287              * we've got a GL extension giving native support this will be an
2288              * identity conversion. */
2289             getFormatDescEntry(CheckFormat, &GLINFO_LOCATION, &glDesc);
2290             shader_backend = select_shader_backend(Adapter, DeviceType);
2291             if (shader_backend->shader_color_fixup_supported(glDesc->color_fixup))
2292             {
2293                 TRACE_(d3d_caps)("[OK]\n");
2294                 return TRUE;
2295             }
2296             TRACE_(d3d_caps)("[FAILED]\n");
2297             return FALSE;
2298
2299         case WINED3DFMT_DXT1:
2300         case WINED3DFMT_DXT2:
2301         case WINED3DFMT_DXT3:
2302         case WINED3DFMT_DXT4:
2303         case WINED3DFMT_DXT5:
2304             if (GL_SUPPORT(EXT_TEXTURE_COMPRESSION_S3TC)) {
2305                 TRACE_(d3d_caps)("[OK]\n");
2306                 return TRUE;
2307             }
2308             TRACE_(d3d_caps)("[FAILED]\n");
2309             return FALSE;
2310
2311
2312         /*****
2313          *  Odd formats - not supported
2314          */
2315         case WINED3DFMT_VERTEXDATA:
2316         case WINED3DFMT_R16_UINT:
2317         case WINED3DFMT_R32_UINT:
2318         case WINED3DFMT_R16G16B16A16_SNORM:
2319         case WINED3DFMT_A2W10V10U10:
2320         case WINED3DFMT_W11V11U10:
2321             TRACE_(d3d_caps)("[FAILED]\n"); /* Enable when implemented */
2322             return FALSE;
2323
2324         /*****
2325          *  WINED3DFMT_CxV8U8: Not supported right now
2326          */
2327         case WINED3DFMT_CxV8U8:
2328             TRACE_(d3d_caps)("[FAILED]\n"); /* Enable when implemented */
2329             return FALSE;
2330
2331         /* YUV formats */
2332         case WINED3DFMT_UYVY:
2333         case WINED3DFMT_YUY2:
2334             if(GL_SUPPORT(APPLE_YCBCR_422)) {
2335                 TRACE_(d3d_caps)("[OK]\n");
2336                 return TRUE;
2337             }
2338             TRACE_(d3d_caps)("[FAILED]\n");
2339             return FALSE;
2340         case WINED3DFMT_YV12:
2341             TRACE_(d3d_caps)("[FAILED]\n");
2342             return FALSE;
2343
2344             /* Not supported */
2345         case WINED3DFMT_R16G16B16A16_UNORM:
2346         case WINED3DFMT_A8R3G3B2:
2347             TRACE_(d3d_caps)("[FAILED]\n"); /* Enable when implemented */
2348             return FALSE;
2349
2350             /* Floating point formats */
2351         case WINED3DFMT_R16_FLOAT:
2352         case WINED3DFMT_R16G16B16A16_FLOAT:
2353             if(GL_SUPPORT(ARB_TEXTURE_FLOAT) && GL_SUPPORT(ARB_HALF_FLOAT_PIXEL)) {
2354                 TRACE_(d3d_caps)("[OK]\n");
2355                 return TRUE;
2356             }
2357             TRACE_(d3d_caps)("[FAILED]\n");
2358             return FALSE;
2359
2360         case WINED3DFMT_R32_FLOAT:
2361         case WINED3DFMT_R32G32B32A32_FLOAT:
2362             if (GL_SUPPORT(ARB_TEXTURE_FLOAT)) {
2363                 TRACE_(d3d_caps)("[OK]\n");
2364                 return TRUE;
2365             }
2366             TRACE_(d3d_caps)("[FAILED]\n");
2367             return FALSE;
2368
2369         case WINED3DFMT_R16G16_FLOAT:
2370         case WINED3DFMT_R32G32_FLOAT:
2371             if(GL_SUPPORT(ARB_TEXTURE_RG)) {
2372                 TRACE_(d3d_caps)("[OK]\n");
2373                 return TRUE;
2374             }
2375             TRACE_(d3d_caps)("[FAILED]\n");
2376             return FALSE;
2377
2378         /* ATI instancing hack: Although ATI cards do not support Shader Model 3.0, they support
2379          * instancing. To query if the card supports instancing CheckDeviceFormat with the special format
2380          * MAKEFOURCC('I','N','S','T') is used. Should a (broken) app check for this provide a proper return value.
2381          * We can do instancing with all shader versions, but we need vertex shaders.
2382          *
2383          * Additionally applications have to set the D3DRS_POINTSIZE render state to MAKEFOURCC('I','N','S','T') once
2384          * to enable instancing. WineD3D doesn't need that and just ignores it.
2385          *
2386          * With Shader Model 3.0 capable cards Instancing 'just works' in Windows.
2387          */
2388         case WINEMAKEFOURCC('I','N','S','T'):
2389             TRACE("ATI Instancing check hack\n");
2390             if(GL_SUPPORT(ARB_VERTEX_PROGRAM) || GL_SUPPORT(ARB_VERTEX_SHADER)) {
2391                 TRACE_(d3d_caps)("[OK]\n");
2392                 return TRUE;
2393             }
2394             TRACE_(d3d_caps)("[FAILED]\n");
2395             return FALSE;
2396
2397         /* Some weird FOURCC formats */
2398         case WINED3DFMT_R8G8_B8G8:
2399         case WINED3DFMT_G8R8_G8B8:
2400         case WINED3DFMT_MULTI2_ARGB8:
2401             TRACE_(d3d_caps)("[FAILED]\n");
2402             return FALSE;
2403
2404         /* Vendor specific formats */
2405         case WINED3DFMT_ATI2N:
2406             if(GL_SUPPORT(ATI_TEXTURE_COMPRESSION_3DC) || GL_SUPPORT(EXT_TEXTURE_COMPRESSION_RGTC)) {
2407                 getFormatDescEntry(CheckFormat, &GLINFO_LOCATION, &glDesc);
2408                 shader_backend = select_shader_backend(Adapter, DeviceType);
2409                 fp = select_fragment_implementation(Adapter, DeviceType);
2410                 if (shader_backend->shader_color_fixup_supported(glDesc->color_fixup)
2411                         && fp->color_fixup_supported(glDesc->color_fixup))
2412                 {
2413                     TRACE_(d3d_caps)("[OK]\n");
2414                     return TRUE;
2415                 }
2416
2417                 TRACE_(d3d_caps)("[OK]\n");
2418                 return TRUE;
2419             }
2420             TRACE_(d3d_caps)("[FAILED]\n");
2421             return FALSE;
2422
2423         case WINED3DFMT_NVHU:
2424         case WINED3DFMT_NVHS:
2425             /* These formats seem to be similar to the HILO formats in GL_NV_texture_shader. NVHU
2426              * is said to be GL_UNSIGNED_HILO16, NVHS GL_SIGNED_HILO16. Rumours say that d3d computes
2427              * a 3rd channel similarly to D3DFMT_CxV8U8(So NVHS could be called D3DFMT_CxV16U16).
2428              * ATI refused to support formats which can easilly be emulated with pixel shaders, so
2429              * Applications have to deal with not having NVHS and NVHU.
2430              */
2431             TRACE_(d3d_caps)("[FAILED]\n");
2432             return FALSE;
2433
2434         case WINED3DFMT_UNKNOWN:
2435             return FALSE;
2436
2437         default:
2438             ERR("Unhandled format=%s\n", debug_d3dformat(CheckFormat));
2439             break;
2440     }
2441     return FALSE;
2442 }
2443
2444 static BOOL CheckSurfaceCapability(UINT Adapter, WINED3DFORMAT AdapterFormat, WINED3DDEVTYPE DeviceType, WINED3DFORMAT CheckFormat, WINED3DSURFTYPE SurfaceType) {
2445     const struct GlPixelFormatDesc *format_desc;
2446     const struct blit_shader *blitter;
2447
2448     if(SurfaceType == SURFACE_GDI) {
2449         switch(CheckFormat) {
2450             case WINED3DFMT_R8G8B8:
2451             case WINED3DFMT_A8R8G8B8:
2452             case WINED3DFMT_X8R8G8B8:
2453             case WINED3DFMT_R5G6B5:
2454             case WINED3DFMT_X1R5G5B5:
2455             case WINED3DFMT_A1R5G5B5:
2456             case WINED3DFMT_A4R4G4B4:
2457             case WINED3DFMT_R3G3B2:
2458             case WINED3DFMT_A8_UNORM:
2459             case WINED3DFMT_A8R3G3B2:
2460             case WINED3DFMT_X4R4G4B4:
2461             case WINED3DFMT_R10G10B10A2_UNORM:
2462             case WINED3DFMT_R8G8B8A8_UNORM:
2463             case WINED3DFMT_X8B8G8R8:
2464             case WINED3DFMT_R16G16_UNORM:
2465             case WINED3DFMT_A2R10G10B10:
2466             case WINED3DFMT_R16G16B16A16_UNORM:
2467             case WINED3DFMT_P8:
2468                 TRACE_(d3d_caps)("[OK]\n");
2469                 return TRUE;
2470             default:
2471                 TRACE_(d3d_caps)("[FAILED] - not available on GDI surfaces\n");
2472                 return FALSE;
2473         }
2474     }
2475
2476     /* All format that are supported for textures are supported for surfaces as well */
2477     if(CheckTextureCapability(Adapter, DeviceType, CheckFormat)) return TRUE;
2478     /* All depth stencil formats are supported on surfaces */
2479     if(CheckDepthStencilCapability(Adapter, AdapterFormat, CheckFormat)) return TRUE;
2480
2481     /* If opengl can't process the format natively, the blitter may be able to convert it */
2482     getFormatDescEntry(CheckFormat, &GLINFO_LOCATION, &format_desc);
2483     blitter = select_blit_implementation(Adapter, DeviceType);
2484     if (blitter->color_fixup_supported(format_desc->color_fixup))
2485     {
2486         TRACE_(d3d_caps)("[OK]\n");
2487         return TRUE;
2488     }
2489
2490     /* Reject other formats */
2491     TRACE_(d3d_caps)("[FAILED]\n");
2492     return FALSE;
2493 }
2494
2495 static BOOL CheckVertexTextureCapability(UINT Adapter, WINED3DFORMAT CheckFormat)
2496 {
2497     if (!GL_LIMITS(vertex_samplers)) {
2498         TRACE_(d3d_caps)("[FAILED]\n");
2499         return FALSE;
2500     }
2501
2502     switch (CheckFormat) {
2503         case WINED3DFMT_R32G32B32A32_FLOAT:
2504             if (!GL_SUPPORT(ARB_TEXTURE_FLOAT)) {
2505                 TRACE_(d3d_caps)("[FAILED]\n");
2506                 return FALSE;
2507             }
2508             TRACE_(d3d_caps)("[OK]\n");
2509             return TRUE;
2510
2511         default:
2512             TRACE_(d3d_caps)("[FAILED]\n");
2513             return FALSE;
2514     }
2515     return FALSE;
2516 }
2517
2518 static HRESULT WINAPI IWineD3DImpl_CheckDeviceFormat(IWineD3D *iface, UINT Adapter, WINED3DDEVTYPE DeviceType, 
2519         WINED3DFORMAT AdapterFormat, DWORD Usage, WINED3DRESOURCETYPE RType, WINED3DFORMAT CheckFormat,
2520         WINED3DSURFTYPE SurfaceType) {
2521     IWineD3DImpl *This = (IWineD3DImpl *)iface;
2522     DWORD UsageCaps = 0;
2523
2524     TRACE_(d3d_caps)("(%p)-> (STUB) (Adptr:%d, DevType:(%u,%s), AdptFmt:(%u,%s), Use:(%u,%s,%s), ResTyp:(%x,%s), CheckFmt:(%u,%s))\n",
2525           This,
2526           Adapter,
2527           DeviceType, debug_d3ddevicetype(DeviceType),
2528           AdapterFormat, debug_d3dformat(AdapterFormat),
2529           Usage, debug_d3dusage(Usage), debug_d3dusagequery(Usage),
2530           RType, debug_d3dresourcetype(RType),
2531           CheckFormat, debug_d3dformat(CheckFormat));
2532
2533     if (Adapter >= IWineD3D_GetAdapterCount(iface)) {
2534         return WINED3DERR_INVALIDCALL;
2535     }
2536
2537     if(RType == WINED3DRTYPE_CUBETEXTURE) {
2538
2539         if(SurfaceType != SURFACE_OPENGL) {
2540             TRACE("[FAILED]\n");
2541             return WINED3DERR_NOTAVAILABLE;
2542         }
2543
2544         /* Cubetexture allows:
2545          *                    - D3DUSAGE_AUTOGENMIPMAP
2546          *                    - D3DUSAGE_DEPTHSTENCIL
2547          *                    - D3DUSAGE_DYNAMIC
2548          *                    - D3DUSAGE_NONSECURE (d3d9ex)
2549          *                    - D3DUSAGE_RENDERTARGET
2550          *                    - D3DUSAGE_SOFTWAREPROCESSING
2551          *                    - D3DUSAGE_QUERY_WRAPANDMIP
2552          */
2553         if(GL_SUPPORT(ARB_TEXTURE_CUBE_MAP)) {
2554             /* Check if the texture format is around */
2555             if(CheckTextureCapability(Adapter, DeviceType, CheckFormat)) {
2556                 if(Usage & WINED3DUSAGE_AUTOGENMIPMAP) {
2557                     /* Check for automatic mipmap generation support */
2558                     if(GL_SUPPORT(SGIS_GENERATE_MIPMAP)) {
2559                         UsageCaps |= WINED3DUSAGE_AUTOGENMIPMAP;
2560                     } else {
2561                         /* When autogenmipmap isn't around continue and return WINED3DOK_NOAUTOGEN instead of D3D_OK */
2562                         TRACE_(d3d_caps)("[FAILED] - No autogenmipmap support, but continuing\n");
2563                     }
2564                 }
2565
2566                 /* Always report dynamic locking */
2567                 if(Usage & WINED3DUSAGE_DYNAMIC)
2568                     UsageCaps |= WINED3DUSAGE_DYNAMIC;
2569
2570                 if(Usage & WINED3DUSAGE_RENDERTARGET) {
2571                     if(CheckRenderTargetCapability(AdapterFormat, CheckFormat)) {
2572                         UsageCaps |= WINED3DUSAGE_RENDERTARGET;
2573                     } else {
2574                         TRACE_(d3d_caps)("[FAILED] - No rendertarget support\n");
2575                         return WINED3DERR_NOTAVAILABLE;
2576                     }
2577                 }
2578
2579                 /* Always report software processing */
2580                 if(Usage & WINED3DUSAGE_SOFTWAREPROCESSING)
2581                     UsageCaps |= WINED3DUSAGE_SOFTWAREPROCESSING;
2582
2583                 /* Check QUERY_FILTER support */
2584                 if(Usage & WINED3DUSAGE_QUERY_FILTER) {
2585                     if(CheckFilterCapability(Adapter, CheckFormat)) {
2586                         UsageCaps |= WINED3DUSAGE_QUERY_FILTER;
2587                     } else {
2588                         TRACE_(d3d_caps)("[FAILED] - No query filter support\n");
2589                         return WINED3DERR_NOTAVAILABLE;
2590                     }
2591                 }
2592
2593                 /* Check QUERY_POSTPIXELSHADER_BLENDING support */
2594                 if(Usage & WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING) {
2595                     if(CheckPostPixelShaderBlendingCapability(Adapter, CheckFormat)) {
2596                         UsageCaps |= WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING;
2597                     } else {
2598                         TRACE_(d3d_caps)("[FAILED] - No query post pixelshader blending support\n");
2599                         return WINED3DERR_NOTAVAILABLE;
2600                     }
2601                 }
2602
2603                 /* Check QUERY_SRGBREAD support */
2604                 if(Usage & WINED3DUSAGE_QUERY_SRGBREAD) {
2605                     if(CheckSrgbReadCapability(Adapter, CheckFormat)) {
2606                         UsageCaps |= WINED3DUSAGE_QUERY_SRGBREAD;
2607                     } else {
2608                         TRACE_(d3d_caps)("[FAILED] - No query srgbread support\n");
2609                         return WINED3DERR_NOTAVAILABLE;
2610                     }
2611                 }
2612
2613                 /* Check QUERY_SRGBWRITE support */
2614                 if(Usage & WINED3DUSAGE_QUERY_SRGBWRITE) {
2615                     if(CheckSrgbWriteCapability(Adapter, DeviceType, CheckFormat)) {
2616                         UsageCaps |= WINED3DUSAGE_QUERY_SRGBWRITE;
2617                     } else {
2618                         TRACE_(d3d_caps)("[FAILED] - No query srgbwrite support\n");
2619                         return WINED3DERR_NOTAVAILABLE;
2620                     }
2621                 }
2622
2623                 /* Check QUERY_VERTEXTEXTURE support */
2624                 if(Usage & WINED3DUSAGE_QUERY_VERTEXTEXTURE) {
2625                     if(CheckVertexTextureCapability(Adapter, CheckFormat)) {
2626                         UsageCaps |= WINED3DUSAGE_QUERY_VERTEXTEXTURE;
2627                     } else {
2628                         TRACE_(d3d_caps)("[FAILED] - No query vertextexture support\n");
2629                         return WINED3DERR_NOTAVAILABLE;
2630                     }
2631                 }
2632
2633                 /* Check QUERY_WRAPANDMIP support */
2634                 if(Usage & WINED3DUSAGE_QUERY_WRAPANDMIP) {
2635                     if(CheckWrapAndMipCapability(Adapter, CheckFormat)) {
2636                         UsageCaps |= WINED3DUSAGE_QUERY_WRAPANDMIP;
2637                     } else {
2638                         TRACE_(d3d_caps)("[FAILED] - No wrapping and mipmapping support\n");
2639                         return WINED3DERR_NOTAVAILABLE;
2640                     }
2641                 }
2642             } else {
2643                 TRACE_(d3d_caps)("[FAILED] - Cube texture format not supported\n");
2644                 return WINED3DERR_NOTAVAILABLE;
2645             }
2646         } else {
2647             TRACE_(d3d_caps)("[FAILED] - No cube texture support\n");
2648             return WINED3DERR_NOTAVAILABLE;
2649         }
2650     } else if(RType == WINED3DRTYPE_SURFACE) {
2651         /* Surface allows:
2652          *                - D3DUSAGE_DEPTHSTENCIL
2653          *                - D3DUSAGE_NONSECURE (d3d9ex)
2654          *                - D3DUSAGE_RENDERTARGET
2655          */
2656
2657         if(CheckSurfaceCapability(Adapter, AdapterFormat, DeviceType, CheckFormat, SurfaceType)) {
2658             if(Usage & WINED3DUSAGE_DEPTHSTENCIL) {
2659                 if(CheckDepthStencilCapability(Adapter, AdapterFormat, CheckFormat)) {
2660                     UsageCaps |= WINED3DUSAGE_DEPTHSTENCIL;
2661                 } else {
2662                     TRACE_(d3d_caps)("[FAILED] - No depthstencil support\n");
2663                     return WINED3DERR_NOTAVAILABLE;
2664                 }
2665             }
2666
2667             if(Usage & WINED3DUSAGE_RENDERTARGET) {
2668                 if(CheckRenderTargetCapability(AdapterFormat, CheckFormat)) {
2669                     UsageCaps |= WINED3DUSAGE_RENDERTARGET;
2670                 } else {
2671                     TRACE_(d3d_caps)("[FAILED] - No rendertarget support\n");
2672                     return WINED3DERR_NOTAVAILABLE;
2673                 }
2674             }
2675
2676             /* Check QUERY_POSTPIXELSHADER_BLENDING support */
2677             if(Usage & WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING) {
2678                 if(CheckPostPixelShaderBlendingCapability(Adapter, CheckFormat)) {
2679                     UsageCaps |= WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING;
2680                 } else {
2681                     TRACE_(d3d_caps)("[FAILED] - No query post pixelshader blending support\n");
2682                     return WINED3DERR_NOTAVAILABLE;
2683                 }
2684             }
2685         } else {
2686             TRACE_(d3d_caps)("[FAILED] - Not supported for plain surfaces\n");
2687             return WINED3DERR_NOTAVAILABLE;
2688         }
2689
2690     } else if(RType == WINED3DRTYPE_TEXTURE) {
2691         /* Texture allows:
2692          *                - D3DUSAGE_AUTOGENMIPMAP
2693          *                - D3DUSAGE_DEPTHSTENCIL
2694          *                - D3DUSAGE_DMAP
2695          *                - D3DUSAGE_DYNAMIC
2696          *                - D3DUSAGE_NONSECURE (d3d9ex)
2697          *                - D3DUSAGE_RENDERTARGET
2698          *                - D3DUSAGE_SOFTWAREPROCESSING
2699          *                - D3DUSAGE_TEXTAPI (d3d9ex)
2700          *                - D3DUSAGE_QUERY_WRAPANDMIP
2701          */
2702
2703         if(SurfaceType != SURFACE_OPENGL) {
2704             TRACE("[FAILED]\n");
2705             return WINED3DERR_NOTAVAILABLE;
2706         }
2707
2708         /* Check if the texture format is around */
2709         if(CheckTextureCapability(Adapter, DeviceType, CheckFormat)) {
2710             if(Usage & WINED3DUSAGE_AUTOGENMIPMAP) {
2711                 /* Check for automatic mipmap generation support */
2712                 if(GL_SUPPORT(SGIS_GENERATE_MIPMAP)) {
2713                     UsageCaps |= WINED3DUSAGE_AUTOGENMIPMAP;
2714                 } else {
2715                     /* When autogenmipmap isn't around continue and return WINED3DOK_NOAUTOGEN instead of D3D_OK */
2716                     TRACE_(d3d_caps)("[FAILED] - No autogenmipmap support, but continuing\n");
2717                 }
2718             }
2719
2720             /* Always report dynamic locking */
2721             if(Usage & WINED3DUSAGE_DYNAMIC)
2722                 UsageCaps |= WINED3DUSAGE_DYNAMIC;
2723
2724             if(Usage & WINED3DUSAGE_RENDERTARGET) {
2725                 if(CheckRenderTargetCapability(AdapterFormat, CheckFormat)) {
2726                     UsageCaps |= WINED3DUSAGE_RENDERTARGET;
2727                 } else {
2728                     TRACE_(d3d_caps)("[FAILED] - No rendertarget support\n");
2729                      return WINED3DERR_NOTAVAILABLE;
2730                  }
2731             }
2732
2733             /* Always report software processing */
2734             if(Usage & WINED3DUSAGE_SOFTWAREPROCESSING)
2735                 UsageCaps |= WINED3DUSAGE_SOFTWAREPROCESSING;
2736
2737             /* Check QUERY_FILTER support */
2738             if(Usage & WINED3DUSAGE_QUERY_FILTER) {
2739                 if(CheckFilterCapability(Adapter, CheckFormat)) {
2740                     UsageCaps |= WINED3DUSAGE_QUERY_FILTER;
2741                 } else {
2742                     TRACE_(d3d_caps)("[FAILED] - No query filter support\n");
2743                     return WINED3DERR_NOTAVAILABLE;
2744                 }
2745             }
2746
2747             /* Check QUERY_LEGACYBUMPMAP support */
2748             if(Usage & WINED3DUSAGE_QUERY_LEGACYBUMPMAP) {
2749                 if(CheckBumpMapCapability(Adapter, DeviceType, CheckFormat)) {
2750                     UsageCaps |= WINED3DUSAGE_QUERY_LEGACYBUMPMAP;
2751                 } else {
2752                     TRACE_(d3d_caps)("[FAILED] - No legacy bumpmap support\n");
2753                     return WINED3DERR_NOTAVAILABLE;
2754                 }
2755             }
2756
2757             /* Check QUERY_POSTPIXELSHADER_BLENDING support */
2758             if(Usage & WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING) {
2759                 if(CheckPostPixelShaderBlendingCapability(Adapter, CheckFormat)) {
2760                     UsageCaps |= WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING;
2761                 } else {
2762                     TRACE_(d3d_caps)("[FAILED] - No query post pixelshader blending support\n");
2763                     return WINED3DERR_NOTAVAILABLE;
2764                 }
2765             }
2766
2767             /* Check QUERY_SRGBREAD support */
2768             if(Usage & WINED3DUSAGE_QUERY_SRGBREAD) {
2769                 if(CheckSrgbReadCapability(Adapter, CheckFormat)) {
2770                     UsageCaps |= WINED3DUSAGE_QUERY_SRGBREAD;
2771                 } else {
2772                     TRACE_(d3d_caps)("[FAILED] - No query srgbread support\n");
2773                     return WINED3DERR_NOTAVAILABLE;
2774                 }
2775             }
2776
2777             /* Check QUERY_SRGBWRITE support */
2778             if(Usage & WINED3DUSAGE_QUERY_SRGBWRITE) {
2779                 if(CheckSrgbWriteCapability(Adapter, DeviceType, CheckFormat)) {
2780                     UsageCaps |= WINED3DUSAGE_QUERY_SRGBWRITE;
2781                 } else {
2782                     TRACE_(d3d_caps)("[FAILED] - No query srgbwrite support\n");
2783                     return WINED3DERR_NOTAVAILABLE;
2784                 }
2785             }
2786
2787             /* Check QUERY_VERTEXTEXTURE support */
2788             if(Usage & WINED3DUSAGE_QUERY_VERTEXTEXTURE) {
2789                 if(CheckVertexTextureCapability(Adapter, CheckFormat)) {
2790                     UsageCaps |= WINED3DUSAGE_QUERY_VERTEXTEXTURE;
2791                 } else {
2792                     TRACE_(d3d_caps)("[FAILED] - No query vertextexture support\n");
2793                     return WINED3DERR_NOTAVAILABLE;
2794                 }
2795             }
2796
2797             /* Check QUERY_WRAPANDMIP support */
2798             if(Usage & WINED3DUSAGE_QUERY_WRAPANDMIP) {
2799                 if(CheckWrapAndMipCapability(Adapter, CheckFormat)) {
2800                     UsageCaps |= WINED3DUSAGE_QUERY_WRAPANDMIP;
2801                 } else {
2802                     TRACE_(d3d_caps)("[FAILED] - No wrapping and mipmapping support\n");
2803                     return WINED3DERR_NOTAVAILABLE;
2804                 }
2805             }
2806
2807             if(Usage & WINED3DUSAGE_DEPTHSTENCIL) {
2808                 if(CheckDepthStencilCapability(Adapter, AdapterFormat, CheckFormat)) {
2809                     UsageCaps |= WINED3DUSAGE_DEPTHSTENCIL;
2810                 } else {
2811                     TRACE_(d3d_caps)("[FAILED] - No depth stencil support\n");
2812                     return WINED3DERR_NOTAVAILABLE;
2813                 }
2814             }
2815         } else {
2816             TRACE_(d3d_caps)("[FAILED] - Texture format not supported\n");
2817             return WINED3DERR_NOTAVAILABLE;
2818         }
2819     } else if((RType == WINED3DRTYPE_VOLUME) || (RType == WINED3DRTYPE_VOLUMETEXTURE)) {
2820         /* Volume is to VolumeTexture what Surface is to Texture but its usage caps are not documented.
2821          * Most driver seem to offer (nearly) the same on Volume and VolumeTexture, so do that too.
2822          *
2823          * Volumetexture allows:
2824          *                      - D3DUSAGE_DYNAMIC
2825          *                      - D3DUSAGE_NONSECURE (d3d9ex)
2826          *                      - D3DUSAGE_SOFTWAREPROCESSING
2827          *                      - D3DUSAGE_QUERY_WRAPANDMIP
2828          */
2829
2830         if(SurfaceType != SURFACE_OPENGL) {
2831             TRACE("[FAILED]\n");
2832             return WINED3DERR_NOTAVAILABLE;
2833         }
2834
2835         /* Check volume texture and volume usage caps */
2836         if(GL_SUPPORT(EXT_TEXTURE3D)) {
2837             if(CheckTextureCapability(Adapter, DeviceType, CheckFormat) == FALSE) {
2838                 TRACE_(d3d_caps)("[FAILED] - Format not supported\n");
2839                 return WINED3DERR_NOTAVAILABLE;
2840             }
2841
2842             /* Always report dynamic locking */
2843             if(Usage & WINED3DUSAGE_DYNAMIC)
2844                 UsageCaps |= WINED3DUSAGE_DYNAMIC;
2845
2846             /* Always report software processing */
2847             if(Usage & WINED3DUSAGE_SOFTWAREPROCESSING)
2848                 UsageCaps |= WINED3DUSAGE_SOFTWAREPROCESSING;
2849
2850             /* Check QUERY_FILTER support */
2851             if(Usage & WINED3DUSAGE_QUERY_FILTER) {
2852                 if(CheckFilterCapability(Adapter, CheckFormat)) {
2853                     UsageCaps |= WINED3DUSAGE_QUERY_FILTER;
2854                 } else {
2855                     TRACE_(d3d_caps)("[FAILED] - No query filter support\n");
2856                     return WINED3DERR_NOTAVAILABLE;
2857                 }
2858             }
2859
2860             /* Check QUERY_POSTPIXELSHADER_BLENDING support */
2861             if(Usage & WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING) {
2862                 if(CheckPostPixelShaderBlendingCapability(Adapter, CheckFormat)) {
2863                     UsageCaps |= WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING;
2864                 } else {
2865                     TRACE_(d3d_caps)("[FAILED] - No query post pixelshader blending support\n");
2866                     return WINED3DERR_NOTAVAILABLE;
2867                 }
2868             }
2869
2870             /* Check QUERY_SRGBREAD support */
2871             if(Usage & WINED3DUSAGE_QUERY_SRGBREAD) {
2872                 if(CheckSrgbReadCapability(Adapter, CheckFormat)) {
2873                     UsageCaps |= WINED3DUSAGE_QUERY_SRGBREAD;
2874                 } else {
2875                     TRACE_(d3d_caps)("[FAILED] - No query srgbread support\n");
2876                     return WINED3DERR_NOTAVAILABLE;
2877                 }
2878             }
2879
2880             /* Check QUERY_SRGBWRITE support */
2881             if(Usage & WINED3DUSAGE_QUERY_SRGBWRITE) {
2882                 if(CheckSrgbWriteCapability(Adapter, DeviceType, CheckFormat)) {
2883                     UsageCaps |= WINED3DUSAGE_QUERY_SRGBWRITE;
2884                 } else {
2885                     TRACE_(d3d_caps)("[FAILED] - No query srgbwrite support\n");
2886                     return WINED3DERR_NOTAVAILABLE;
2887                 }
2888             }
2889
2890             /* Check QUERY_VERTEXTEXTURE support */
2891             if(Usage & WINED3DUSAGE_QUERY_VERTEXTEXTURE) {
2892                 if(CheckVertexTextureCapability(Adapter, CheckFormat)) {
2893                     UsageCaps |= WINED3DUSAGE_QUERY_VERTEXTEXTURE;
2894                 } else {
2895                     TRACE_(d3d_caps)("[FAILED] - No query vertextexture support\n");
2896                     return WINED3DERR_NOTAVAILABLE;
2897                 }
2898             }
2899
2900             /* Check QUERY_WRAPANDMIP support */
2901             if(Usage & WINED3DUSAGE_QUERY_WRAPANDMIP) {
2902                 if(CheckWrapAndMipCapability(Adapter, CheckFormat)) {
2903                     UsageCaps |= WINED3DUSAGE_QUERY_WRAPANDMIP;
2904                 } else {
2905                     TRACE_(d3d_caps)("[FAILED] - No wrapping and mipmapping support\n");
2906                     return WINED3DERR_NOTAVAILABLE;
2907                 }
2908             }
2909         } else {
2910             TRACE_(d3d_caps)("[FAILED] - No volume texture support\n");
2911             return WINED3DERR_NOTAVAILABLE;
2912         }
2913
2914         /* Filter formats that need conversion; For one part, this conversion is unimplemented,
2915          * and volume textures are huge, so it would be a big performance hit. Unless we hit an
2916          * app needing one of those formats, don't advertize them to avoid leading apps into
2917          * temptation. The windows drivers don't support most of those formats on volumes anyway,
2918          * except of R32F.
2919          */
2920         switch(CheckFormat) {
2921             case WINED3DFMT_P8:
2922             case WINED3DFMT_A4L4:
2923             case WINED3DFMT_R32_FLOAT:
2924             case WINED3DFMT_R16_FLOAT:
2925             case WINED3DFMT_X8L8V8U8:
2926             case WINED3DFMT_L6V5U5:
2927             case WINED3DFMT_R16G16_UNORM:
2928                 TRACE_(d3d_caps)("[FAILED] - No converted formats on volumes\n");
2929                 return WINED3DERR_NOTAVAILABLE;
2930
2931             case WINED3DFMT_R8G8B8A8_SNORM:
2932             case WINED3DFMT_R16G16_SNORM:
2933             if(!GL_SUPPORT(NV_TEXTURE_SHADER)) {
2934                 TRACE_(d3d_caps)("[FAILED] - No converted formats on volumes\n");
2935                 return WINED3DERR_NOTAVAILABLE;
2936             }
2937             break;
2938
2939             case WINED3DFMT_R8G8_SNORM:
2940             if(!GL_SUPPORT(NV_TEXTURE_SHADER)) {
2941                 TRACE_(d3d_caps)("[FAILED] - No converted formats on volumes\n");
2942                 return WINED3DERR_NOTAVAILABLE;
2943             }
2944             break;
2945
2946             case WINED3DFMT_DXT1:
2947             case WINED3DFMT_DXT2:
2948             case WINED3DFMT_DXT3:
2949             case WINED3DFMT_DXT4:
2950             case WINED3DFMT_DXT5:
2951                 /* The GL_EXT_texture_compression_s3tc spec requires that loading an s3tc
2952                  * compressed texture results in an error. While the D3D refrast does
2953                  * support s3tc volumes, at least the nvidia windows driver does not, so
2954                  * we're free not to support this format.
2955                  */
2956                 TRACE_(d3d_caps)("[FAILED] - DXTn does not support 3D textures\n");
2957                 return WINED3DERR_NOTAVAILABLE;
2958
2959             default:
2960                 /* Do nothing, continue with checking the format below */
2961                 break;
2962         }
2963     } else if((RType == WINED3DRTYPE_INDEXBUFFER) || (RType == WINED3DRTYPE_VERTEXBUFFER)){
2964         /* For instance vertexbuffer/indexbuffer aren't supported yet because no Windows drivers seem to offer it */
2965         TRACE_(d3d_caps)("Unhandled resource type D3DRTYPE_INDEXBUFFER / D3DRTYPE_VERTEXBUFFER\n");
2966         return WINED3DERR_NOTAVAILABLE;
2967     }
2968
2969     /* This format is nothing special and it is supported perfectly.
2970      * However, ati and nvidia driver on windows do not mark this format as
2971      * supported (tested with the dxCapsViewer) and pretending to
2972      * support this format uncovers a bug in Battlefield 1942 (fonts are missing)
2973      * So do the same as Windows drivers and pretend not to support it on dx8 and 9
2974      * Enable it on dx7. It will need additional checking on dx10 when we support it.
2975      */
2976     if(This->dxVersion > 7 && CheckFormat == WINED3DFMT_R8G8B8) {
2977         TRACE_(d3d_caps)("[FAILED]\n");
2978         return WINED3DERR_NOTAVAILABLE;
2979     }
2980
2981     /* When the UsageCaps exactly matches Usage return WINED3D_OK except for the situation in which
2982      * WINED3DUSAGE_AUTOGENMIPMAP isn't around, then WINED3DOK_NOAUTOGEN is returned if all the other
2983      * usage flags match. */
2984     if(UsageCaps == Usage) {
2985         return WINED3D_OK;
2986     } else if((UsageCaps == (Usage & ~WINED3DUSAGE_AUTOGENMIPMAP)) && (Usage & WINED3DUSAGE_AUTOGENMIPMAP)){
2987         return WINED3DOK_NOAUTOGEN;
2988     } else {
2989         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);
2990         return WINED3DERR_NOTAVAILABLE;
2991     }
2992 }
2993
2994 static HRESULT  WINAPI IWineD3DImpl_CheckDeviceFormatConversion(IWineD3D *iface, UINT Adapter, WINED3DDEVTYPE DeviceType,
2995                                                           WINED3DFORMAT SourceFormat, WINED3DFORMAT TargetFormat) {
2996     IWineD3DImpl *This = (IWineD3DImpl *)iface;
2997
2998     FIXME_(d3d_caps)("(%p)-> (STUB) (Adptr:%d, DevType:(%u,%s), SrcFmt:(%u,%s), TgtFmt:(%u,%s))\n",
2999           This,
3000           Adapter,
3001           DeviceType, debug_d3ddevicetype(DeviceType),
3002           SourceFormat, debug_d3dformat(SourceFormat),
3003           TargetFormat, debug_d3dformat(TargetFormat));
3004     return WINED3D_OK;
3005 }
3006
3007 static const shader_backend_t *select_shader_backend(UINT Adapter, WINED3DDEVTYPE DeviceType) {
3008     const shader_backend_t *ret;
3009     int vs_selected_mode;
3010     int ps_selected_mode;
3011
3012     select_shader_mode(&GLINFO_LOCATION, DeviceType, &ps_selected_mode, &vs_selected_mode);
3013     if (vs_selected_mode == SHADER_GLSL || ps_selected_mode == SHADER_GLSL) {
3014         ret = &glsl_shader_backend;
3015     } else if (vs_selected_mode == SHADER_ARB || ps_selected_mode == SHADER_ARB) {
3016         ret = &arb_program_shader_backend;
3017     } else {
3018         ret = &none_shader_backend;
3019     }
3020     return ret;
3021 }
3022
3023 static const struct fragment_pipeline *select_fragment_implementation(UINT Adapter, WINED3DDEVTYPE DeviceType) {
3024     int vs_selected_mode;
3025     int ps_selected_mode;
3026
3027     select_shader_mode(&GLINFO_LOCATION, DeviceType, &ps_selected_mode, &vs_selected_mode);
3028     if((ps_selected_mode == SHADER_ARB || ps_selected_mode == SHADER_GLSL) && GL_SUPPORT(ARB_FRAGMENT_PROGRAM)) {
3029         return &arbfp_fragment_pipeline;
3030     } else if(ps_selected_mode == SHADER_ATI) {
3031         return &atifs_fragment_pipeline;
3032     } else if(GL_SUPPORT(NV_REGISTER_COMBINERS) && GL_SUPPORT(NV_TEXTURE_SHADER2)) {
3033         return &nvts_fragment_pipeline;
3034     } else if(GL_SUPPORT(NV_REGISTER_COMBINERS)) {
3035         return &nvrc_fragment_pipeline;
3036     } else {
3037         return &ffp_fragment_pipeline;
3038     }
3039 }
3040
3041 static const struct blit_shader *select_blit_implementation(UINT Adapter, WINED3DDEVTYPE DeviceType) {
3042     int vs_selected_mode;
3043     int ps_selected_mode;
3044
3045     select_shader_mode(&GLINFO_LOCATION, DeviceType, &ps_selected_mode, &vs_selected_mode);
3046     if((ps_selected_mode == SHADER_ARB || ps_selected_mode == SHADER_GLSL) && GL_SUPPORT(ARB_FRAGMENT_PROGRAM)) {
3047         return &arbfp_blit;
3048     } else {
3049         return &ffp_blit;
3050     }
3051 }
3052
3053 /* Note: d3d8 passes in a pointer to a D3DCAPS8 structure, which is a true
3054       subset of a D3DCAPS9 structure. However, it has to come via a void *
3055       as the d3d8 interface cannot import the d3d9 header                  */
3056 static HRESULT WINAPI IWineD3DImpl_GetDeviceCaps(IWineD3D *iface, UINT Adapter, WINED3DDEVTYPE DeviceType, WINED3DCAPS* pCaps) {
3057
3058     IWineD3DImpl    *This = (IWineD3DImpl *)iface;
3059     int vs_selected_mode;
3060     int ps_selected_mode;
3061     struct shader_caps shader_caps;
3062     struct fragment_caps fragment_caps;
3063     const shader_backend_t *shader_backend;
3064     const struct fragment_pipeline *frag_pipeline = NULL;
3065     DWORD ckey_caps, blit_caps, fx_caps;
3066
3067     TRACE_(d3d_caps)("(%p)->(Adptr:%d, DevType: %x, pCaps: %p)\n", This, Adapter, DeviceType, pCaps);
3068
3069     if (Adapter >= IWineD3D_GetAdapterCount(iface)) {
3070         return WINED3DERR_INVALIDCALL;
3071     }
3072
3073     select_shader_mode(&Adapters[Adapter].gl_info, DeviceType, &ps_selected_mode, &vs_selected_mode);
3074
3075     /* This function should *not* be modifying GL caps
3076      * TODO: move the functionality where it belongs */
3077     select_shader_max_constants(ps_selected_mode, vs_selected_mode, &Adapters[Adapter].gl_info);
3078
3079     /* ------------------------------------------------
3080        The following fields apply to both d3d8 and d3d9
3081        ------------------------------------------------ */
3082     pCaps->DeviceType              = (DeviceType == WINED3DDEVTYPE_HAL) ? WINED3DDEVTYPE_HAL : WINED3DDEVTYPE_REF;  /* Not quite true, but use h/w supported by opengl I suppose */
3083     pCaps->AdapterOrdinal          = Adapter;
3084
3085     pCaps->Caps                    = 0;
3086     pCaps->Caps2                   = WINED3DCAPS2_CANRENDERWINDOWED |
3087                                      WINED3DCAPS2_FULLSCREENGAMMA |
3088                                      WINED3DCAPS2_DYNAMICTEXTURES;
3089     if(GL_SUPPORT(SGIS_GENERATE_MIPMAP)) {
3090         pCaps->Caps2 |= WINED3DCAPS2_CANAUTOGENMIPMAP;
3091     }
3092
3093     pCaps->Caps3                   = WINED3DCAPS3_ALPHA_FULLSCREEN_FLIP_OR_DISCARD |
3094                                      WINED3DCAPS3_COPY_TO_VIDMEM                   |
3095                                      WINED3DCAPS3_COPY_TO_SYSTEMMEM;
3096
3097     pCaps->PresentationIntervals   = WINED3DPRESENT_INTERVAL_IMMEDIATE  |
3098                                      WINED3DPRESENT_INTERVAL_ONE;
3099
3100     pCaps->CursorCaps              = WINED3DCURSORCAPS_COLOR            |
3101                                      WINED3DCURSORCAPS_LOWRES;
3102
3103     pCaps->DevCaps                 = WINED3DDEVCAPS_FLOATTLVERTEX       |
3104                                      WINED3DDEVCAPS_EXECUTESYSTEMMEMORY |
3105                                      WINED3DDEVCAPS_TLVERTEXSYSTEMMEMORY|
3106                                      WINED3DDEVCAPS_TLVERTEXVIDEOMEMORY |
3107                                      WINED3DDEVCAPS_DRAWPRIMTLVERTEX    |
3108                                      WINED3DDEVCAPS_HWTRANSFORMANDLIGHT |
3109                                      WINED3DDEVCAPS_EXECUTEVIDEOMEMORY  |
3110                                      WINED3DDEVCAPS_PUREDEVICE          |
3111                                      WINED3DDEVCAPS_HWRASTERIZATION     |
3112                                      WINED3DDEVCAPS_TEXTUREVIDEOMEMORY  |
3113                                      WINED3DDEVCAPS_TEXTURESYSTEMMEMORY |
3114                                      WINED3DDEVCAPS_CANRENDERAFTERFLIP  |
3115                                      WINED3DDEVCAPS_DRAWPRIMITIVES2     |
3116                                      WINED3DDEVCAPS_DRAWPRIMITIVES2EX   |
3117                                      WINED3DDEVCAPS_RTPATCHES;
3118
3119     pCaps->PrimitiveMiscCaps       = WINED3DPMISCCAPS_CULLNONE              |
3120                                      WINED3DPMISCCAPS_CULLCCW               |
3121                                      WINED3DPMISCCAPS_CULLCW                |
3122                                      WINED3DPMISCCAPS_COLORWRITEENABLE      |
3123                                      WINED3DPMISCCAPS_CLIPTLVERTS           |
3124                                      WINED3DPMISCCAPS_CLIPPLANESCALEDPOINTS |
3125                                      WINED3DPMISCCAPS_MASKZ                 |
3126                                      WINED3DPMISCCAPS_BLENDOP               |
3127                                      WINED3DPMISCCAPS_MRTPOSTPIXELSHADERBLENDING;
3128                                     /* TODO:
3129                                         WINED3DPMISCCAPS_NULLREFERENCE
3130                                         WINED3DPMISCCAPS_INDEPENDENTWRITEMASKS
3131                                         WINED3DPMISCCAPS_FOGANDSPECULARALPHA
3132                                         WINED3DPMISCCAPS_MRTINDEPENDENTBITDEPTHS
3133                                         WINED3DPMISCCAPS_FOGVERTEXCLAMPED */
3134
3135     if(GL_SUPPORT(EXT_BLEND_EQUATION_SEPARATE) && GL_SUPPORT(EXT_BLEND_FUNC_SEPARATE))
3136         pCaps->PrimitiveMiscCaps |= WINED3DPMISCCAPS_SEPARATEALPHABLEND;
3137
3138     pCaps->RasterCaps              = WINED3DPRASTERCAPS_DITHER    |
3139                                      WINED3DPRASTERCAPS_PAT       |
3140                                      WINED3DPRASTERCAPS_WFOG      |
3141                                      WINED3DPRASTERCAPS_ZFOG      |
3142                                      WINED3DPRASTERCAPS_FOGVERTEX |
3143                                      WINED3DPRASTERCAPS_FOGTABLE  |
3144                                      WINED3DPRASTERCAPS_STIPPLE   |
3145                                      WINED3DPRASTERCAPS_SUBPIXEL  |
3146                                      WINED3DPRASTERCAPS_ZTEST     |
3147                                      WINED3DPRASTERCAPS_SCISSORTEST   |
3148                                      WINED3DPRASTERCAPS_SLOPESCALEDEPTHBIAS |
3149                                      WINED3DPRASTERCAPS_DEPTHBIAS;
3150
3151     if (GL_SUPPORT(EXT_TEXTURE_FILTER_ANISOTROPIC)) {
3152         pCaps->RasterCaps |= WINED3DPRASTERCAPS_ANISOTROPY    |
3153                              WINED3DPRASTERCAPS_ZBIAS         |
3154                              WINED3DPRASTERCAPS_MIPMAPLODBIAS;
3155     }
3156     if(GL_SUPPORT(NV_FOG_DISTANCE)) {
3157         pCaps->RasterCaps         |= WINED3DPRASTERCAPS_FOGRANGE;
3158     }
3159                         /* FIXME Add:
3160                            WINED3DPRASTERCAPS_COLORPERSPECTIVE
3161                            WINED3DPRASTERCAPS_STRETCHBLTMULTISAMPLE
3162                            WINED3DPRASTERCAPS_ANTIALIASEDGES
3163                            WINED3DPRASTERCAPS_ZBUFFERLESSHSR
3164                            WINED3DPRASTERCAPS_WBUFFER */
3165
3166     pCaps->ZCmpCaps = WINED3DPCMPCAPS_ALWAYS       |
3167                       WINED3DPCMPCAPS_EQUAL        |
3168                       WINED3DPCMPCAPS_GREATER      |
3169                       WINED3DPCMPCAPS_GREATEREQUAL |
3170                       WINED3DPCMPCAPS_LESS         |
3171                       WINED3DPCMPCAPS_LESSEQUAL    |
3172                       WINED3DPCMPCAPS_NEVER        |
3173                       WINED3DPCMPCAPS_NOTEQUAL;
3174
3175     pCaps->SrcBlendCaps  = WINED3DPBLENDCAPS_BOTHINVSRCALPHA |
3176                            WINED3DPBLENDCAPS_BOTHSRCALPHA    |
3177                            WINED3DPBLENDCAPS_DESTALPHA       |
3178                            WINED3DPBLENDCAPS_DESTCOLOR       |
3179                            WINED3DPBLENDCAPS_INVDESTALPHA    |
3180                            WINED3DPBLENDCAPS_INVDESTCOLOR    |
3181                            WINED3DPBLENDCAPS_INVSRCALPHA     |
3182                            WINED3DPBLENDCAPS_INVSRCCOLOR     |
3183                            WINED3DPBLENDCAPS_ONE             |
3184                            WINED3DPBLENDCAPS_SRCALPHA        |
3185                            WINED3DPBLENDCAPS_SRCALPHASAT     |
3186                            WINED3DPBLENDCAPS_SRCCOLOR        |
3187                            WINED3DPBLENDCAPS_ZERO;
3188
3189     pCaps->DestBlendCaps = WINED3DPBLENDCAPS_DESTALPHA       |
3190                            WINED3DPBLENDCAPS_DESTCOLOR       |
3191                            WINED3DPBLENDCAPS_INVDESTALPHA    |
3192                            WINED3DPBLENDCAPS_INVDESTCOLOR    |
3193                            WINED3DPBLENDCAPS_INVSRCALPHA     |
3194                            WINED3DPBLENDCAPS_INVSRCCOLOR     |
3195                            WINED3DPBLENDCAPS_ONE             |
3196                            WINED3DPBLENDCAPS_SRCALPHA        |
3197                            WINED3DPBLENDCAPS_SRCCOLOR        |
3198                            WINED3DPBLENDCAPS_ZERO;
3199     /* NOTE: WINED3DPBLENDCAPS_SRCALPHASAT is not supported as dest blend factor,
3200      * according to the glBlendFunc manpage
3201      *
3202      * WINED3DPBLENDCAPS_BOTHINVSRCALPHA and WINED3DPBLENDCAPS_BOTHSRCALPHA are
3203      * legacy settings for srcblend only
3204      */
3205
3206     if( GL_SUPPORT(EXT_BLEND_COLOR)) {
3207         pCaps->SrcBlendCaps |= WINED3DPBLENDCAPS_BLENDFACTOR;
3208         pCaps->DestBlendCaps |= WINED3DPBLENDCAPS_BLENDFACTOR;
3209     }
3210
3211
3212     pCaps->AlphaCmpCaps = WINED3DPCMPCAPS_ALWAYS       |
3213                           WINED3DPCMPCAPS_EQUAL        |
3214                           WINED3DPCMPCAPS_GREATER      |
3215                           WINED3DPCMPCAPS_GREATEREQUAL |
3216                           WINED3DPCMPCAPS_LESS         |
3217                           WINED3DPCMPCAPS_LESSEQUAL    |
3218                           WINED3DPCMPCAPS_NEVER        |
3219                           WINED3DPCMPCAPS_NOTEQUAL;
3220
3221     pCaps->ShadeCaps     = WINED3DPSHADECAPS_SPECULARGOURAUDRGB |
3222                            WINED3DPSHADECAPS_COLORGOURAUDRGB    |
3223                            WINED3DPSHADECAPS_ALPHAFLATBLEND     |
3224                            WINED3DPSHADECAPS_ALPHAGOURAUDBLEND  |
3225                            WINED3DPSHADECAPS_COLORFLATRGB       |
3226                            WINED3DPSHADECAPS_FOGFLAT            |
3227                            WINED3DPSHADECAPS_FOGGOURAUD         |
3228                            WINED3DPSHADECAPS_SPECULARFLATRGB;
3229
3230     pCaps->TextureCaps =  WINED3DPTEXTURECAPS_ALPHA              |
3231                           WINED3DPTEXTURECAPS_ALPHAPALETTE       |
3232                           WINED3DPTEXTURECAPS_TRANSPARENCY       |
3233                           WINED3DPTEXTURECAPS_BORDER             |
3234                           WINED3DPTEXTURECAPS_MIPMAP             |
3235                           WINED3DPTEXTURECAPS_PROJECTED          |
3236                           WINED3DPTEXTURECAPS_PERSPECTIVE;
3237
3238     if( !GL_SUPPORT(ARB_TEXTURE_NON_POWER_OF_TWO)) {
3239         pCaps->TextureCaps |= WINED3DPTEXTURECAPS_POW2 |
3240                               WINED3DPTEXTURECAPS_NONPOW2CONDITIONAL;
3241     }
3242
3243     if( GL_SUPPORT(EXT_TEXTURE3D)) {
3244         pCaps->TextureCaps |=  WINED3DPTEXTURECAPS_VOLUMEMAP      |
3245                                WINED3DPTEXTURECAPS_MIPVOLUMEMAP   |
3246                                WINED3DPTEXTURECAPS_VOLUMEMAP_POW2;
3247     }
3248
3249     if (GL_SUPPORT(ARB_TEXTURE_CUBE_MAP)) {
3250         pCaps->TextureCaps |= WINED3DPTEXTURECAPS_CUBEMAP     |
3251                               WINED3DPTEXTURECAPS_MIPCUBEMAP    |
3252                               WINED3DPTEXTURECAPS_CUBEMAP_POW2;
3253
3254     }
3255
3256     pCaps->TextureFilterCaps = WINED3DPTFILTERCAPS_MAGFLINEAR       |
3257                                WINED3DPTFILTERCAPS_MAGFPOINT        |
3258                                WINED3DPTFILTERCAPS_MINFLINEAR       |
3259                                WINED3DPTFILTERCAPS_MINFPOINT        |
3260                                WINED3DPTFILTERCAPS_MIPFLINEAR       |
3261                                WINED3DPTFILTERCAPS_MIPFPOINT        |
3262                                WINED3DPTFILTERCAPS_LINEAR           |
3263                                WINED3DPTFILTERCAPS_LINEARMIPLINEAR  |
3264                                WINED3DPTFILTERCAPS_LINEARMIPNEAREST |
3265                                WINED3DPTFILTERCAPS_MIPLINEAR        |
3266                                WINED3DPTFILTERCAPS_MIPNEAREST       |
3267                                WINED3DPTFILTERCAPS_NEAREST;
3268
3269     if (GL_SUPPORT(EXT_TEXTURE_FILTER_ANISOTROPIC)) {
3270         pCaps->TextureFilterCaps |= WINED3DPTFILTERCAPS_MAGFANISOTROPIC |
3271                                     WINED3DPTFILTERCAPS_MINFANISOTROPIC;
3272     }
3273
3274     if (GL_SUPPORT(ARB_TEXTURE_CUBE_MAP)) {
3275         pCaps->CubeTextureFilterCaps = WINED3DPTFILTERCAPS_MAGFLINEAR       |
3276                                        WINED3DPTFILTERCAPS_MAGFPOINT        |
3277                                        WINED3DPTFILTERCAPS_MINFLINEAR       |
3278                                        WINED3DPTFILTERCAPS_MINFPOINT        |
3279                                        WINED3DPTFILTERCAPS_MIPFLINEAR       |
3280                                        WINED3DPTFILTERCAPS_MIPFPOINT        |
3281                                        WINED3DPTFILTERCAPS_LINEAR           |
3282                                        WINED3DPTFILTERCAPS_LINEARMIPLINEAR  |
3283                                        WINED3DPTFILTERCAPS_LINEARMIPNEAREST |
3284                                        WINED3DPTFILTERCAPS_MIPLINEAR        |
3285                                        WINED3DPTFILTERCAPS_MIPNEAREST       |
3286                                        WINED3DPTFILTERCAPS_NEAREST;
3287
3288         if (GL_SUPPORT(EXT_TEXTURE_FILTER_ANISOTROPIC)) {
3289             pCaps->CubeTextureFilterCaps |= WINED3DPTFILTERCAPS_MAGFANISOTROPIC |
3290                                             WINED3DPTFILTERCAPS_MINFANISOTROPIC;
3291         }
3292     } else
3293         pCaps->CubeTextureFilterCaps = 0;
3294
3295     if (GL_SUPPORT(EXT_TEXTURE3D)) {
3296         pCaps->VolumeTextureFilterCaps = WINED3DPTFILTERCAPS_MAGFLINEAR       |
3297                                          WINED3DPTFILTERCAPS_MAGFPOINT        |
3298                                          WINED3DPTFILTERCAPS_MINFLINEAR       |
3299                                          WINED3DPTFILTERCAPS_MINFPOINT        |
3300                                          WINED3DPTFILTERCAPS_MIPFLINEAR       |
3301                                          WINED3DPTFILTERCAPS_MIPFPOINT        |
3302                                          WINED3DPTFILTERCAPS_LINEAR           |
3303                                          WINED3DPTFILTERCAPS_LINEARMIPLINEAR  |
3304                                          WINED3DPTFILTERCAPS_LINEARMIPNEAREST |
3305                                          WINED3DPTFILTERCAPS_MIPLINEAR        |
3306                                          WINED3DPTFILTERCAPS_MIPNEAREST       |
3307                                          WINED3DPTFILTERCAPS_NEAREST;
3308     } else
3309         pCaps->VolumeTextureFilterCaps = 0;
3310
3311     pCaps->TextureAddressCaps =  WINED3DPTADDRESSCAPS_INDEPENDENTUV |
3312                                  WINED3DPTADDRESSCAPS_CLAMP  |
3313                                  WINED3DPTADDRESSCAPS_WRAP;
3314
3315     if (GL_SUPPORT(ARB_TEXTURE_BORDER_CLAMP)) {
3316         pCaps->TextureAddressCaps |= WINED3DPTADDRESSCAPS_BORDER;
3317     }
3318     if (GL_SUPPORT(ARB_TEXTURE_MIRRORED_REPEAT)) {
3319         pCaps->TextureAddressCaps |= WINED3DPTADDRESSCAPS_MIRROR;
3320     }
3321     if (GL_SUPPORT(ATI_TEXTURE_MIRROR_ONCE)) {
3322         pCaps->TextureAddressCaps |= WINED3DPTADDRESSCAPS_MIRRORONCE;
3323     }
3324
3325     if (GL_SUPPORT(EXT_TEXTURE3D)) {
3326         pCaps->VolumeTextureAddressCaps =  WINED3DPTADDRESSCAPS_INDEPENDENTUV |
3327                                            WINED3DPTADDRESSCAPS_CLAMP  |
3328                                            WINED3DPTADDRESSCAPS_WRAP;
3329         if (GL_SUPPORT(ARB_TEXTURE_BORDER_CLAMP)) {
3330             pCaps->VolumeTextureAddressCaps |= WINED3DPTADDRESSCAPS_BORDER;
3331         }
3332         if (GL_SUPPORT(ARB_TEXTURE_MIRRORED_REPEAT)) {
3333             pCaps->VolumeTextureAddressCaps |= WINED3DPTADDRESSCAPS_MIRROR;
3334         }
3335         if (GL_SUPPORT(ATI_TEXTURE_MIRROR_ONCE)) {
3336             pCaps->VolumeTextureAddressCaps |= WINED3DPTADDRESSCAPS_MIRRORONCE;
3337         }
3338     } else
3339         pCaps->VolumeTextureAddressCaps = 0;
3340
3341     pCaps->LineCaps = WINED3DLINECAPS_TEXTURE       |
3342                       WINED3DLINECAPS_ZTEST         |
3343                       WINED3DLINECAPS_BLEND         |
3344                       WINED3DLINECAPS_ALPHACMP      |
3345                       WINED3DLINECAPS_FOG;
3346     /* WINED3DLINECAPS_ANTIALIAS is not supported on Windows, and dx and gl seem to have a different
3347      * idea how generating the smoothing alpha values works; the result is different
3348      */
3349
3350     pCaps->MaxTextureWidth  = GL_LIMITS(texture_size);
3351     pCaps->MaxTextureHeight = GL_LIMITS(texture_size);
3352
3353     if(GL_SUPPORT(EXT_TEXTURE3D))
3354         pCaps->MaxVolumeExtent = GL_LIMITS(texture3d_size);
3355     else
3356         pCaps->MaxVolumeExtent = 0;
3357
3358     pCaps->MaxTextureRepeat = 32768;
3359     pCaps->MaxTextureAspectRatio = GL_LIMITS(texture_size);
3360     pCaps->MaxVertexW = 1.0;
3361
3362     pCaps->GuardBandLeft = 0;
3363     pCaps->GuardBandTop = 0;
3364     pCaps->GuardBandRight = 0;
3365     pCaps->GuardBandBottom = 0;
3366
3367     pCaps->ExtentsAdjust = 0;
3368
3369     pCaps->StencilCaps =  WINED3DSTENCILCAPS_DECRSAT |
3370                           WINED3DSTENCILCAPS_INCRSAT |
3371                           WINED3DSTENCILCAPS_INVERT  |
3372                           WINED3DSTENCILCAPS_KEEP    |
3373                           WINED3DSTENCILCAPS_REPLACE |
3374                           WINED3DSTENCILCAPS_ZERO;
3375     if (GL_SUPPORT(EXT_STENCIL_WRAP)) {
3376         pCaps->StencilCaps |= WINED3DSTENCILCAPS_DECR  |
3377                               WINED3DSTENCILCAPS_INCR;
3378     }
3379     if ( This->dxVersion > 8 &&
3380         ( GL_SUPPORT(EXT_STENCIL_TWO_SIDE) ||
3381             GL_SUPPORT(ATI_SEPARATE_STENCIL) ) ) {
3382         pCaps->StencilCaps |= WINED3DSTENCILCAPS_TWOSIDED;
3383     }
3384
3385     pCaps->FVFCaps = WINED3DFVFCAPS_PSIZE | 0x0008; /* 8 texture coords */
3386
3387     pCaps->MaxUserClipPlanes       = GL_LIMITS(clipplanes);
3388     pCaps->MaxActiveLights         = GL_LIMITS(lights);
3389
3390     pCaps->MaxVertexBlendMatrices      = GL_LIMITS(blends);
3391     pCaps->MaxVertexBlendMatrixIndex   = 0;
3392
3393     pCaps->MaxAnisotropy   = GL_LIMITS(anisotropy);
3394     pCaps->MaxPointSize    = GL_LIMITS(pointsize);
3395
3396
3397     pCaps->VertexProcessingCaps = WINED3DVTXPCAPS_DIRECTIONALLIGHTS |
3398                                   WINED3DVTXPCAPS_MATERIALSOURCE7   |
3399                                   WINED3DVTXPCAPS_POSITIONALLIGHTS  |
3400                                   WINED3DVTXPCAPS_LOCALVIEWER       |
3401                                   WINED3DVTXPCAPS_VERTEXFOG         |
3402                                   WINED3DVTXPCAPS_TEXGEN;
3403                                   /* FIXME: Add 
3404                                      D3DVTXPCAPS_TWEENING, D3DVTXPCAPS_TEXGEN_SPHEREMAP */
3405
3406     pCaps->MaxPrimitiveCount   = 0xFFFFF; /* For now set 2^20-1 which is used by most >=Geforce3/Radeon8500 cards */
3407     pCaps->MaxVertexIndex      = 0xFFFFF;
3408     pCaps->MaxStreams          = MAX_STREAMS;
3409     pCaps->MaxStreamStride     = 1024;
3410
3411     /* d3d9.dll sets D3DDEVCAPS2_CAN_STRETCHRECT_FROM_TEXTURES here because StretchRects is implemented in d3d9 */
3412     pCaps->DevCaps2                          = WINED3DDEVCAPS2_STREAMOFFSET |
3413                                                WINED3DDEVCAPS2_VERTEXELEMENTSCANSHARESTREAMOFFSET;
3414     pCaps->MaxNpatchTessellationLevel        = 0;
3415     pCaps->MasterAdapterOrdinal              = 0;
3416     pCaps->AdapterOrdinalInGroup             = 0;
3417     pCaps->NumberOfAdaptersInGroup           = 1;
3418
3419     pCaps->NumSimultaneousRTs = GL_LIMITS(buffers);
3420
3421     pCaps->StretchRectFilterCaps             = WINED3DPTFILTERCAPS_MINFPOINT  |
3422                                                 WINED3DPTFILTERCAPS_MAGFPOINT  |
3423                                                 WINED3DPTFILTERCAPS_MINFLINEAR |
3424                                                 WINED3DPTFILTERCAPS_MAGFLINEAR;
3425     pCaps->VertexTextureFilterCaps           = 0;
3426
3427     memset(&shader_caps, 0, sizeof(shader_caps));
3428     shader_backend = select_shader_backend(Adapter, DeviceType);
3429     shader_backend->shader_get_caps(DeviceType, &GLINFO_LOCATION, &shader_caps);
3430
3431     memset(&fragment_caps, 0, sizeof(fragment_caps));
3432     frag_pipeline = select_fragment_implementation(Adapter, DeviceType);
3433     frag_pipeline->get_caps(DeviceType, &GLINFO_LOCATION, &fragment_caps);
3434
3435     /* Add shader misc caps. Only some of them belong to the shader parts of the pipeline */
3436     pCaps->PrimitiveMiscCaps |= fragment_caps.PrimitiveMiscCaps;
3437
3438     /* This takes care for disabling vertex shader or pixel shader caps while leaving the other one enabled.
3439      * Ignore shader model capabilities if disabled in config
3440      */
3441     if(vs_selected_mode == SHADER_NONE) {
3442         TRACE_(d3d_caps)("Vertex shader disabled in config, reporting version 0.0\n");
3443         pCaps->VertexShaderVersion          = WINED3DVS_VERSION(0,0);
3444         pCaps->MaxVertexShaderConst         = 0;
3445     } else {
3446         pCaps->VertexShaderVersion          = shader_caps.VertexShaderVersion;
3447         pCaps->MaxVertexShaderConst         = shader_caps.MaxVertexShaderConst;
3448     }
3449
3450     if(ps_selected_mode == SHADER_NONE) {
3451         TRACE_(d3d_caps)("Pixel shader disabled in config, reporting version 0.0\n");
3452         pCaps->PixelShaderVersion           = WINED3DPS_VERSION(0,0);
3453         pCaps->PixelShader1xMaxValue        = 0.0;
3454     } else {
3455         pCaps->PixelShaderVersion           = shader_caps.PixelShaderVersion;
3456         pCaps->PixelShader1xMaxValue        = shader_caps.PixelShader1xMaxValue;
3457     }
3458
3459     pCaps->TextureOpCaps                    = fragment_caps.TextureOpCaps;
3460     pCaps->MaxTextureBlendStages            = fragment_caps.MaxTextureBlendStages;
3461     pCaps->MaxSimultaneousTextures          = fragment_caps.MaxSimultaneousTextures;
3462
3463     pCaps->VS20Caps                         = shader_caps.VS20Caps;
3464     pCaps->MaxVShaderInstructionsExecuted   = shader_caps.MaxVShaderInstructionsExecuted;
3465     pCaps->MaxVertexShader30InstructionSlots= shader_caps.MaxVertexShader30InstructionSlots;
3466     pCaps->PS20Caps                         = shader_caps.PS20Caps;
3467     pCaps->MaxPShaderInstructionsExecuted   = shader_caps.MaxPShaderInstructionsExecuted;
3468     pCaps->MaxPixelShader30InstructionSlots = shader_caps.MaxPixelShader30InstructionSlots;
3469
3470     /* The following caps are shader specific, but they are things we cannot detect, or which
3471      * are the same among all shader models. So to avoid code duplication set the shader version
3472      * specific, but otherwise constant caps here
3473      */
3474     if(pCaps->VertexShaderVersion == WINED3DVS_VERSION(3,0)) {
3475         /* Where possible set the caps based on OpenGL extensions and if they aren't set (in case of software rendering)
3476         use the VS 3.0 from MSDN or else if there's OpenGL spec use a hardcoded value minimum VS3.0 value. */
3477         pCaps->VS20Caps.Caps                     = WINED3DVS20CAPS_PREDICATION;
3478         pCaps->VS20Caps.DynamicFlowControlDepth  = WINED3DVS20_MAX_DYNAMICFLOWCONTROLDEPTH; /* VS 3.0 requires MAX_DYNAMICFLOWCONTROLDEPTH (24) */
3479         pCaps->VS20Caps.NumTemps                 = max(32, GLINFO_LOCATION.vs_arb_max_temps);
3480         pCaps->VS20Caps.StaticFlowControlDepth   = WINED3DVS20_MAX_STATICFLOWCONTROLDEPTH ; /* level of nesting in loops / if-statements; VS 3.0 requires MAX (4) */
3481
3482         pCaps->MaxVShaderInstructionsExecuted    = 65535; /* VS 3.0 needs at least 65535, some cards even use 2^32-1 */
3483         pCaps->MaxVertexShader30InstructionSlots = max(512, GLINFO_LOCATION.vs_arb_max_instructions);
3484     } else if(pCaps->VertexShaderVersion == WINED3DVS_VERSION(2,0)) {
3485         pCaps->VS20Caps.Caps                     = 0;
3486         pCaps->VS20Caps.DynamicFlowControlDepth  = WINED3DVS20_MIN_DYNAMICFLOWCONTROLDEPTH;
3487         pCaps->VS20Caps.NumTemps                 = max(12, GLINFO_LOCATION.vs_arb_max_temps);
3488         pCaps->VS20Caps.StaticFlowControlDepth   = 1;
3489
3490         pCaps->MaxVShaderInstructionsExecuted    = 65535;
3491         pCaps->MaxVertexShader30InstructionSlots = 0;
3492     } else { /* VS 1.x */
3493         pCaps->VS20Caps.Caps                     = 0;
3494         pCaps->VS20Caps.DynamicFlowControlDepth  = 0;
3495         pCaps->VS20Caps.NumTemps                 = 0;
3496         pCaps->VS20Caps.StaticFlowControlDepth   = 0;
3497
3498         pCaps->MaxVShaderInstructionsExecuted    = 0;
3499         pCaps->MaxVertexShader30InstructionSlots = 0;
3500     }
3501
3502     if(pCaps->PixelShaderVersion == WINED3DPS_VERSION(3,0)) {
3503         /* Where possible set the caps based on OpenGL extensions and if they aren't set (in case of software rendering)
3504         use the PS 3.0 from MSDN or else if there's OpenGL spec use a hardcoded value minimum PS 3.0 value. */
3505
3506         /* 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 */
3507         pCaps->PS20Caps.Caps                     = WINED3DPS20CAPS_ARBITRARYSWIZZLE     |
3508                 WINED3DPS20CAPS_GRADIENTINSTRUCTIONS |
3509                 WINED3DPS20CAPS_PREDICATION          |
3510                 WINED3DPS20CAPS_NODEPENDENTREADLIMIT |
3511                 WINED3DPS20CAPS_NOTEXINSTRUCTIONLIMIT;
3512         pCaps->PS20Caps.DynamicFlowControlDepth  = WINED3DPS20_MAX_DYNAMICFLOWCONTROLDEPTH; /* PS 3.0 requires MAX_DYNAMICFLOWCONTROLDEPTH (24) */
3513         pCaps->PS20Caps.NumTemps                 = max(32, GLINFO_LOCATION.ps_arb_max_temps);
3514         pCaps->PS20Caps.StaticFlowControlDepth   = WINED3DPS20_MAX_STATICFLOWCONTROLDEPTH; /* PS 3.0 requires MAX_STATICFLOWCONTROLDEPTH (4) */
3515         pCaps->PS20Caps.NumInstructionSlots      = WINED3DPS20_MAX_NUMINSTRUCTIONSLOTS; /* PS 3.0 requires MAX_NUMINSTRUCTIONSLOTS (512) */
3516
3517         pCaps->MaxPShaderInstructionsExecuted    = 65535;
3518         pCaps->MaxPixelShader30InstructionSlots  = max(WINED3DMIN30SHADERINSTRUCTIONS, GLINFO_LOCATION.ps_arb_max_instructions);
3519     } else if(pCaps->PixelShaderVersion == WINED3DPS_VERSION(2,0)) {
3520         /* Below we assume PS2.0 specs, not extended 2.0a(GeforceFX)/2.0b(Radeon R3xx) ones */
3521         pCaps->PS20Caps.Caps                     = 0;
3522         pCaps->PS20Caps.DynamicFlowControlDepth  = 0; /* WINED3DVS20_MIN_DYNAMICFLOWCONTROLDEPTH = 0 */
3523         pCaps->PS20Caps.NumTemps                 = max(12, GLINFO_LOCATION.ps_arb_max_temps);
3524         pCaps->PS20Caps.StaticFlowControlDepth   = WINED3DPS20_MIN_STATICFLOWCONTROLDEPTH; /* Minimum: 1 */
3525         pCaps->PS20Caps.NumInstructionSlots      = WINED3DPS20_MIN_NUMINSTRUCTIONSLOTS; /* Minimum number (64 ALU + 32 Texture), a GeforceFX uses 512 */
3526
3527         pCaps->MaxPShaderInstructionsExecuted    = 512; /* Minimum value, a GeforceFX uses 1024 */
3528         pCaps->MaxPixelShader30InstructionSlots  = 0;
3529     } else { /* PS 1.x */
3530         pCaps->PS20Caps.Caps                     = 0;
3531         pCaps->PS20Caps.DynamicFlowControlDepth  = 0;
3532         pCaps->PS20Caps.NumTemps                 = 0;
3533         pCaps->PS20Caps.StaticFlowControlDepth   = 0;
3534         pCaps->PS20Caps.NumInstructionSlots      = 0;
3535
3536         pCaps->MaxPShaderInstructionsExecuted    = 0;
3537         pCaps->MaxPixelShader30InstructionSlots  = 0;
3538     }
3539
3540     if(pCaps->VertexShaderVersion >= WINED3DVS_VERSION(2,0)) {
3541         /* OpenGL supports all the formats below, perhaps not always
3542          * without conversion, but it supports them.
3543          * Further GLSL doesn't seem to have an official unsigned type so
3544          * don't advertise it yet as I'm not sure how we handle it.
3545          * We might need to add some clamping in the shader engine to
3546          * support it.
3547          * TODO: WINED3DDTCAPS_USHORT2N, WINED3DDTCAPS_USHORT4N, WINED3DDTCAPS_UDEC3, WINED3DDTCAPS_DEC3N */
3548         pCaps->DeclTypes = WINED3DDTCAPS_UBYTE4    |
3549                            WINED3DDTCAPS_UBYTE4N   |
3550                            WINED3DDTCAPS_SHORT2N   |
3551                            WINED3DDTCAPS_SHORT4N;
3552         if (GL_SUPPORT(NV_HALF_FLOAT)) {
3553             pCaps->DeclTypes |= WINED3DDTCAPS_FLOAT16_2 |
3554                                 WINED3DDTCAPS_FLOAT16_4;
3555         }
3556     } else
3557         pCaps->DeclTypes                         = 0;
3558
3559     /* Set DirectDraw helper Caps */
3560     ckey_caps =                         WINEDDCKEYCAPS_DESTBLT              |
3561                                         WINEDDCKEYCAPS_SRCBLT;
3562     fx_caps =                           WINEDDFXCAPS_BLTALPHA               |
3563                                         WINEDDFXCAPS_BLTMIRRORLEFTRIGHT     |
3564                                         WINEDDFXCAPS_BLTMIRRORUPDOWN        |
3565                                         WINEDDFXCAPS_BLTROTATION90          |
3566                                         WINEDDFXCAPS_BLTSHRINKX             |
3567                                         WINEDDFXCAPS_BLTSHRINKXN            |
3568                                         WINEDDFXCAPS_BLTSHRINKY             |
3569                                         WINEDDFXCAPS_BLTSHRINKXN            |
3570                                         WINEDDFXCAPS_BLTSTRETCHX            |
3571                                         WINEDDFXCAPS_BLTSTRETCHXN           |
3572                                         WINEDDFXCAPS_BLTSTRETCHY            |
3573                                         WINEDDFXCAPS_BLTSTRETCHYN;
3574     blit_caps =                         WINEDDCAPS_BLT                      |
3575                                         WINEDDCAPS_BLTCOLORFILL             |
3576                                         WINEDDCAPS_BLTDEPTHFILL             |
3577                                         WINEDDCAPS_BLTSTRETCH               |
3578                                         WINEDDCAPS_CANBLTSYSMEM             |
3579                                         WINEDDCAPS_CANCLIP                  |
3580                                         WINEDDCAPS_CANCLIPSTRETCHED         |
3581                                         WINEDDCAPS_COLORKEY                 |
3582                                         WINEDDCAPS_COLORKEYHWASSIST         |
3583                                         WINEDDCAPS_ALIGNBOUNDARYSRC;
3584
3585     /* Fill the ddraw caps structure */
3586     pCaps->DirectDrawCaps.Caps =        WINEDDCAPS_GDI                      |
3587                                         WINEDDCAPS_PALETTE                  |
3588                                         blit_caps;
3589     pCaps->DirectDrawCaps.Caps2 =       WINEDDCAPS2_CERTIFIED                |
3590                                         WINEDDCAPS2_NOPAGELOCKREQUIRED       |
3591                                         WINEDDCAPS2_PRIMARYGAMMA             |
3592                                         WINEDDCAPS2_WIDESURFACES             |
3593                                         WINEDDCAPS2_CANRENDERWINDOWED;
3594     pCaps->DirectDrawCaps.SVBCaps =     blit_caps;
3595     pCaps->DirectDrawCaps.SVBCKeyCaps = ckey_caps;
3596     pCaps->DirectDrawCaps.SVBFXCaps =   fx_caps;
3597     pCaps->DirectDrawCaps.VSBCaps =     blit_caps;
3598     pCaps->DirectDrawCaps.VSBCKeyCaps = ckey_caps;
3599     pCaps->DirectDrawCaps.VSBFXCaps =   fx_caps;
3600     pCaps->DirectDrawCaps.SSBCaps =     blit_caps;
3601     pCaps->DirectDrawCaps.SSBCKeyCaps = ckey_caps;
3602     pCaps->DirectDrawCaps.SSBFXCaps =   fx_caps;
3603
3604     pCaps->DirectDrawCaps.ddsCaps =     WINEDDSCAPS_ALPHA                   |
3605                                         WINEDDSCAPS_BACKBUFFER              |
3606                                         WINEDDSCAPS_FLIP                    |
3607                                         WINEDDSCAPS_FRONTBUFFER             |
3608                                         WINEDDSCAPS_OFFSCREENPLAIN          |
3609                                         WINEDDSCAPS_PALETTE                 |
3610                                         WINEDDSCAPS_PRIMARYSURFACE          |
3611                                         WINEDDSCAPS_SYSTEMMEMORY            |
3612                                         WINEDDSCAPS_VIDEOMEMORY             |
3613                                         WINEDDSCAPS_VISIBLE;
3614     pCaps->DirectDrawCaps.StrideAlign = DDRAW_PITCH_ALIGNMENT;
3615
3616     /* Set D3D caps if OpenGL is available. */
3617     if(Adapters[Adapter].opengl) {
3618         pCaps->DirectDrawCaps.ddsCaps |=WINEDDSCAPS_3DDEVICE                |
3619                                         WINEDDSCAPS_MIPMAP                  |
3620                                         WINEDDSCAPS_TEXTURE                 |
3621                                         WINEDDSCAPS_ZBUFFER;
3622         pCaps->DirectDrawCaps.Caps |=   WINEDDCAPS_3D;
3623     }
3624
3625     return WINED3D_OK;
3626 }
3627
3628 /* Note due to structure differences between dx8 and dx9 D3DPRESENT_PARAMETERS,
3629    and fields being inserted in the middle, a new structure is used in place    */
3630 static HRESULT WINAPI IWineD3DImpl_CreateDevice(IWineD3D *iface, UINT Adapter,
3631         WINED3DDEVTYPE DeviceType, HWND hFocusWindow, DWORD BehaviourFlags, IUnknown *parent,
3632         IWineD3DDeviceParent *device_parent, IWineD3DDevice **ppReturnedDeviceInterface)
3633 {
3634     IWineD3DDeviceImpl *object  = NULL;
3635     IWineD3DImpl       *This    = (IWineD3DImpl *)iface;
3636     WINED3DDISPLAYMODE  mode;
3637     const struct fragment_pipeline *frag_pipeline = NULL;
3638     int i;
3639     struct fragment_caps ffp_caps;
3640     HRESULT hr;
3641
3642     /* Validate the adapter number. If no adapters are available(no GL), ignore the adapter
3643      * number and create a device without a 3D adapter for 2D only operation.
3644      */
3645     if (IWineD3D_GetAdapterCount(iface) && Adapter >= IWineD3D_GetAdapterCount(iface)) {
3646         return WINED3DERR_INVALIDCALL;
3647     }
3648
3649     /* Create a WineD3DDevice object */
3650     object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IWineD3DDeviceImpl));
3651     *ppReturnedDeviceInterface = (IWineD3DDevice *)object;
3652     TRACE("Created WineD3DDevice object @ %p\n", object);
3653     if (NULL == object) {
3654       return WINED3DERR_OUTOFVIDEOMEMORY;
3655     }
3656
3657     /* Set up initial COM information */
3658     object->lpVtbl  = &IWineD3DDevice_Vtbl;
3659     object->ref     = 1;
3660     object->wineD3D = iface;
3661     object->adapter = numAdapters ? &Adapters[Adapter] : NULL;
3662     IWineD3D_AddRef(object->wineD3D);
3663     object->parent  = parent;
3664     object->device_parent = device_parent;
3665     list_init(&object->resources);
3666     list_init(&object->shaders);
3667
3668     if(This->dxVersion == 7) {
3669         object->surface_alignment = DDRAW_PITCH_ALIGNMENT;
3670     } else {
3671         object->surface_alignment = D3D8_PITCH_ALIGNMENT;
3672     }
3673     object->posFixup[0] = 1.0; /* This is needed to get the x coord unmodified through a MAD */
3674
3675     /* Set the state up as invalid until the device is fully created */
3676     object->state   = WINED3DERR_DRIVERINTERNALERROR;
3677
3678     TRACE("(%p)->(Adptr:%d, DevType: %x, FocusHwnd: %p, BehFlags: %x, RetDevInt: %p)\n", This, Adapter, DeviceType,
3679           hFocusWindow, BehaviourFlags, ppReturnedDeviceInterface);
3680
3681     /* Save the creation parameters */
3682     object->createParms.AdapterOrdinal = Adapter;
3683     object->createParms.DeviceType     = DeviceType;
3684     object->createParms.hFocusWindow   = hFocusWindow;
3685     object->createParms.BehaviorFlags  = BehaviourFlags;
3686
3687     /* Initialize other useful values */
3688     object->adapterNo                    = Adapter;
3689     object->devType                      = DeviceType;
3690
3691     select_shader_mode(&GLINFO_LOCATION, DeviceType, &object->ps_selected_mode, &object->vs_selected_mode);
3692     object->shader_backend = select_shader_backend(Adapter, DeviceType);
3693
3694     memset(&ffp_caps, 0, sizeof(ffp_caps));
3695     frag_pipeline = select_fragment_implementation(Adapter, DeviceType);
3696     object->frag_pipe = frag_pipeline;
3697     frag_pipeline->get_caps(DeviceType, &GLINFO_LOCATION, &ffp_caps);
3698     object->max_ffp_textures = ffp_caps.MaxSimultaneousTextures;
3699     object->max_ffp_texture_stages = ffp_caps.MaxTextureBlendStages;
3700     hr = compile_state_table(object->StateTable, object->multistate_funcs, &GLINFO_LOCATION,
3701                         ffp_vertexstate_template, frag_pipeline, misc_state_template);
3702
3703     if (FAILED(hr)) {
3704         IWineD3D_Release(object->wineD3D);
3705         HeapFree(GetProcessHeap(), 0, object);
3706
3707         return hr;
3708     }
3709
3710     object->blitter = select_blit_implementation(Adapter, DeviceType);
3711
3712     /* set the state of the device to valid */
3713     object->state = WINED3D_OK;
3714
3715     /* Get the initial screen setup for ddraw */
3716     IWineD3DImpl_GetAdapterDisplayMode(iface, Adapter, &mode);
3717
3718     object->ddraw_width = mode.Width;
3719     object->ddraw_height = mode.Height;
3720     object->ddraw_format = mode.Format;
3721
3722     for(i = 0; i < PATCHMAP_SIZE; i++) {
3723         list_init(&object->patches[i]);
3724     }
3725
3726     IWineD3DDeviceParent_WineD3DDeviceCreated(device_parent, *ppReturnedDeviceInterface);
3727
3728     return WINED3D_OK;
3729 }
3730 #undef GLINFO_LOCATION
3731
3732 static HRESULT WINAPI IWineD3DImpl_GetParent(IWineD3D *iface, IUnknown **pParent) {
3733     IWineD3DImpl *This = (IWineD3DImpl *)iface;
3734     IUnknown_AddRef(This->parent);
3735     *pParent = This->parent;
3736     return WINED3D_OK;
3737 }
3738
3739 ULONG WINAPI D3DCB_DefaultDestroySurface(IWineD3DSurface *pSurface) {
3740     IUnknown* surfaceParent;
3741     TRACE("(%p) call back\n", pSurface);
3742
3743     /* Now, release the parent, which will take care of cleaning up the surface for us */
3744     IWineD3DSurface_GetParent(pSurface, &surfaceParent);
3745     IUnknown_Release(surfaceParent);
3746     return IUnknown_Release(surfaceParent);
3747 }
3748
3749 ULONG WINAPI D3DCB_DefaultDestroyVolume(IWineD3DVolume *pVolume) {
3750     IUnknown* volumeParent;
3751     TRACE("(%p) call back\n", pVolume);
3752
3753     /* Now, release the parent, which will take care of cleaning up the volume for us */
3754     IWineD3DVolume_GetParent(pVolume, &volumeParent);
3755     IUnknown_Release(volumeParent);
3756     return IUnknown_Release(volumeParent);
3757 }
3758
3759 static BOOL implementation_is_apple(const WineD3D_GL_Info *gl_info)
3760 {
3761     /* MacOS has various specialities in the extensions it advertises. Some have to be loaded from
3762      * the opengl 1.2+ core, while other extensions are advertised, but software emulated. So try to
3763      * detect the Apple OpenGL implementation to apply some extension fixups afterwards.
3764      *
3765      * Detecting this isn't really easy. The vendor string doesn't mention Apple. Compile-time checks
3766      * aren't sufficient either because a Linux binary may display on a macos X server via remote X11.
3767      * So try to detect the GL implementation by looking at certain Apple extensions. Some extensions
3768      * like client storage might be supported on other implementations too, but GL_APPLE_flush_render
3769      * is specific to the Mac OS X window management, and GL_APPLE_ycbcr_422 is QuickTime specific. So
3770      * the chance that other implementations support them is rather small since Win32 QuickTime uses
3771      * DirectDraw, not OpenGL.
3772      */
3773     if(gl_info->supported[APPLE_FENCE] &&
3774        gl_info->supported[APPLE_CLIENT_STORAGE] &&
3775        gl_info->supported[APPLE_FLUSH_RENDER] &&
3776        gl_info->supported[APPLE_YCBCR_422]) {
3777         TRACE_(d3d_caps)("GL_APPLE_fence, GL_APPLE_client_storage, GL_APPLE_flush_render and GL_ycbcr_422 are supported\n");
3778         TRACE_(d3d_caps)("Activating MacOS fixups\n");
3779         return TRUE;
3780     } else {
3781         TRACE_(d3d_caps)("Apple extensions are not supported\n");
3782         TRACE_(d3d_caps)("Not activating MacOS fixups\n");
3783         return FALSE;
3784     }
3785 }
3786
3787 #define GLINFO_LOCATION (*gl_info)
3788 static void test_pbo_functionality(WineD3D_GL_Info *gl_info) {
3789     /* Some OpenGL implementations, namely Apple's Geforce 8 driver, advertises PBOs,
3790      * but glTexSubImage from a PBO fails miserably, with the first line repeated over
3791      * all the texture. This function detects this bug by its symptom and disables PBOs
3792      * if the test fails.
3793      *
3794      * The test uploads a 4x4 texture via the PBO in the "native" format GL_BGRA,
3795      * GL_UNSIGNED_INT_8_8_8_8_REV. This format triggers the bug, and it is what we use
3796      * for D3DFMT_A8R8G8B8. Then the texture is read back without any PBO and the data
3797      * read back is compared to the original. If they are equal PBOs are assumed to work,
3798      * otherwise the PBO extension is disabled.
3799      */
3800     GLuint texture, pbo;
3801     static const unsigned int pattern[] = {
3802         0x00000000, 0x000000ff, 0x0000ff00, 0x40ff0000,
3803         0x80ffffff, 0x40ffff00, 0x00ff00ff, 0x0000ffff,
3804         0x00ffff00, 0x00ff00ff, 0x0000ffff, 0x000000ff,
3805         0x80ff00ff, 0x0000ffff, 0x00ff00ff, 0x40ff00ff
3806     };
3807     unsigned int check[sizeof(pattern) / sizeof(pattern[0])];
3808
3809     if(!gl_info->supported[ARB_PIXEL_BUFFER_OBJECT]) {
3810         /* No PBO -> No point in testing them */
3811         return;
3812     }
3813
3814     while(glGetError());
3815     glGenTextures(1, &texture);
3816     glBindTexture(GL_TEXTURE_2D, texture);
3817     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 4, 4, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, 0);
3818     checkGLcall("Specifying the PBO test texture\n");
3819
3820     GL_EXTCALL(glGenBuffersARB(1, &pbo));
3821     GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, pbo));
3822     GL_EXTCALL(glBufferDataARB(GL_PIXEL_UNPACK_BUFFER_ARB, sizeof(pattern), pattern, GL_STREAM_DRAW_ARB));
3823     checkGLcall("Specifying the PBO test pbo\n");
3824
3825     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 4, 4, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL);
3826     checkGLcall("Loading the PBO test texture\n");
3827
3828     GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0));
3829     glFinish(); /* just to be sure */
3830
3831     memset(check, 0, sizeof(check));
3832     glGetTexImage(GL_TEXTURE_2D, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, check);
3833     checkGLcall("Reading back the PBO test texture\n");
3834
3835     glDeleteTextures(1, &texture);
3836     GL_EXTCALL(glDeleteBuffersARB(1, &pbo));
3837     checkGLcall("PBO test cleanup\n");
3838
3839     if(memcmp(check, pattern, sizeof(check)) != 0) {
3840         WARN_(d3d_caps)("PBO test failed, read back data doesn't match original\n");
3841         WARN_(d3d_caps)("Disabling PBOs. This may result in slower performance\n");
3842         gl_info->supported[ARB_PIXEL_BUFFER_OBJECT] = FALSE;
3843     } else {
3844         TRACE_(d3d_caps)("PBO test successful\n");
3845     }
3846 }
3847 #undef GLINFO_LOCATION
3848
3849 /* Certain applications(Steam) complain if we report an outdated driver version. In general,
3850  * reporting a driver version is moot because we are not the Windows driver, and we have different
3851  * bugs, features, etc.
3852  *
3853  * If a card is not found in this table, the gl driver version is reported
3854  */
3855 struct driver_version_information {
3856     WORD vendor;                        /* reported PCI card vendor ID  */
3857     WORD card;                          /* reported PCI card device ID  */
3858     WORD hipart_hi, hipart_lo;          /* driver hiword to report      */
3859     WORD lopart_hi, lopart_lo;          /* driver loword to report      */
3860 };
3861
3862 static const struct driver_version_information driver_version_table[] = {
3863     /* Nvidia drivers. Geforce6 and newer cards are supported by the current driver (177.x)*/
3864     /* GeforceFX support is up to 173.x, Geforce2MX/3/4 up to 96.x, TNT/Geforce1/2 up to 71.x */
3865     /* Note that version numbers >100 lets say 123.45 use >= x.y.11.2345 and not x.y.10.12345 */
3866     {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCEFX_5200,     7,  15, 11, 7341   },
3867     {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCEFX_5600,     7,  15, 11, 7341   },
3868     {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCEFX_5800,     7,  15, 11, 7341   },
3869     {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_6200,       7,  15, 11, 7341   },
3870     {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_6600GT,     7,  15, 11, 7341   },
3871     {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_6800,       7,  15, 11, 7341   },
3872     {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_7400,       7,  15, 11, 7341   },
3873     {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_7300,       7,  15, 11, 7341   },
3874     {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_7600,       7,  15, 11, 7341   },
3875     {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_7800GT,     7,  15, 11, 7341   },
3876     {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_8300GS,     7,  15, 11, 7341   },
3877     {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_8600GT,     7,  15, 11, 7341   },
3878     {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_8600MGT,    7,  15, 11, 7341   },
3879     {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_8800GTS,    7,  15, 11, 7341   },
3880     {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_9600GT,     7,  15, 11, 7341    },
3881     {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_9800GT,     7,  15, 11, 7341    },
3882     {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX280,     7,  15, 11, 7341    },
3883
3884     /* ATI cards. The driver versions are somewhat similar, but not quite the same. Let's hardcode */
3885     {VENDOR_ATI,        CARD_ATI_RADEON_9500,           6,  14, 10, 6764    },
3886     {VENDOR_ATI,        CARD_ATI_RADEON_X700,           6,  14, 10, 6764    },
3887     {VENDOR_ATI,        CARD_ATI_RADEON_X1600,          6,  14, 10, 6764    },
3888     {VENDOR_ATI,        CARD_ATI_RADEON_HD2300,         6,  14, 10, 6764    },
3889     {VENDOR_ATI,        CARD_ATI_RADEON_HD2600,         6,  14, 10, 6764    },
3890     {VENDOR_ATI,        CARD_ATI_RADEON_HD2900,         6,  14, 10, 6764    },
3891
3892     /* TODO: Add information about legacy nvidia and ATI hardware, Intel and other cards */
3893 };
3894
3895 static void fixup_extensions(WineD3D_GL_Info *gl_info) {
3896     unsigned int i;
3897     BOOL apple = implementation_is_apple(gl_info);
3898
3899     if(apple) {
3900         /* MacOS advertises more GLSL vertex shader uniforms than supported by the hardware, and if more are
3901          * used it falls back to software. While the compiler can detect if the shader uses all declared
3902          * uniforms, the optimization fails if the shader uses relative addressing. So any GLSL shader
3903          * using relative addressing falls back to software.
3904          *
3905          * ARB vp gives the correct amount of uniforms, so use it instead of GLSL
3906          */
3907         if(gl_info->vs_glsl_constantsF <= gl_info->vs_arb_constantsF) {
3908             FIXME("GLSL doesn't advertise more vertex shader uniforms than ARB. Driver fixup outdated?\n");
3909         } else {
3910             TRACE("Driver claims %u GLSL vs uniforms, replacing with %u ARB vp uniforms\n",
3911                   gl_info->vs_glsl_constantsF, gl_info->vs_arb_constantsF);
3912             gl_info->vs_glsl_constantsF = gl_info->vs_arb_constantsF;
3913         }
3914
3915         /* The Intel GPUs on MacOS set the .w register of texcoords to 0.0 by default, which causes problems
3916          * with fixed function fragment processing. Ideally this flag should be detected with a test shader
3917          * and OpenGL feedback mode, but some GL implementations (MacOS ATI at least, probably all MacOS ones)
3918          * do not like vertex shaders in feedback mode and return an error, even though it should be valid
3919          * according to the spec.
3920          *
3921          * We don't want to enable this on all cards, as it adds an extra instruction per texcoord used. This
3922          * makes the shader slower and eats instruction slots which should be available to the d3d app.
3923          *
3924          * ATI Radeon HD 2xxx cards on MacOS have the issue. Instead of checking for the buggy cards, blacklist
3925          * all radeon cards on Macs and whitelist the good ones. That way we're prepared for the future. If
3926          * this workaround is activated on cards that do not need it, it won't break things, just affect
3927          * performance negatively.
3928          */
3929         if(gl_info->gl_vendor == VENDOR_INTEL ||
3930            (gl_info->gl_vendor == VENDOR_ATI && gl_info->gl_card != CARD_ATI_RADEON_X1600)) {
3931             TRACE("Enabling vertex texture coord fixes in vertex shaders\n");
3932             gl_info->set_texcoord_w = TRUE;
3933         }
3934     }
3935
3936     /* MacOS advertises GL_ARB_texture_non_power_of_two on ATI r500 and earlier cards, although
3937      * these cards only support GL_ARB_texture_rectangle(D3DPTEXTURECAPS_NONPOW2CONDITIONAL).
3938      * If real NP2 textures are used, the driver falls back to software. We could just remove the
3939      * extension and use GL_ARB_texture_rectangle instead, but texture_rectangle is inconventient
3940      * due to the non-normalized texture coordinates. Thus set an internal extension flag,
3941      * GL_WINE_normalized_texrect, which signals the code that it can use non power of two textures
3942      * as per GL_ARB_texture_non_power_of_two, but has to stick to the texture_rectangle limits.
3943      *
3944      * fglrx doesn't advertise GL_ARB_texture_non_power_of_two, but it advertises opengl 2.0 which
3945      * has this extension promoted to core. The extension loading code sets this extension supported
3946      * due to that, so this code works on fglrx as well.
3947      */
3948     if(gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO] && gl_info->gl_vendor == VENDOR_ATI) {
3949         if(gl_info->gl_card == CARD_ATI_RADEON_X700 || gl_info->gl_card == CARD_ATI_RADEON_X1600 ||
3950             gl_info->gl_card == CARD_ATI_RADEON_9500 || gl_info->gl_card == CARD_ATI_RADEON_8500  ||
3951             gl_info->gl_card == CARD_ATI_RADEON_7200 || gl_info->gl_card == CARD_ATI_RAGE_128PRO) {
3952             TRACE("GL_ARB_texture_non_power_of_two advertised on R500 or earlier card, removing\n");
3953             gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO] = FALSE;
3954             gl_info->supported[WINE_NORMALIZED_TEXRECT] = TRUE;
3955         }
3956     }
3957
3958     /*  The nVidia GeForceFX series reports OpenGL 2.0 capabilities with the latest drivers versions, but
3959      *  doesn't explicitly advertise the ARB_tex_npot extension in the GL extension string.
3960      *  This usually means that ARB_tex_npot is supported in hardware as long as the application is staying
3961      *  within the limits enforced by the ARB_texture_rectangle extension. This however is not true for the
3962      *  FX series, which instantly falls back to a slower software path as soon as ARB_tex_npot is used.
3963      *  We therefore completely remove ARB_tex_npot from the list of supported extensions.
3964      *
3965      *  Note that wine_normalized_texrect can't be used in this case because internally it uses ARB_tex_npot,
3966      *  triggering the software fallback. There is not much we can do here apart from disabling the
3967      *  software-emulated extension and reenable ARB_tex_rect (which was previously disabled
3968      *  in IWineD3DImpl_FillGLCaps).
3969      *  This fixup removes performance problems on both the FX 5900 and FX 5700 (e.g. for framebuffer
3970      *  post-processing effects in the game "Max Payne 2").
3971      *  The behaviour can be verified through a simple test app attached in bugreport #14724.
3972      */
3973     if(gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO] && gl_info->gl_vendor == VENDOR_NVIDIA) {
3974         if(gl_info->gl_card == CARD_NVIDIA_GEFORCEFX_5800 || gl_info->gl_card == CARD_NVIDIA_GEFORCEFX_5600) {
3975             TRACE("GL_ARB_texture_non_power_of_two advertised through OpenGL 2.0 on NV FX card, removing\n");
3976             gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO] = FALSE;
3977             gl_info->supported[ARB_TEXTURE_RECTANGLE] = TRUE;
3978         }
3979     }
3980
3981     /* Find out if PBOs work as they are supposed to */
3982     test_pbo_functionality(gl_info);
3983
3984     /* Fixup the driver version */
3985     for(i = 0; i < (sizeof(driver_version_table) / sizeof(driver_version_table[0])); i++) {
3986         if(gl_info->gl_vendor == driver_version_table[i].vendor &&
3987            gl_info->gl_card   == driver_version_table[i].card) {
3988             TRACE_(d3d_caps)("Found card 0x%04x, 0x%04x in driver version DB\n", gl_info->gl_vendor, gl_info->gl_card);
3989
3990             gl_info->driver_version        = MAKEDWORD_VERSION(driver_version_table[i].lopart_hi,
3991                                                                driver_version_table[i].lopart_lo);
3992             gl_info->driver_version_hipart = MAKEDWORD_VERSION(driver_version_table[i].hipart_hi,
3993                                                                driver_version_table[i].hipart_lo);
3994             break;
3995         }
3996     }
3997 }
3998
3999 static void WINE_GLAPI invalid_func(const void *data)
4000 {
4001     ERR("Invalid vertex attribute function called\n");
4002     DebugBreak();
4003 }
4004
4005 static void WINE_GLAPI invalid_texcoord_func(GLenum unit, const void *data)
4006 {
4007     ERR("Invalid texcoord function called\n");
4008     DebugBreak();
4009 }
4010
4011 #define GLINFO_LOCATION (Adapters[0].gl_info)
4012
4013 /* Helper functions for providing vertex data to opengl. The arrays are initialized based on
4014  * the extension detection and are used in drawStridedSlow
4015  */
4016 static void WINE_GLAPI position_d3dcolor(const void *data)
4017 {
4018     DWORD pos = *((const DWORD *)data);
4019
4020     FIXME("Add a test for fixed function position from d3dcolor type\n");
4021     glVertex4s(D3DCOLOR_B_R(pos),
4022                D3DCOLOR_B_G(pos),
4023                D3DCOLOR_B_B(pos),
4024                D3DCOLOR_B_A(pos));
4025 }
4026
4027 static void WINE_GLAPI position_float4(const void *data)
4028 {
4029     const GLfloat *pos = data;
4030
4031     if (pos[3] < eps && pos[3] > -eps)
4032         glVertex3fv(pos);
4033     else {
4034         float w = 1.0 / pos[3];
4035
4036         glVertex4f(pos[0] * w, pos[1] * w, pos[2] * w, w);
4037     }
4038 }
4039
4040 static void WINE_GLAPI diffuse_d3dcolor(const void *data)
4041 {
4042     DWORD diffuseColor = *((const DWORD *)data);
4043
4044     glColor4ub(D3DCOLOR_B_R(diffuseColor),
4045                D3DCOLOR_B_G(diffuseColor),
4046                D3DCOLOR_B_B(diffuseColor),
4047                D3DCOLOR_B_A(diffuseColor));
4048 }
4049
4050 static void WINE_GLAPI specular_d3dcolor(const void *data)
4051 {
4052     DWORD specularColor = *((const DWORD *)data);
4053
4054     GL_EXTCALL(glSecondaryColor3ubEXT)(D3DCOLOR_B_R(specularColor),
4055                                        D3DCOLOR_B_G(specularColor),
4056                                        D3DCOLOR_B_B(specularColor));
4057 }
4058
4059 static void WINE_GLAPI warn_no_specular_func(const void *data)
4060 {
4061     WARN("GL_EXT_secondary_color not supported\n");
4062 }
4063
4064 static void fillGLAttribFuncs(const WineD3D_GL_Info *gl_info)
4065 {
4066     position_funcs[WINED3DDECLTYPE_FLOAT1]      = invalid_func;
4067     position_funcs[WINED3DDECLTYPE_FLOAT2]      = invalid_func;
4068     position_funcs[WINED3DDECLTYPE_FLOAT3]      = (glAttribFunc)glVertex3fv;
4069     position_funcs[WINED3DDECLTYPE_FLOAT4]      = position_float4;
4070     position_funcs[WINED3DDECLTYPE_D3DCOLOR]    = position_d3dcolor;
4071     position_funcs[WINED3DDECLTYPE_UBYTE4]      = invalid_func;
4072     position_funcs[WINED3DDECLTYPE_SHORT2]      = invalid_func;
4073     position_funcs[WINED3DDECLTYPE_SHORT4]      = (glAttribFunc)glVertex2sv;
4074     position_funcs[WINED3DDECLTYPE_UBYTE4N]     = invalid_func;
4075     position_funcs[WINED3DDECLTYPE_SHORT2N]     = invalid_func;
4076     position_funcs[WINED3DDECLTYPE_SHORT4N]     = invalid_func;
4077     position_funcs[WINED3DDECLTYPE_USHORT2N]    = invalid_func;
4078     position_funcs[WINED3DDECLTYPE_USHORT4N]    = invalid_func;
4079     position_funcs[WINED3DDECLTYPE_UDEC3]       = invalid_func;
4080     position_funcs[WINED3DDECLTYPE_DEC3N]       = invalid_func;
4081     position_funcs[WINED3DDECLTYPE_FLOAT16_2]   = invalid_func;
4082     position_funcs[WINED3DDECLTYPE_FLOAT16_4]   = invalid_func;
4083
4084     diffuse_funcs[WINED3DDECLTYPE_FLOAT1]       = invalid_func;
4085     diffuse_funcs[WINED3DDECLTYPE_FLOAT2]       = invalid_func;
4086     diffuse_funcs[WINED3DDECLTYPE_FLOAT3]       = (glAttribFunc)glColor3fv;
4087     diffuse_funcs[WINED3DDECLTYPE_FLOAT4]       = (glAttribFunc)glColor4fv;
4088     diffuse_funcs[WINED3DDECLTYPE_D3DCOLOR]     = diffuse_d3dcolor;
4089     diffuse_funcs[WINED3DDECLTYPE_UBYTE4]       = invalid_func;
4090     diffuse_funcs[WINED3DDECLTYPE_SHORT2]       = invalid_func;
4091     diffuse_funcs[WINED3DDECLTYPE_SHORT4]       = invalid_func;
4092     diffuse_funcs[WINED3DDECLTYPE_UBYTE4N]      = (glAttribFunc)glColor4ubv;
4093     diffuse_funcs[WINED3DDECLTYPE_SHORT2N]      = invalid_func;
4094     diffuse_funcs[WINED3DDECLTYPE_SHORT4N]      = (glAttribFunc)glColor4sv;
4095     diffuse_funcs[WINED3DDECLTYPE_USHORT2N]     = invalid_func;
4096     diffuse_funcs[WINED3DDECLTYPE_USHORT4N]     = (glAttribFunc)glColor4usv;
4097     diffuse_funcs[WINED3DDECLTYPE_UDEC3]        = invalid_func;
4098     diffuse_funcs[WINED3DDECLTYPE_DEC3N]        = invalid_func;
4099     diffuse_funcs[WINED3DDECLTYPE_FLOAT16_2]    = invalid_func;
4100     diffuse_funcs[WINED3DDECLTYPE_FLOAT16_4]    = invalid_func;
4101
4102     /* No 4 component entry points here */
4103     specular_funcs[WINED3DDECLTYPE_FLOAT1]      = invalid_func;
4104     specular_funcs[WINED3DDECLTYPE_FLOAT2]      = invalid_func;
4105     if(GL_SUPPORT(EXT_SECONDARY_COLOR)) {
4106         specular_funcs[WINED3DDECLTYPE_FLOAT3]      = (glAttribFunc)GL_EXTCALL(glSecondaryColor3fvEXT);
4107     } else {
4108         specular_funcs[WINED3DDECLTYPE_FLOAT3]      = warn_no_specular_func;
4109     }
4110     specular_funcs[WINED3DDECLTYPE_FLOAT4]      = invalid_func;
4111     if(GL_SUPPORT(EXT_SECONDARY_COLOR)) {
4112         specular_funcs[WINED3DDECLTYPE_D3DCOLOR]    = specular_d3dcolor;
4113     } else {
4114         specular_funcs[WINED3DDECLTYPE_D3DCOLOR]      = warn_no_specular_func;
4115     }
4116     specular_funcs[WINED3DDECLTYPE_UBYTE4]      = invalid_func;
4117     specular_funcs[WINED3DDECLTYPE_SHORT2]      = invalid_func;
4118     specular_funcs[WINED3DDECLTYPE_SHORT4]      = invalid_func;
4119     specular_funcs[WINED3DDECLTYPE_UBYTE4N]     = invalid_func;
4120     specular_funcs[WINED3DDECLTYPE_SHORT2N]     = invalid_func;
4121     specular_funcs[WINED3DDECLTYPE_SHORT4N]     = invalid_func;
4122     specular_funcs[WINED3DDECLTYPE_USHORT2N]    = invalid_func;
4123     specular_funcs[WINED3DDECLTYPE_USHORT4N]    = invalid_func;
4124     specular_funcs[WINED3DDECLTYPE_UDEC3]       = invalid_func;
4125     specular_funcs[WINED3DDECLTYPE_DEC3N]       = invalid_func;
4126     specular_funcs[WINED3DDECLTYPE_FLOAT16_2]   = invalid_func;
4127     specular_funcs[WINED3DDECLTYPE_FLOAT16_4]   = invalid_func;
4128
4129     /* Only 3 component entry points here. Test how others behave. Float4 normals are used
4130      * by one of our tests, trying to pass it to the pixel shader, which fails on Windows.
4131      */
4132     normal_funcs[WINED3DDECLTYPE_FLOAT1]         = invalid_func;
4133     normal_funcs[WINED3DDECLTYPE_FLOAT2]         = invalid_func;
4134     normal_funcs[WINED3DDECLTYPE_FLOAT3]         = (glAttribFunc)glNormal3fv;
4135     normal_funcs[WINED3DDECLTYPE_FLOAT4]         = (glAttribFunc)glNormal3fv; /* Just ignore the 4th value */
4136     normal_funcs[WINED3DDECLTYPE_D3DCOLOR]       = invalid_func;
4137     normal_funcs[WINED3DDECLTYPE_UBYTE4]         = invalid_func;
4138     normal_funcs[WINED3DDECLTYPE_SHORT2]         = invalid_func;
4139     normal_funcs[WINED3DDECLTYPE_SHORT4]         = invalid_func;
4140     normal_funcs[WINED3DDECLTYPE_UBYTE4N]        = invalid_func;
4141     normal_funcs[WINED3DDECLTYPE_SHORT2N]        = invalid_func;
4142     normal_funcs[WINED3DDECLTYPE_SHORT4N]        = invalid_func;
4143     normal_funcs[WINED3DDECLTYPE_USHORT2N]       = invalid_func;
4144     normal_funcs[WINED3DDECLTYPE_USHORT4N]       = invalid_func;
4145     normal_funcs[WINED3DDECLTYPE_UDEC3]          = invalid_func;
4146     normal_funcs[WINED3DDECLTYPE_DEC3N]          = invalid_func;
4147     normal_funcs[WINED3DDECLTYPE_FLOAT16_2]      = invalid_func;
4148     normal_funcs[WINED3DDECLTYPE_FLOAT16_4]      = invalid_func;
4149
4150     multi_texcoord_funcs[WINED3DDECLTYPE_FLOAT1]    = (glMultiTexCoordFunc)GL_EXTCALL(glMultiTexCoord1fvARB);
4151     multi_texcoord_funcs[WINED3DDECLTYPE_FLOAT2]    = (glMultiTexCoordFunc)GL_EXTCALL(glMultiTexCoord2fvARB);
4152     multi_texcoord_funcs[WINED3DDECLTYPE_FLOAT3]    = (glMultiTexCoordFunc)GL_EXTCALL(glMultiTexCoord3fvARB);
4153     multi_texcoord_funcs[WINED3DDECLTYPE_FLOAT4]    = (glMultiTexCoordFunc)GL_EXTCALL(glMultiTexCoord4fvARB);
4154     multi_texcoord_funcs[WINED3DDECLTYPE_D3DCOLOR]  = invalid_texcoord_func;
4155     multi_texcoord_funcs[WINED3DDECLTYPE_UBYTE4]    = invalid_texcoord_func;
4156     multi_texcoord_funcs[WINED3DDECLTYPE_SHORT2]    = (glMultiTexCoordFunc)GL_EXTCALL(glMultiTexCoord2svARB);
4157     multi_texcoord_funcs[WINED3DDECLTYPE_SHORT4]    = (glMultiTexCoordFunc)GL_EXTCALL(glMultiTexCoord4svARB);
4158     multi_texcoord_funcs[WINED3DDECLTYPE_UBYTE4N]   = invalid_texcoord_func;
4159     multi_texcoord_funcs[WINED3DDECLTYPE_SHORT2N]   = invalid_texcoord_func;
4160     multi_texcoord_funcs[WINED3DDECLTYPE_SHORT4N]   = invalid_texcoord_func;
4161     multi_texcoord_funcs[WINED3DDECLTYPE_USHORT2N]  = invalid_texcoord_func;
4162     multi_texcoord_funcs[WINED3DDECLTYPE_USHORT4N]  = invalid_texcoord_func;
4163     multi_texcoord_funcs[WINED3DDECLTYPE_UDEC3]     = invalid_texcoord_func;
4164     multi_texcoord_funcs[WINED3DDECLTYPE_DEC3N]     = invalid_texcoord_func;
4165     if (GL_SUPPORT(NV_HALF_FLOAT))
4166     {
4167         multi_texcoord_funcs[WINED3DDECLTYPE_FLOAT16_2] = (glMultiTexCoordFunc)GL_EXTCALL(glMultiTexCoord2hvNV);
4168         multi_texcoord_funcs[WINED3DDECLTYPE_FLOAT16_4] = (glMultiTexCoordFunc)GL_EXTCALL(glMultiTexCoord4hvNV);
4169     } else {
4170         multi_texcoord_funcs[WINED3DDECLTYPE_FLOAT16_2] = invalid_texcoord_func;
4171         multi_texcoord_funcs[WINED3DDECLTYPE_FLOAT16_4] = invalid_texcoord_func;
4172     }
4173 }
4174
4175 #define PUSH1(att)        attribs[nAttribs++] = (att);
4176 BOOL InitAdapters(void) {
4177     static HMODULE mod_gl;
4178     BOOL ret;
4179     int ps_selected_mode, vs_selected_mode;
4180
4181     /* No need to hold any lock. The calling library makes sure only one thread calls
4182      * wined3d simultaneously
4183      */
4184     if(numAdapters > 0) return Adapters[0].opengl;
4185
4186     TRACE("Initializing adapters\n");
4187
4188     if(!mod_gl) {
4189 #ifdef USE_WIN32_OPENGL
4190 #define USE_GL_FUNC(pfn) pfn = (void*)GetProcAddress(mod_gl, #pfn);
4191         mod_gl = LoadLibraryA("opengl32.dll");
4192         if(!mod_gl) {
4193             ERR("Can't load opengl32.dll!\n");
4194             goto nogl_adapter;
4195         }
4196 #else
4197 #define USE_GL_FUNC(pfn) pfn = (void*)pwglGetProcAddress(#pfn);
4198         /* To bypass the opengl32 thunks load wglGetProcAddress from gdi32 (glXGetProcAddress wrapper) instead of opengl32's */
4199         mod_gl = GetModuleHandleA("gdi32.dll");
4200 #endif
4201     }
4202
4203 /* Load WGL core functions from opengl32.dll */
4204 #define USE_WGL_FUNC(pfn) p##pfn = (void*)GetProcAddress(mod_gl, #pfn);
4205     WGL_FUNCS_GEN;
4206 #undef USE_WGL_FUNC
4207
4208     if(!pwglGetProcAddress) {
4209         ERR("Unable to load wglGetProcAddress!\n");
4210         goto nogl_adapter;
4211     }
4212
4213 /* Dynamically load all GL core functions */
4214     GL_FUNCS_GEN;
4215 #undef USE_GL_FUNC
4216
4217     /* Load glFinish and glFlush from opengl32.dll even if we're not using WIN32 opengl
4218      * otherwise because we have to use winex11.drv's override
4219      */
4220 #ifdef USE_WIN32_OPENGL
4221     glFinish = (void*)GetProcAddress(mod_gl, "glFinish");
4222     glFlush = (void*)GetProcAddress(mod_gl, "glFlush");
4223 #else
4224     glFinish = (void*)pwglGetProcAddress("wglFinish");
4225     glFlush = (void*)pwglGetProcAddress("wglFlush");
4226 #endif
4227
4228     glEnableWINE = glEnable;
4229     glDisableWINE = glDisable;
4230
4231     /* For now only one default adapter */
4232     {
4233         int iPixelFormat;
4234         int attribs[10];
4235         int values[10];
4236         int nAttribs = 0;
4237         int res;
4238         int i;
4239         WineD3D_PixelFormat *cfgs;
4240         int attribute;
4241         DISPLAY_DEVICEW DisplayDevice;
4242         HDC hdc;
4243
4244         TRACE("Initializing default adapter\n");
4245         Adapters[0].num = 0;
4246         Adapters[0].monitorPoint.x = -1;
4247         Adapters[0].monitorPoint.y = -1;
4248
4249         if (!WineD3D_CreateFakeGLContext()) {
4250             ERR("Failed to get a gl context for default adapter\n");
4251             WineD3D_ReleaseFakeGLContext();
4252             goto nogl_adapter;
4253         }
4254
4255         ret = IWineD3DImpl_FillGLCaps(&Adapters[0].gl_info);
4256         if(!ret) {
4257             ERR("Failed to initialize gl caps for default adapter\n");
4258             WineD3D_ReleaseFakeGLContext();
4259             goto nogl_adapter;
4260         }
4261         ret = initPixelFormats(&Adapters[0].gl_info);
4262         if(!ret) {
4263             ERR("Failed to init gl formats\n");
4264             WineD3D_ReleaseFakeGLContext();
4265             goto nogl_adapter;
4266         }
4267
4268         hdc = pwglGetCurrentDC();
4269         if(!hdc) {
4270             ERR("Failed to get gl HDC\n");
4271             WineD3D_ReleaseFakeGLContext();
4272             goto nogl_adapter;
4273         }
4274
4275         Adapters[0].driver = "Display";
4276         Adapters[0].description = "Direct3D HAL";
4277
4278         /* Use the VideoRamSize registry setting when set */
4279         if(wined3d_settings.emulated_textureram)
4280             Adapters[0].TextureRam = wined3d_settings.emulated_textureram;
4281         else
4282             Adapters[0].TextureRam = Adapters[0].gl_info.vidmem;
4283         Adapters[0].UsedTextureRam = 0;
4284         TRACE("Emulating %dMB of texture ram\n", Adapters[0].TextureRam/(1024*1024));
4285
4286         /* Initialize the Adapter's DeviceName which is required for ChangeDisplaySettings and friends */
4287         DisplayDevice.cb = sizeof(DisplayDevice);
4288         EnumDisplayDevicesW(NULL, 0 /* Adapter 0 = iDevNum 0 */, &DisplayDevice, 0);
4289         TRACE("DeviceName: %s\n", debugstr_w(DisplayDevice.DeviceName));
4290         strcpyW(Adapters[0].DeviceName, DisplayDevice.DeviceName);
4291
4292         attribute = WGL_NUMBER_PIXEL_FORMATS_ARB;
4293         GL_EXTCALL(wglGetPixelFormatAttribivARB(hdc, 0, 0, 1, &attribute, &Adapters[0].nCfgs));
4294
4295         Adapters[0].cfgs = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, Adapters[0].nCfgs *sizeof(WineD3D_PixelFormat));
4296         cfgs = Adapters[0].cfgs;
4297         PUSH1(WGL_RED_BITS_ARB)
4298         PUSH1(WGL_GREEN_BITS_ARB)
4299         PUSH1(WGL_BLUE_BITS_ARB)
4300         PUSH1(WGL_ALPHA_BITS_ARB)
4301         PUSH1(WGL_DEPTH_BITS_ARB)
4302         PUSH1(WGL_STENCIL_BITS_ARB)
4303         PUSH1(WGL_DRAW_TO_WINDOW_ARB)
4304         PUSH1(WGL_PIXEL_TYPE_ARB)
4305         PUSH1(WGL_DOUBLE_BUFFER_ARB)
4306         PUSH1(WGL_AUX_BUFFERS_ARB)
4307
4308         for(iPixelFormat=1; iPixelFormat<=Adapters[0].nCfgs; iPixelFormat++) {
4309             res = GL_EXTCALL(wglGetPixelFormatAttribivARB(hdc, iPixelFormat, 0, nAttribs, attribs, values));
4310
4311             if(!res)
4312                 continue;
4313
4314             /* Cache the pixel format */
4315             cfgs->iPixelFormat = iPixelFormat;
4316             cfgs->redSize = values[0];
4317             cfgs->greenSize = values[1];
4318             cfgs->blueSize = values[2];
4319             cfgs->alphaSize = values[3];
4320             cfgs->depthSize = values[4];
4321             cfgs->stencilSize = values[5];
4322             cfgs->windowDrawable = values[6];
4323             cfgs->iPixelType = values[7];
4324             cfgs->doubleBuffer = values[8];
4325             cfgs->auxBuffers = values[9];
4326
4327             cfgs->pbufferDrawable = FALSE;
4328             /* Check for pbuffer support when it is around as wglGetPixelFormatAttribiv fails for unknown attributes. */
4329             if(GL_SUPPORT(WGL_ARB_PBUFFER)) {
4330                 int attrib = WGL_DRAW_TO_PBUFFER_ARB;
4331                 int value;
4332                 if(GL_EXTCALL(wglGetPixelFormatAttribivARB(hdc, iPixelFormat, 0, 1, &attrib, &value)))
4333                     cfgs->pbufferDrawable = value;
4334             }
4335
4336             cfgs->numSamples = 0;
4337             /* Check multisample support */
4338             if(GL_SUPPORT(ARB_MULTISAMPLE)) {
4339                 int attrib[2] = {WGL_SAMPLE_BUFFERS_ARB, WGL_SAMPLES_ARB};
4340                 int value[2];
4341                 if(GL_EXTCALL(wglGetPixelFormatAttribivARB(hdc, iPixelFormat, 0, 2, attrib, value))) {
4342                     /* value[0] = WGL_SAMPLE_BUFFERS_ARB which tells whether multisampling is supported.
4343                      * value[1] = number of multi sample buffers*/
4344                     if(value[0])
4345                         cfgs->numSamples = value[1];
4346                 }
4347             }
4348
4349             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);
4350             cfgs++;
4351         }
4352
4353         /* D16, D24X8 and D24S8 are common depth / depth+stencil formats. All drivers support them though this doesn't
4354          * mean that the format is offered in hardware. For instance Geforce8 cards don't have offer D16 in hardware
4355          * but just fake it using D24(X8?) which is fine. D3D also allows that.
4356          * Some display drivers (i915 on Linux) only report mixed depth+stencil formats like D24S8. MSDN clearly mentions
4357          * that only on lockable formats (e.g. D16_locked) the bit order is guaranteed and that on other formats the
4358          * driver is allowed to consume more bits EXCEPT for stencil bits.
4359          *
4360          * Mark an adapter with this broken stencil behavior.
4361          */
4362         Adapters[0].brokenStencil = TRUE;
4363         for(i=0, cfgs=Adapters[0].cfgs; i<Adapters[0].nCfgs; i++) {
4364             /* Nearly all drivers offer depth formats without stencil, only on i915 this if-statement won't be entered. */
4365             if(cfgs[i].depthSize && !cfgs[i].stencilSize) {
4366                 Adapters[0].brokenStencil = FALSE;
4367                 break;
4368             }
4369         }
4370
4371         fixup_extensions(&Adapters[0].gl_info);
4372         add_gl_compat_wrappers(&Adapters[0].gl_info);
4373
4374         WineD3D_ReleaseFakeGLContext();
4375
4376         select_shader_mode(&Adapters[0].gl_info, WINED3DDEVTYPE_HAL, &ps_selected_mode, &vs_selected_mode);
4377         select_shader_max_constants(ps_selected_mode, vs_selected_mode, &Adapters[0].gl_info);
4378         fillGLAttribFuncs(&Adapters[0].gl_info);
4379         init_type_lookup(&Adapters[0].gl_info);
4380         Adapters[0].opengl = TRUE;
4381     }
4382     numAdapters = 1;
4383     TRACE("%d adapters successfully initialized\n", numAdapters);
4384
4385     return TRUE;
4386
4387 nogl_adapter:
4388     /* Initialize an adapter for ddraw-only memory counting */
4389     memset(Adapters, 0, sizeof(Adapters));
4390     Adapters[0].num = 0;
4391     Adapters[0].opengl = FALSE;
4392     Adapters[0].monitorPoint.x = -1;
4393     Adapters[0].monitorPoint.y = -1;
4394
4395     Adapters[0].driver = "Display";
4396     Adapters[0].description = "WineD3D DirectDraw Emulation";
4397     if(wined3d_settings.emulated_textureram) {
4398         Adapters[0].TextureRam = wined3d_settings.emulated_textureram;
4399     } else {
4400         Adapters[0].TextureRam = 8 * 1024 * 1024; /* This is plenty for a DDraw-only card */
4401     }
4402
4403     numAdapters = 1;
4404     return FALSE;
4405 }
4406 #undef PUSH1
4407 #undef GLINFO_LOCATION
4408
4409 /**********************************************************
4410  * IWineD3D VTbl follows
4411  **********************************************************/
4412
4413 const IWineD3DVtbl IWineD3D_Vtbl =
4414 {
4415     /* IUnknown */
4416     IWineD3DImpl_QueryInterface,
4417     IWineD3DImpl_AddRef,
4418     IWineD3DImpl_Release,
4419     /* IWineD3D */
4420     IWineD3DImpl_GetParent,
4421     IWineD3DImpl_GetAdapterCount,
4422     IWineD3DImpl_RegisterSoftwareDevice,
4423     IWineD3DImpl_GetAdapterMonitor,
4424     IWineD3DImpl_GetAdapterModeCount,
4425     IWineD3DImpl_EnumAdapterModes,
4426     IWineD3DImpl_GetAdapterDisplayMode,
4427     IWineD3DImpl_GetAdapterIdentifier,
4428     IWineD3DImpl_CheckDeviceMultiSampleType,
4429     IWineD3DImpl_CheckDepthStencilMatch,
4430     IWineD3DImpl_CheckDeviceType,
4431     IWineD3DImpl_CheckDeviceFormat,
4432     IWineD3DImpl_CheckDeviceFormatConversion,
4433     IWineD3DImpl_GetDeviceCaps,
4434     IWineD3DImpl_CreateDevice
4435 };