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