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