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