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