hlink/tests: Add a trailing '\n' to an ok() call.
[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  * Copyright 2009 Henri Verbeet for CodeWeavers
10  *
11  * This library is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU Lesser General Public
13  * License as published by the Free Software Foundation; either
14  * version 2.1 of the License, or (at your option) any later version.
15  *
16  * This library is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
19  * Lesser General Public License for more details.
20  *
21  * You should have received a copy of the GNU Lesser General Public
22  * License along with this library; if not, write to the Free Software
23  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
24  */
25
26 #include "config.h"
27 #include "wined3d_private.h"
28
29 WINE_DEFAULT_DEBUG_CHANNEL(d3d);
30 WINE_DECLARE_DEBUG_CHANNEL(d3d_caps);
31
32 #define GLINFO_LOCATION (*gl_info)
33 #define WINE_DEFAULT_VIDMEM (64 * 1024 * 1024)
34 #define MAKEDWORD_VERSION(maj, min)  ((maj & 0xffff) << 16) | (min & 0xffff)
35
36 /* The d3d device ID */
37 static const GUID IID_D3DDEVICE_D3DUID = { 0xaeb2cdd4, 0x6e41, 0x43ea, { 0x94,0x1c,0x83,0x61,0xcc,0x76,0x07,0x81 } };
38
39 /* Extension detection */
40 static const struct {
41     const char *extension_string;
42     GL_SupportedExt extension;
43     DWORD version;
44 } EXTENSION_MAP[] = {
45     /* APPLE */
46     {"GL_APPLE_client_storage",             APPLE_CLIENT_STORAGE,           0                           },
47     {"GL_APPLE_fence",                      APPLE_FENCE,                    0                           },
48     {"GL_APPLE_float_pixels",               APPLE_FLOAT_PIXELS,             0                           },
49     {"GL_APPLE_flush_buffer_range",         APPLE_FLUSH_BUFFER_RANGE,       0                           },
50     {"GL_APPLE_flush_render",               APPLE_FLUSH_RENDER,             0                           },
51     {"GL_APPLE_ycbcr_422",                  APPLE_YCBCR_422,                0                           },
52
53     /* ARB */
54     {"GL_ARB_color_buffer_float",           ARB_COLOR_BUFFER_FLOAT,         0                           },
55     {"GL_ARB_depth_buffer_float",           ARB_DEPTH_BUFFER_FLOAT,         0                           },
56     {"GL_ARB_depth_clamp",                  ARB_DEPTH_CLAMP,                0                           },
57     {"GL_ARB_depth_texture",                ARB_DEPTH_TEXTURE,              0                           },
58     {"GL_ARB_draw_buffers",                 ARB_DRAW_BUFFERS,               0                           },
59     {"GL_ARB_fragment_program",             ARB_FRAGMENT_PROGRAM,           0                           },
60     {"GL_ARB_fragment_shader",              ARB_FRAGMENT_SHADER,            0                           },
61     {"GL_ARB_framebuffer_object",           ARB_FRAMEBUFFER_OBJECT,         0                           },
62     {"GL_ARB_geometry_shader4",             ARB_GEOMETRY_SHADER4,           0                           },
63     {"GL_ARB_half_float_pixel",             ARB_HALF_FLOAT_PIXEL,           0                           },
64     {"GL_ARB_half_float_vertex",            ARB_HALF_FLOAT_VERTEX,          0                           },
65     {"GL_ARB_imaging",                      ARB_IMAGING,                    0                           },
66     {"GL_ARB_map_buffer_range",             ARB_MAP_BUFFER_RANGE,           0                           },
67     {"GL_ARB_multisample",                  ARB_MULTISAMPLE,                0                           }, /* needs GLX_ARB_MULTISAMPLE as well */
68     {"GL_ARB_multitexture",                 ARB_MULTITEXTURE,               0                           },
69     {"GL_ARB_occlusion_query",              ARB_OCCLUSION_QUERY,            0                           },
70     {"GL_ARB_pixel_buffer_object",          ARB_PIXEL_BUFFER_OBJECT,        0                           },
71     {"GL_ARB_point_parameters",             ARB_POINT_PARAMETERS,           0                           },
72     {"GL_ARB_point_sprite",                 ARB_POINT_SPRITE,               0                           },
73     {"GL_ARB_provoking_vertex",             ARB_PROVOKING_VERTEX,           0                           },
74     {"GL_ARB_shader_objects",               ARB_SHADER_OBJECTS,             0                           },
75     {"GL_ARB_shader_texture_lod",           ARB_SHADER_TEXTURE_LOD,         0                           },
76     {"GL_ARB_shading_language_100",         ARB_SHADING_LANGUAGE_100,       0                           },
77     {"GL_ARB_sync",                         ARB_SYNC,                       0                           },
78     {"GL_ARB_texture_border_clamp",         ARB_TEXTURE_BORDER_CLAMP,       0                           },
79     {"GL_ARB_texture_compression",          ARB_TEXTURE_COMPRESSION,        0                           },
80     {"GL_ARB_texture_cube_map",             ARB_TEXTURE_CUBE_MAP,           0                           },
81     {"GL_ARB_texture_env_add",              ARB_TEXTURE_ENV_ADD,            0                           },
82     {"GL_ARB_texture_env_combine",          ARB_TEXTURE_ENV_COMBINE,        0                           },
83     {"GL_ARB_texture_env_dot3",             ARB_TEXTURE_ENV_DOT3,           0                           },
84     {"GL_ARB_texture_float",                ARB_TEXTURE_FLOAT,              0                           },
85     {"GL_ARB_texture_mirrored_repeat",      ARB_TEXTURE_MIRRORED_REPEAT,    0                           },
86     {"GL_ARB_texture_non_power_of_two",     ARB_TEXTURE_NON_POWER_OF_TWO,   MAKEDWORD_VERSION(2, 0)     },
87     {"GL_ARB_texture_rectangle",            ARB_TEXTURE_RECTANGLE,          0                           },
88     {"GL_ARB_texture_rg",                   ARB_TEXTURE_RG,                 0                           },
89     {"GL_ARB_vertex_array_bgra",            ARB_VERTEX_ARRAY_BGRA,          0                           },
90     {"GL_ARB_vertex_blend",                 ARB_VERTEX_BLEND,               0                           },
91     {"GL_ARB_vertex_buffer_object",         ARB_VERTEX_BUFFER_OBJECT,       0                           },
92     {"GL_ARB_vertex_program",               ARB_VERTEX_PROGRAM,             0                           },
93     {"GL_ARB_vertex_shader",                ARB_VERTEX_SHADER,              0                           },
94
95     /* ATI */
96     {"GL_ATI_fragment_shader",              ATI_FRAGMENT_SHADER,            0                           },
97     {"GL_ATI_separate_stencil",             ATI_SEPARATE_STENCIL,           0                           },
98     {"GL_ATI_texture_compression_3dc",      ATI_TEXTURE_COMPRESSION_3DC,    0                           },
99     {"GL_ATI_texture_env_combine3",         ATI_TEXTURE_ENV_COMBINE3,       0                           },
100     {"GL_ATI_texture_mirror_once",          ATI_TEXTURE_MIRROR_ONCE,        0                           },
101
102     /* EXT */
103     {"GL_EXT_blend_color",                  EXT_BLEND_COLOR,                0                           },
104     {"GL_EXT_blend_equation_separate",      EXT_BLEND_EQUATION_SEPARATE,    0                           },
105     {"GL_EXT_blend_func_separate",          EXT_BLEND_FUNC_SEPARATE,        0                           },
106     {"GL_EXT_blend_minmax",                 EXT_BLEND_MINMAX,               0                           },
107     {"GL_EXT_fog_coord",                    EXT_FOG_COORD,                  0                           },
108     {"GL_EXT_framebuffer_blit",             EXT_FRAMEBUFFER_BLIT,           0                           },
109     {"GL_EXT_framebuffer_multisample",      EXT_FRAMEBUFFER_MULTISAMPLE,    0                           },
110     {"GL_EXT_framebuffer_object",           EXT_FRAMEBUFFER_OBJECT,         0                           },
111     {"GL_EXT_gpu_program_parameters",       EXT_GPU_PROGRAM_PARAMETERS,     0                           },
112     {"GL_EXT_gpu_shader4",                  EXT_GPU_SHADER4,                0                           },
113     {"GL_EXT_packed_depth_stencil",         EXT_PACKED_DEPTH_STENCIL,       0                           },
114     {"GL_EXT_paletted_texture",             EXT_PALETTED_TEXTURE,           0                           },
115     {"GL_EXT_point_parameters",             EXT_POINT_PARAMETERS,           0                           },
116     {"GL_EXT_provoking_vertex",             EXT_PROVOKING_VERTEX,           0                           },
117     {"GL_EXT_secondary_color",              EXT_SECONDARY_COLOR,            0                           },
118     {"GL_EXT_stencil_two_side",             EXT_STENCIL_TWO_SIDE,           0                           },
119     {"GL_EXT_stencil_wrap",                 EXT_STENCIL_WRAP,               0                           },
120     {"GL_EXT_texture3D",                    EXT_TEXTURE3D,                  MAKEDWORD_VERSION(1, 2)     },
121     {"GL_EXT_texture_compression_rgtc",     EXT_TEXTURE_COMPRESSION_RGTC,   0                           },
122     {"GL_EXT_texture_compression_s3tc",     EXT_TEXTURE_COMPRESSION_S3TC,   0                           },
123     {"GL_EXT_texture_env_add",              EXT_TEXTURE_ENV_ADD,            0                           },
124     {"GL_EXT_texture_env_combine",          EXT_TEXTURE_ENV_COMBINE,        0                           },
125     {"GL_EXT_texture_env_dot3",             EXT_TEXTURE_ENV_DOT3,           0                           },
126     {"GL_EXT_texture_filter_anisotropic",   EXT_TEXTURE_FILTER_ANISOTROPIC, 0                           },
127     {"GL_EXT_texture_lod_bias",             EXT_TEXTURE_LOD_BIAS,           0                           },
128     {"GL_EXT_texture_sRGB",                 EXT_TEXTURE_SRGB,               0                           },
129     {"GL_EXT_vertex_array_bgra",            EXT_VERTEX_ARRAY_BGRA,          0                           },
130
131     /* NV */
132     {"GL_NV_depth_clamp",                   NV_DEPTH_CLAMP,                 0                           },
133     {"GL_NV_fence",                         NV_FENCE,                       0                           },
134     {"GL_NV_fog_distance",                  NV_FOG_DISTANCE,                0                           },
135     {"GL_NV_fragment_program",              NV_FRAGMENT_PROGRAM,            0                           },
136     {"GL_NV_fragment_program2",             NV_FRAGMENT_PROGRAM2,           0                           },
137     {"GL_NV_fragment_program_option",       NV_FRAGMENT_PROGRAM_OPTION,     0                           },
138     {"GL_NV_half_float",                    NV_HALF_FLOAT,                  0                           },
139     {"GL_NV_light_max_exponent",            NV_LIGHT_MAX_EXPONENT,          0                           },
140     {"GL_NV_register_combiners",            NV_REGISTER_COMBINERS,          0                           },
141     {"GL_NV_register_combiners2",           NV_REGISTER_COMBINERS2,         0                           },
142     {"GL_NV_texgen_reflection",             NV_TEXGEN_REFLECTION,           0                           },
143     {"GL_NV_texture_env_combine4",          NV_TEXTURE_ENV_COMBINE4,        0                           },
144     {"GL_NV_texture_shader",                NV_TEXTURE_SHADER,              0                           },
145     {"GL_NV_texture_shader2",               NV_TEXTURE_SHADER2,             0                           },
146     {"GL_NV_vertex_program",                NV_VERTEX_PROGRAM,              0                           },
147     {"GL_NV_vertex_program1_1",             NV_VERTEX_PROGRAM1_1,           0                           },
148     {"GL_NV_vertex_program2",               NV_VERTEX_PROGRAM2,             0                           },
149     {"GL_NV_vertex_program2_option",        NV_VERTEX_PROGRAM2_OPTION,      0                           },
150     {"GL_NV_vertex_program3",               NV_VERTEX_PROGRAM3,             0                           },
151
152     /* SGI */
153     {"GL_SGIS_generate_mipmap",             SGIS_GENERATE_MIPMAP,           0                           },
154 };
155
156 /**********************************************************
157  * Utility functions follow
158  **********************************************************/
159
160 static HRESULT WINAPI IWineD3DImpl_CheckDeviceFormat(IWineD3D *iface, UINT Adapter, WINED3DDEVTYPE DeviceType, WINED3DFORMAT AdapterFormat, DWORD Usage, WINED3DRESOURCETYPE RType, WINED3DFORMAT CheckFormat, WINED3DSURFTYPE SurfaceType);
161
162 const struct min_lookup minMipLookup[] =
163 {
164     /* NONE         POINT                       LINEAR */
165     {{GL_NEAREST,   GL_NEAREST,                 GL_NEAREST}},               /* NONE */
166     {{GL_NEAREST,   GL_NEAREST_MIPMAP_NEAREST,  GL_NEAREST_MIPMAP_LINEAR}}, /* POINT*/
167     {{GL_LINEAR,    GL_LINEAR_MIPMAP_NEAREST,   GL_LINEAR_MIPMAP_LINEAR}},  /* LINEAR */
168 };
169
170 const struct min_lookup minMipLookup_noFilter[] =
171 {
172     /* NONE         POINT                       LINEAR */
173     {{GL_NEAREST,   GL_NEAREST,                 GL_NEAREST}},               /* NONE */
174     {{GL_NEAREST,   GL_NEAREST,                 GL_NEAREST}},               /* POINT */
175     {{GL_NEAREST,   GL_NEAREST,                 GL_NEAREST}},               /* LINEAR */
176 };
177
178 const struct min_lookup minMipLookup_noMip[] =
179 {
180     /* NONE         POINT                       LINEAR */
181     {{GL_NEAREST,   GL_NEAREST,                 GL_NEAREST}},               /* NONE */
182     {{GL_NEAREST,   GL_NEAREST,                 GL_NEAREST}},               /* POINT */
183     {{GL_LINEAR,    GL_LINEAR,                  GL_LINEAR }},               /* LINEAR */
184 };
185
186 const GLenum magLookup[] =
187 {
188     /* NONE     POINT       LINEAR */
189     GL_NEAREST, GL_NEAREST, GL_LINEAR,
190 };
191
192 const GLenum magLookup_noFilter[] =
193 {
194     /* NONE     POINT       LINEAR */
195     GL_NEAREST, GL_NEAREST, GL_NEAREST,
196 };
197
198 /* drawStridedSlow attributes */
199 glAttribFunc position_funcs[WINED3D_FFP_EMIT_COUNT];
200 glAttribFunc diffuse_funcs[WINED3D_FFP_EMIT_COUNT];
201 glAttribFunc specular_func_3ubv;
202 glAttribFunc specular_funcs[WINED3D_FFP_EMIT_COUNT];
203 glAttribFunc normal_funcs[WINED3D_FFP_EMIT_COUNT];
204 glMultiTexCoordFunc multi_texcoord_funcs[WINED3D_FFP_EMIT_COUNT];
205
206 /**
207  * Note: GL seems to trap if GetDeviceCaps is called before any HWND's created,
208  * i.e., there is no GL Context - Get a default rendering context to enable the
209  * function query some info from GL.
210  */
211
212 struct wined3d_fake_gl_ctx
213 {
214     HDC dc;
215     HWND wnd;
216     HGLRC gl_ctx;
217     HDC restore_dc;
218     HGLRC restore_gl_ctx;
219 };
220
221 static void WineD3D_ReleaseFakeGLContext(struct wined3d_fake_gl_ctx *ctx)
222 {
223     TRACE_(d3d_caps)("Destroying fake GL context.\n");
224
225     if (!pwglMakeCurrent(NULL, NULL))
226     {
227         ERR_(d3d_caps)("Failed to disable fake GL context.\n");
228     }
229
230     if (!pwglDeleteContext(ctx->gl_ctx))
231     {
232         DWORD err = GetLastError();
233         ERR("wglDeleteContext(%p) failed, last error %#x.\n", ctx->gl_ctx, err);
234     }
235
236     ReleaseDC(ctx->wnd, ctx->dc);
237     DestroyWindow(ctx->wnd);
238
239     if (ctx->restore_gl_ctx && !pwglMakeCurrent(ctx->restore_dc, ctx->restore_gl_ctx))
240     {
241         ERR_(d3d_caps)("Failed to restore previous GL context.\n");
242     }
243 }
244
245 static BOOL WineD3D_CreateFakeGLContext(struct wined3d_fake_gl_ctx *ctx)
246 {
247     PIXELFORMATDESCRIPTOR pfd;
248     int iPixelFormat;
249
250     TRACE("getting context...\n");
251
252     ctx->restore_dc = pwglGetCurrentDC();
253     ctx->restore_gl_ctx = pwglGetCurrentContext();
254
255     /* We need a fake window as a hdc retrieved using GetDC(0) can't be used for much GL purposes. */
256     ctx->wnd = CreateWindowA(WINED3D_OPENGL_WINDOW_CLASS_NAME, "WineD3D fake window",
257             WS_OVERLAPPEDWINDOW, 10, 10, 10, 10, NULL, NULL, NULL, NULL);
258     if (!ctx->wnd)
259     {
260         ERR_(d3d_caps)("Failed to create a window.\n");
261         goto fail;
262     }
263
264     ctx->dc = GetDC(ctx->wnd);
265     if (!ctx->dc)
266     {
267         ERR_(d3d_caps)("Failed to get a DC.\n");
268         goto fail;
269     }
270
271     /* PixelFormat selection */
272     ZeroMemory(&pfd, sizeof(pfd));
273     pfd.nSize = sizeof(pfd);
274     pfd.nVersion = 1;
275     pfd.dwFlags = PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER | PFD_DRAW_TO_WINDOW; /* PFD_GENERIC_ACCELERATED */
276     pfd.iPixelType = PFD_TYPE_RGBA;
277     pfd.cColorBits = 32;
278     pfd.iLayerType = PFD_MAIN_PLANE;
279
280     iPixelFormat = ChoosePixelFormat(ctx->dc, &pfd);
281     if (!iPixelFormat)
282     {
283         /* If this happens something is very wrong as ChoosePixelFormat barely fails. */
284         ERR_(d3d_caps)("Can't find a suitable iPixelFormat.\n");
285         goto fail;
286     }
287     DescribePixelFormat(ctx->dc, iPixelFormat, sizeof(pfd), &pfd);
288     SetPixelFormat(ctx->dc, iPixelFormat, &pfd);
289
290     /* Create a GL context. */
291     ctx->gl_ctx = pwglCreateContext(ctx->dc);
292     if (!ctx->gl_ctx)
293     {
294         WARN_(d3d_caps)("Error creating default context for capabilities initialization.\n");
295         goto fail;
296     }
297
298     /* Make it the current GL context. */
299     if (!context_set_current(NULL))
300     {
301         ERR_(d3d_caps)("Failed to clear current D3D context.\n");
302     }
303
304     if (!pwglMakeCurrent(ctx->dc, ctx->gl_ctx))
305     {
306         ERR_(d3d_caps)("Failed to make fake GL context current.\n");
307         goto fail;
308     }
309
310     return TRUE;
311
312 fail:
313     if (ctx->gl_ctx) pwglDeleteContext(ctx->gl_ctx);
314     ctx->gl_ctx = NULL;
315     if (ctx->dc) ReleaseDC(ctx->wnd, ctx->dc);
316     ctx->dc = NULL;
317     if (ctx->wnd) DestroyWindow(ctx->wnd);
318     ctx->wnd = NULL;
319     if (ctx->restore_gl_ctx && !pwglMakeCurrent(ctx->restore_dc, ctx->restore_gl_ctx))
320     {
321         ERR_(d3d_caps)("Failed to restore previous GL context.\n");
322     }
323
324     return FALSE;
325 }
326
327 /* Adjust the amount of used texture memory */
328 long WineD3DAdapterChangeGLRam(IWineD3DDeviceImpl *D3DDevice, long glram)
329 {
330     struct wined3d_adapter *adapter = D3DDevice->adapter;
331
332     adapter->UsedTextureRam += glram;
333     TRACE("Adjusted gl ram by %ld to %d\n", glram, adapter->UsedTextureRam);
334     return adapter->UsedTextureRam;
335 }
336
337 static void wined3d_adapter_cleanup(struct wined3d_adapter *adapter)
338 {
339     HeapFree(GetProcessHeap(), 0, adapter->gl_info.gl_formats);
340     HeapFree(GetProcessHeap(), 0, adapter->cfgs);
341 }
342
343 /**********************************************************
344  * IUnknown parts follows
345  **********************************************************/
346
347 static HRESULT WINAPI IWineD3DImpl_QueryInterface(IWineD3D *iface,REFIID riid,LPVOID *ppobj)
348 {
349     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
350
351     TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(riid),ppobj);
352     if (IsEqualGUID(riid, &IID_IUnknown)
353         || IsEqualGUID(riid, &IID_IWineD3DBase)
354         || IsEqualGUID(riid, &IID_IWineD3DDevice)) {
355         IUnknown_AddRef(iface);
356         *ppobj = This;
357         return S_OK;
358     }
359     *ppobj = NULL;
360     return E_NOINTERFACE;
361 }
362
363 static ULONG WINAPI IWineD3DImpl_AddRef(IWineD3D *iface) {
364     IWineD3DImpl *This = (IWineD3DImpl *)iface;
365     ULONG refCount = InterlockedIncrement(&This->ref);
366
367     TRACE("(%p) : AddRef increasing from %d\n", This, refCount - 1);
368     return refCount;
369 }
370
371 static ULONG WINAPI IWineD3DImpl_Release(IWineD3D *iface) {
372     IWineD3DImpl *This = (IWineD3DImpl *)iface;
373     ULONG ref;
374     TRACE("(%p) : Releasing from %d\n", This, This->ref);
375     ref = InterlockedDecrement(&This->ref);
376     if (ref == 0) {
377         unsigned int i;
378
379         for (i = 0; i < This->adapter_count; ++i)
380         {
381             wined3d_adapter_cleanup(&This->adapters[i]);
382         }
383         HeapFree(GetProcessHeap(), 0, This);
384     }
385
386     return ref;
387 }
388
389 /**********************************************************
390  * IWineD3D parts follows
391  **********************************************************/
392
393 /* GL locking is done by the caller */
394 static inline BOOL test_arb_vs_offset_limit(const struct wined3d_gl_info *gl_info)
395 {
396     GLuint prog;
397     BOOL ret = FALSE;
398     const char *testcode =
399         "!!ARBvp1.0\n"
400         "PARAM C[66] = { program.env[0..65] };\n"
401         "ADDRESS A0;"
402         "PARAM zero = {0.0, 0.0, 0.0, 0.0};\n"
403         "ARL A0.x, zero.x;\n"
404         "MOV result.position, C[A0.x + 65];\n"
405         "END\n";
406
407     while(glGetError());
408     GL_EXTCALL(glGenProgramsARB(1, &prog));
409     if(!prog) {
410         ERR("Failed to create an ARB offset limit test program\n");
411     }
412     GL_EXTCALL(glBindProgramARB(GL_VERTEX_PROGRAM_ARB, prog));
413     GL_EXTCALL(glProgramStringARB(GL_VERTEX_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB,
414                                   strlen(testcode), testcode));
415     if(glGetError() != 0) {
416         TRACE("OpenGL implementation does not allow indirect addressing offsets > 63\n");
417         TRACE("error: %s\n", debugstr_a((const char *)glGetString(GL_PROGRAM_ERROR_STRING_ARB)));
418         ret = TRUE;
419     } else TRACE("OpenGL implementation allows offsets > 63\n");
420
421     GL_EXTCALL(glBindProgramARB(GL_VERTEX_PROGRAM_ARB, 0));
422     GL_EXTCALL(glDeleteProgramsARB(1, &prog));
423     checkGLcall("ARB vp offset limit test cleanup");
424
425     return ret;
426 }
427
428 static DWORD ver_for_ext(GL_SupportedExt ext)
429 {
430     unsigned int i;
431     for (i = 0; i < (sizeof(EXTENSION_MAP) / sizeof(*EXTENSION_MAP)); ++i) {
432         if(EXTENSION_MAP[i].extension == ext) {
433             return EXTENSION_MAP[i].version;
434         }
435     }
436     return 0;
437 }
438
439 static BOOL match_ati_r300_to_500(const struct wined3d_gl_info *gl_info, const char *gl_renderer,
440         enum wined3d_gl_vendor gl_vendor, enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device)
441 {
442     if (card_vendor != HW_VENDOR_ATI) return FALSE;
443     if (device == CARD_ATI_RADEON_9500) return TRUE;
444     if (device == CARD_ATI_RADEON_X700) return TRUE;
445     if (device == CARD_ATI_RADEON_X1600) return TRUE;
446     return FALSE;
447 }
448
449 static BOOL match_geforce5(const struct wined3d_gl_info *gl_info, const char *gl_renderer,
450         enum wined3d_gl_vendor gl_vendor, enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device)
451 {
452     if (card_vendor == HW_VENDOR_NVIDIA)
453     {
454         if (device == CARD_NVIDIA_GEFORCEFX_5800 || device == CARD_NVIDIA_GEFORCEFX_5600)
455         {
456             return TRUE;
457         }
458     }
459     return FALSE;
460 }
461
462 static BOOL match_apple(const struct wined3d_gl_info *gl_info, const char *gl_renderer,
463         enum wined3d_gl_vendor gl_vendor, enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device)
464 {
465     /* MacOS has various specialities in the extensions it advertises. Some have to be loaded from
466      * the opengl 1.2+ core, while other extensions are advertised, but software emulated. So try to
467      * detect the Apple OpenGL implementation to apply some extension fixups afterwards.
468      *
469      * Detecting this isn't really easy. The vendor string doesn't mention Apple. Compile-time checks
470      * aren't sufficient either because a Linux binary may display on a macos X server via remote X11.
471      * So try to detect the GL implementation by looking at certain Apple extensions. Some extensions
472      * like client storage might be supported on other implementations too, but GL_APPLE_flush_render
473      * is specific to the Mac OS X window management, and GL_APPLE_ycbcr_422 is QuickTime specific. So
474      * the chance that other implementations support them is rather small since Win32 QuickTime uses
475      * DirectDraw, not OpenGL.
476      *
477      * This test has been moved into wined3d_guess_gl_vendor()
478      */
479     if (gl_vendor == GL_VENDOR_APPLE)
480     {
481         return TRUE;
482     }
483     return FALSE;
484 }
485
486 /* Context activation is done by the caller. */
487 static void test_pbo_functionality(struct wined3d_gl_info *gl_info)
488 {
489     /* Some OpenGL implementations, namely Apple's Geforce 8 driver, advertises PBOs,
490      * but glTexSubImage from a PBO fails miserably, with the first line repeated over
491      * all the texture. This function detects this bug by its symptom and disables PBOs
492      * if the test fails.
493      *
494      * The test uploads a 4x4 texture via the PBO in the "native" format GL_BGRA,
495      * GL_UNSIGNED_INT_8_8_8_8_REV. This format triggers the bug, and it is what we use
496      * for D3DFMT_A8R8G8B8. Then the texture is read back without any PBO and the data
497      * read back is compared to the original. If they are equal PBOs are assumed to work,
498      * otherwise the PBO extension is disabled. */
499     GLuint texture, pbo;
500     static const unsigned int pattern[] =
501     {
502         0x00000000, 0x000000ff, 0x0000ff00, 0x40ff0000,
503         0x80ffffff, 0x40ffff00, 0x00ff00ff, 0x0000ffff,
504         0x00ffff00, 0x00ff00ff, 0x0000ffff, 0x000000ff,
505         0x80ff00ff, 0x0000ffff, 0x00ff00ff, 0x40ff00ff
506     };
507     unsigned int check[sizeof(pattern) / sizeof(pattern[0])];
508
509     /* No PBO -> No point in testing them. */
510     if (!gl_info->supported[ARB_PIXEL_BUFFER_OBJECT]) return;
511
512     ENTER_GL();
513
514     while (glGetError());
515     glGenTextures(1, &texture);
516     glBindTexture(GL_TEXTURE_2D, texture);
517
518     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
519     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 4, 4, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, 0);
520     checkGLcall("Specifying the PBO test texture");
521
522     GL_EXTCALL(glGenBuffersARB(1, &pbo));
523     GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, pbo));
524     GL_EXTCALL(glBufferDataARB(GL_PIXEL_UNPACK_BUFFER_ARB, sizeof(pattern), pattern, GL_STREAM_DRAW_ARB));
525     checkGLcall("Specifying the PBO test pbo");
526
527     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 4, 4, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL);
528     checkGLcall("Loading the PBO test texture");
529
530     GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0));
531     wglFinish(); /* just to be sure */
532
533     memset(check, 0, sizeof(check));
534     glGetTexImage(GL_TEXTURE_2D, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, check);
535     checkGLcall("Reading back the PBO test texture");
536
537     glDeleteTextures(1, &texture);
538     GL_EXTCALL(glDeleteBuffersARB(1, &pbo));
539     checkGLcall("PBO test cleanup");
540
541     LEAVE_GL();
542
543     if (memcmp(check, pattern, sizeof(check)))
544     {
545         WARN_(d3d_caps)("PBO test failed, read back data doesn't match original.\n");
546         WARN_(d3d_caps)("Disabling PBOs. This may result in slower performance.\n");
547         gl_info->supported[ARB_PIXEL_BUFFER_OBJECT] = FALSE;
548     }
549     else
550     {
551         TRACE_(d3d_caps)("PBO test successful.\n");
552     }
553 }
554
555 static BOOL match_apple_intel(const struct wined3d_gl_info *gl_info, const char *gl_renderer,
556         enum wined3d_gl_vendor gl_vendor, enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device)
557 {
558     return (card_vendor == HW_VENDOR_INTEL) && (gl_vendor == GL_VENDOR_APPLE);
559 }
560
561 static BOOL match_apple_nonr500ati(const struct wined3d_gl_info *gl_info, const char *gl_renderer,
562         enum wined3d_gl_vendor gl_vendor, enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device)
563 {
564     if (gl_vendor != GL_VENDOR_APPLE) return FALSE;
565     if (card_vendor != HW_VENDOR_ATI) return FALSE;
566     if (device == CARD_ATI_RADEON_X1600) return FALSE;
567     return TRUE;
568 }
569
570 static BOOL match_fglrx(const struct wined3d_gl_info *gl_info, const char *gl_renderer,
571         enum wined3d_gl_vendor gl_vendor, enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device)
572 {
573     return (gl_vendor == GL_VENDOR_ATI);
574
575 }
576
577 static BOOL match_dx10_capable(const struct wined3d_gl_info *gl_info, const char *gl_renderer,
578         enum wined3d_gl_vendor gl_vendor, enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device)
579 {
580     /* DX9 cards support 40 single float varyings in hardware, most drivers report 32. ATI misreports
581      * 44 varyings. So assume that if we have more than 44 varyings we have a dx10 card.
582      * This detection is for the gl_ClipPos varying quirk. If a d3d9 card really supports more than 44
583      * varyings and we subtract one in dx9 shaders its not going to hurt us because the dx9 limit is
584      * hardcoded
585      *
586      * dx10 cards usually have 64 varyings */
587     return gl_info->limits.glsl_varyings > 44;
588 }
589
590 /* A GL context is provided by the caller */
591 static BOOL match_allows_spec_alpha(const struct wined3d_gl_info *gl_info, const char *gl_renderer,
592         enum wined3d_gl_vendor gl_vendor, enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device)
593 {
594     GLenum error;
595     DWORD data[16];
596
597     if (!gl_info->supported[EXT_SECONDARY_COLOR]) return FALSE;
598
599     ENTER_GL();
600     while(glGetError());
601     GL_EXTCALL(glSecondaryColorPointerEXT)(4, GL_UNSIGNED_BYTE, 4, data);
602     error = glGetError();
603     LEAVE_GL();
604
605     if(error == GL_NO_ERROR)
606     {
607         TRACE("GL Implementation accepts 4 component specular color pointers\n");
608         return TRUE;
609     }
610     else
611     {
612         TRACE("GL implementation does not accept 4 component specular colors, error %s\n",
613               debug_glerror(error));
614         return FALSE;
615     }
616 }
617
618 static BOOL match_apple_nvts(const struct wined3d_gl_info *gl_info, const char *gl_renderer,
619         enum wined3d_gl_vendor gl_vendor, enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device)
620 {
621     if (!match_apple(gl_info, gl_renderer, gl_vendor, card_vendor, device)) return FALSE;
622     return gl_info->supported[NV_TEXTURE_SHADER];
623 }
624
625 /* A GL context is provided by the caller */
626 static BOOL match_broken_nv_clip(const struct wined3d_gl_info *gl_info, const char *gl_renderer,
627         enum wined3d_gl_vendor gl_vendor, enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device)
628 {
629     GLuint prog;
630     BOOL ret = FALSE;
631     GLint pos;
632     const char *testcode =
633         "!!ARBvp1.0\n"
634         "OPTION NV_vertex_program2;\n"
635         "MOV result.clip[0], 0.0;\n"
636         "MOV result.position, 0.0;\n"
637         "END\n";
638
639     if (!gl_info->supported[NV_VERTEX_PROGRAM2_OPTION]) return FALSE;
640
641     ENTER_GL();
642     while(glGetError());
643
644     GL_EXTCALL(glGenProgramsARB(1, &prog));
645     if(!prog)
646     {
647         ERR("Failed to create the NVvp clip test program\n");
648         LEAVE_GL();
649         return FALSE;
650     }
651     GL_EXTCALL(glBindProgramARB(GL_VERTEX_PROGRAM_ARB, prog));
652     GL_EXTCALL(glProgramStringARB(GL_VERTEX_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB,
653                                   strlen(testcode), testcode));
654     glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB, &pos);
655     if(pos != -1)
656     {
657         WARN("GL_NV_vertex_program2_option result.clip[] test failed\n");
658         TRACE("error: %s\n", debugstr_a((const char *)glGetString(GL_PROGRAM_ERROR_STRING_ARB)));
659         ret = TRUE;
660         while(glGetError());
661     }
662     else TRACE("GL_NV_vertex_program2_option result.clip[] test passed\n");
663
664     GL_EXTCALL(glBindProgramARB(GL_VERTEX_PROGRAM_ARB, 0));
665     GL_EXTCALL(glDeleteProgramsARB(1, &prog));
666     checkGLcall("GL_NV_vertex_program2_option result.clip[] test cleanup");
667
668     LEAVE_GL();
669     return ret;
670 }
671
672 static BOOL match_fbo_tex_update(const struct wined3d_gl_info *gl_info, const char *gl_renderer,
673         enum wined3d_gl_vendor gl_vendor, enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device)
674 {
675     char data[4 * 4 * 4];
676     GLuint tex, fbo;
677     GLenum status;
678
679     if (wined3d_settings.offscreen_rendering_mode != ORM_FBO) return FALSE;
680
681     memset(data, 0xcc, sizeof(data));
682
683     glGenTextures(1, &tex);
684     glBindTexture(GL_TEXTURE_2D, tex);
685     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
686     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
687     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 4, 4, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL);
688     checkGLcall("glTexImage2D");
689
690     gl_info->fbo_ops.glGenFramebuffers(1, &fbo);
691     gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, fbo);
692     gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
693     checkGLcall("glFramebufferTexture2D");
694
695     status = gl_info->fbo_ops.glCheckFramebufferStatus(GL_FRAMEBUFFER);
696     if (status != GL_FRAMEBUFFER_COMPLETE) ERR("FBO status %#x\n", status);
697     checkGLcall("glCheckFramebufferStatus");
698
699     memset(data, 0x11, sizeof(data));
700     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 4, 4, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, data);
701     checkGLcall("glTexSubImage2D");
702
703     glClearColor(0.996, 0.729, 0.745, 0.792);
704     glClear(GL_COLOR_BUFFER_BIT);
705     checkGLcall("glClear");
706
707     glGetTexImage(GL_TEXTURE_2D, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, data);
708     checkGLcall("glGetTexImage");
709
710     gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
711     gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, 0);
712     glBindTexture(GL_TEXTURE_2D, 0);
713     checkGLcall("glBindTexture");
714
715     gl_info->fbo_ops.glDeleteFramebuffers(1, &fbo);
716     glDeleteTextures(1, &tex);
717     checkGLcall("glDeleteTextures");
718
719     return *(DWORD *)data == 0x11111111;
720 }
721
722 static void quirk_arb_constants(struct wined3d_gl_info *gl_info)
723 {
724     TRACE_(d3d_caps)("Using ARB vs constant limit(=%u) for GLSL.\n", gl_info->limits.arb_vs_native_constants);
725     gl_info->limits.glsl_vs_float_constants = gl_info->limits.arb_vs_native_constants;
726     TRACE_(d3d_caps)("Using ARB ps constant limit(=%u) for GLSL.\n", gl_info->limits.arb_ps_native_constants);
727     gl_info->limits.glsl_ps_float_constants = gl_info->limits.arb_ps_native_constants;
728 }
729
730 static void quirk_apple_glsl_constants(struct wined3d_gl_info *gl_info)
731 {
732     quirk_arb_constants(gl_info);
733     /* MacOS needs uniforms for relative addressing offsets. This can accumulate to quite a few uniforms.
734      * Beyond that the general uniform isn't optimal, so reserve a number of uniforms. 12 vec4's should
735      * allow 48 different offsets or other helper immediate values. */
736     TRACE_(d3d_caps)("Reserving 12 GLSL constants for compiler private use.\n");
737     gl_info->reserved_glsl_constants = max(gl_info->reserved_glsl_constants, 12);
738 }
739
740 /* fglrx crashes with a very bad kernel panic if GL_POINT_SPRITE_ARB is set to GL_COORD_REPLACE_ARB
741  * on more than one texture unit. This means that the d3d9 visual point size test will cause a
742  * kernel panic on any machine running fglrx 9.3(latest that supports r300 to r500 cards). This
743  * quirk only enables point sprites on the first texture unit. This keeps point sprites working in
744  * most games, but avoids the crash
745  *
746  * A more sophisticated way would be to find all units that need texture coordinates and enable
747  * point sprites for one if only one is found, and software emulate point sprites in drawStridedSlow
748  * if more than one unit needs texture coordinates(This requires software ffp and vertex shaders though)
749  *
750  * Note that disabling the extension entirely does not gain predictability because there is no point
751  * sprite capability flag in d3d, so the potential rendering bugs are the same if we disable the extension. */
752 static void quirk_one_point_sprite(struct wined3d_gl_info *gl_info)
753 {
754     if (gl_info->supported[ARB_POINT_SPRITE])
755     {
756         TRACE("Limiting point sprites to one texture unit.\n");
757         gl_info->limits.point_sprite_units = 1;
758     }
759 }
760
761 static void quirk_ati_dx9(struct wined3d_gl_info *gl_info)
762 {
763     quirk_arb_constants(gl_info);
764
765     /* MacOS advertises GL_ARB_texture_non_power_of_two on ATI r500 and earlier cards, although
766      * these cards only support GL_ARB_texture_rectangle(D3DPTEXTURECAPS_NONPOW2CONDITIONAL).
767      * If real NP2 textures are used, the driver falls back to software. We could just remove the
768      * extension and use GL_ARB_texture_rectangle instead, but texture_rectangle is inconventient
769      * due to the non-normalized texture coordinates. Thus set an internal extension flag,
770      * GL_WINE_normalized_texrect, which signals the code that it can use non power of two textures
771      * as per GL_ARB_texture_non_power_of_two, but has to stick to the texture_rectangle limits.
772      *
773      * fglrx doesn't advertise GL_ARB_texture_non_power_of_two, but it advertises opengl 2.0 which
774      * has this extension promoted to core. The extension loading code sets this extension supported
775      * due to that, so this code works on fglrx as well. */
776     if(gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO])
777     {
778         TRACE("GL_ARB_texture_non_power_of_two advertised on R500 or earlier card, removing.\n");
779         gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO] = FALSE;
780         gl_info->supported[WINE_NORMALIZED_TEXRECT] = TRUE;
781     }
782
783     /* fglrx has the same structural issues as the one described in quirk_apple_glsl_constants, although
784      * it is generally more efficient. Reserve just 8 constants. */
785     TRACE_(d3d_caps)("Reserving 8 GLSL constants for compiler private use.\n");
786     gl_info->reserved_glsl_constants = max(gl_info->reserved_glsl_constants, 8);
787 }
788
789 static void quirk_no_np2(struct wined3d_gl_info *gl_info)
790 {
791     /*  The nVidia GeForceFX series reports OpenGL 2.0 capabilities with the latest drivers versions, but
792      *  doesn't explicitly advertise the ARB_tex_npot extension in the GL extension string.
793      *  This usually means that ARB_tex_npot is supported in hardware as long as the application is staying
794      *  within the limits enforced by the ARB_texture_rectangle extension. This however is not true for the
795      *  FX series, which instantly falls back to a slower software path as soon as ARB_tex_npot is used.
796      *  We therefore completely remove ARB_tex_npot from the list of supported extensions.
797      *
798      *  Note that wine_normalized_texrect can't be used in this case because internally it uses ARB_tex_npot,
799      *  triggering the software fallback. There is not much we can do here apart from disabling the
800      *  software-emulated extension and reenable ARB_tex_rect (which was previously disabled
801      *  in IWineD3DImpl_FillGLCaps).
802      *  This fixup removes performance problems on both the FX 5900 and FX 5700 (e.g. for framebuffer
803      *  post-processing effects in the game "Max Payne 2").
804      *  The behaviour can be verified through a simple test app attached in bugreport #14724. */
805     TRACE("GL_ARB_texture_non_power_of_two advertised through OpenGL 2.0 on NV FX card, removing.\n");
806     gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO] = FALSE;
807     gl_info->supported[ARB_TEXTURE_RECTANGLE] = TRUE;
808 }
809
810 static void quirk_texcoord_w(struct wined3d_gl_info *gl_info)
811 {
812     /* The Intel GPUs on MacOS set the .w register of texcoords to 0.0 by default, which causes problems
813      * with fixed function fragment processing. Ideally this flag should be detected with a test shader
814      * and OpenGL feedback mode, but some GL implementations (MacOS ATI at least, probably all MacOS ones)
815      * do not like vertex shaders in feedback mode and return an error, even though it should be valid
816      * according to the spec.
817      *
818      * We don't want to enable this on all cards, as it adds an extra instruction per texcoord used. This
819      * makes the shader slower and eats instruction slots which should be available to the d3d app.
820      *
821      * ATI Radeon HD 2xxx cards on MacOS have the issue. Instead of checking for the buggy cards, blacklist
822      * all radeon cards on Macs and whitelist the good ones. That way we're prepared for the future. If
823      * this workaround is activated on cards that do not need it, it won't break things, just affect
824      * performance negatively. */
825     TRACE("Enabling vertex texture coord fixes in vertex shaders.\n");
826     gl_info->quirks |= WINED3D_QUIRK_SET_TEXCOORD_W;
827 }
828
829 static void quirk_clip_varying(struct wined3d_gl_info *gl_info)
830 {
831     gl_info->quirks |= WINED3D_QUIRK_GLSL_CLIP_VARYING;
832 }
833
834 static void quirk_allows_specular_alpha(struct wined3d_gl_info *gl_info)
835 {
836     gl_info->quirks |= WINED3D_QUIRK_ALLOWS_SPECULAR_ALPHA;
837 }
838
839 static void quirk_apple_nvts(struct wined3d_gl_info *gl_info)
840 {
841     gl_info->supported[NV_TEXTURE_SHADER] = FALSE;
842     gl_info->supported[NV_TEXTURE_SHADER2] = FALSE;
843 }
844
845 static void quirk_disable_nvvp_clip(struct wined3d_gl_info *gl_info)
846 {
847     gl_info->quirks |= WINED3D_QUIRK_NV_CLIP_BROKEN;
848 }
849
850 static void quirk_fbo_tex_update(struct wined3d_gl_info *gl_info)
851 {
852     gl_info->quirks |= WINED3D_QUIRK_FBO_TEX_UPDATE;
853 }
854
855 struct driver_quirk
856 {
857     BOOL (*match)(const struct wined3d_gl_info *gl_info, const char *gl_renderer,
858             enum wined3d_gl_vendor gl_vendor, enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device);
859     void (*apply)(struct wined3d_gl_info *gl_info);
860     const char *description;
861 };
862
863 static const struct driver_quirk quirk_table[] =
864 {
865     {
866         match_ati_r300_to_500,
867         quirk_ati_dx9,
868         "ATI GLSL constant and normalized texrect quirk"
869     },
870     /* MacOS advertises more GLSL vertex shader uniforms than supported by the hardware, and if more are
871      * used it falls back to software. While the compiler can detect if the shader uses all declared
872      * uniforms, the optimization fails if the shader uses relative addressing. So any GLSL shader
873      * using relative addressing falls back to software.
874      *
875      * ARB vp gives the correct amount of uniforms, so use it instead of GLSL. */
876     {
877         match_apple,
878         quirk_apple_glsl_constants,
879         "Apple GLSL uniform override"
880     },
881     {
882         match_geforce5,
883         quirk_no_np2,
884         "Geforce 5 NP2 disable"
885     },
886     {
887         match_apple_intel,
888         quirk_texcoord_w,
889         "Init texcoord .w for Apple Intel GPU driver"
890     },
891     {
892         match_apple_nonr500ati,
893         quirk_texcoord_w,
894         "Init texcoord .w for Apple ATI >= r600 GPU driver"
895     },
896     {
897         match_fglrx,
898         quirk_one_point_sprite,
899         "Fglrx point sprite crash workaround"
900     },
901     {
902         match_dx10_capable,
903         quirk_clip_varying,
904         "Reserved varying for gl_ClipPos"
905     },
906     {
907         /* GL_EXT_secondary_color does not allow 4 component secondary colors, but most
908          * GL implementations accept it. The Mac GL is the only implementation known to
909          * reject it.
910          *
911          * If we can pass 4 component specular colors, do it, because (a) we don't have
912          * to screw around with the data, and (b) the D3D fixed function vertex pipeline
913          * passes specular alpha to the pixel shader if any is used. Otherwise the
914          * specular alpha is used to pass the fog coordinate, which we pass to opengl
915          * via GL_EXT_fog_coord.
916          */
917         match_allows_spec_alpha,
918         quirk_allows_specular_alpha,
919         "Allow specular alpha quirk"
920     },
921     {
922         /* The pixel formats provided by GL_NV_texture_shader are broken on OSX
923          * (rdar://5682521).
924          */
925         match_apple_nvts,
926         quirk_apple_nvts,
927         "Apple NV_texture_shader disable"
928     },
929     {
930         match_broken_nv_clip,
931         quirk_disable_nvvp_clip,
932         "Apple NV_vertex_program clip bug quirk"
933     },
934     {
935         match_fbo_tex_update,
936         quirk_fbo_tex_update,
937         "FBO rebind for attachment updates"
938     },
939 };
940
941 /* Certain applications (Steam) complain if we report an outdated driver version. In general,
942  * reporting a driver version is moot because we are not the Windows driver, and we have different
943  * bugs, features, etc.
944  *
945  * The driver version has the form "x.y.z.w".
946  *
947  * "x" is the Windows version the driver is meant for:
948  * 4 -> 95/98/NT4
949  * 5 -> 2000
950  * 6 -> 2000/XP
951  * 7 -> Vista
952  * 8 -> Win 7
953  *
954  * "y" is the Direct3D level the driver supports:
955  * 11 -> d3d6
956  * 12 -> d3d7
957  * 13 -> d3d8
958  * 14 -> d3d9
959  * 15 -> d3d10
960  *
961  * "z" is unknown, possibly vendor specific.
962  *
963  * "w" is the vendor specific driver version.
964  */
965 struct driver_version_information
966 {
967     WORD vendor;                    /* reported PCI card vendor ID  */
968     WORD card;                      /* reported PCI card device ID  */
969     const char *description;        /* Description of the card e.g. NVIDIA RIVA TNT */
970     WORD d3d_level;                 /* driver hiword to report      */
971     WORD lopart_hi, lopart_lo;      /* driver loword to report      */
972 };
973
974 static const struct driver_version_information driver_version_table[] =
975 {
976     /* Nvidia drivers. Geforce6 and newer cards are supported by the current driver (180.x)
977      * GeforceFX support is up to 173.x, - driver uses numbering x.y.11.7341 for 173.41 where x is the windows revision (6=2000/xp, 7=vista), y is unknown
978      * Geforce2MX/3/4 up to 96.x - driver uses numbering 9.6.8.9 for 96.89
979      * TNT/Geforce1/2 up to 71.x - driver uses numbering 7.1.8.6 for 71.86
980      *
981      * All version numbers used below are from the Linux nvidia drivers. */
982     {HW_VENDOR_NVIDIA,     CARD_NVIDIA_RIVA_TNT,           "NVIDIA RIVA TNT",                  1,  8,  6      },
983     {HW_VENDOR_NVIDIA,     CARD_NVIDIA_RIVA_TNT2,          "NVIDIA RIVA TNT2/TNT2 Pro",        1,  8,  6      },
984     {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE,            "NVIDIA GeForce 256",               1,  8,  6      },
985     {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE2_MX,        "NVIDIA GeForce2 MX/MX 400",        6,  4,  3      },
986     {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE2,           "NVIDIA GeForce2 GTS/GeForce2 Pro", 1,  8,  6      },
987     {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE3,           "NVIDIA GeForce3",                  6,  10, 9371   },
988     {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE4_MX,        "NVIDIA GeForce4 MX 460",           6,  10, 9371   },
989     {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE4_TI4200,    "NVIDIA GeForce4 Ti 4200",          6,  10, 9371   },
990     {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCEFX_5200,     "NVIDIA GeForce FX 5200",           15, 11, 7516   },
991     {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCEFX_5600,     "NVIDIA GeForce FX 5600",           15, 11, 7516   },
992     {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCEFX_5800,     "NVIDIA GeForce FX 5800",           15, 11, 7516   },
993     {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_6200,       "NVIDIA GeForce 6200",              15, 11, 8618   },
994     {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_6600GT,     "NVIDIA GeForce 6600 GT",           15, 11, 8618   },
995     {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_6800,       "NVIDIA GeForce 6800",              15, 11, 8618   },
996     {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_7300,       "NVIDIA GeForce Go 7300",           15, 11, 8585   },
997     {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_7400,       "NVIDIA GeForce Go 7400",           15, 11, 8585   },
998     {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_7600,       "NVIDIA GeForce 7600 GT",           15, 11, 8618   },
999     {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_7800GT,     "NVIDIA GeForce 7800 GT",           15, 11, 8618   },
1000     {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_8300GS,     "NVIDIA GeForce 8300 GS",           15, 11, 8618   },
1001     {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_8600GT,     "NVIDIA GeForce 8600 GT",           15, 11, 8618   },
1002     {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_8600MGT,    "NVIDIA GeForce 8600M GT",          15, 11, 8585   },
1003     {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_8800GTS,    "NVIDIA GeForce 8800 GTS",          15, 11, 8618   },
1004     {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_9200,       "NVIDIA GeForce 9200",              15, 11, 8618   },
1005     {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_9400GT,     "NVIDIA GeForce 9400 GT",           15, 11, 8618   },
1006     {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_9500GT,     "NVIDIA GeForce 9500 GT",           15, 11, 8618   },
1007     {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_9600GT,     "NVIDIA GeForce 9600 GT",           15, 11, 8618   },
1008     {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_9800GT,     "NVIDIA GeForce 9800 GT",           15, 11, 8618   },
1009     {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX260,     "NVIDIA GeForce GTX 260",           15, 11, 8618   },
1010     {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX275,     "NVIDIA GeForce GTX 275",           15, 11, 8618   },
1011     {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX280,     "NVIDIA GeForce GTX 280",           15, 11, 8618   },
1012     {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GT240,      "NVIDIA GeForce GT 240",            15, 11, 8618   },
1013
1014     /* ATI cards. The driver versions are somewhat similar, but not quite the same. Let's hardcode. */
1015     {HW_VENDOR_ATI,        CARD_ATI_RADEON_9500,           "ATI Radeon 9500",                  14, 10, 6764    },
1016     {HW_VENDOR_ATI,        CARD_ATI_RADEON_X700,           "ATI Radeon X700 SE",               14, 10, 6764    },
1017     {HW_VENDOR_ATI,        CARD_ATI_RADEON_X1600,          "ATI Radeon X1600 Series",          14, 10, 6764    },
1018     {HW_VENDOR_ATI,        CARD_ATI_RADEON_HD2300,         "ATI Mobility Radeon HD 2300",      14, 10, 6764    },
1019     {HW_VENDOR_ATI,        CARD_ATI_RADEON_HD2600,         "ATI Mobility Radeon HD 2600",      14, 10, 6764    },
1020     {HW_VENDOR_ATI,        CARD_ATI_RADEON_HD2900,         "ATI Radeon HD 2900 XT",            14, 10, 6764    },
1021     {HW_VENDOR_ATI,        CARD_ATI_RADEON_HD4350,         "ATI Radeon HD 4350",               14, 10, 6764    },
1022     {HW_VENDOR_ATI,        CARD_ATI_RADEON_HD4600,         "ATI Radeon HD 4600 Series",        14, 10, 6764    },
1023     {HW_VENDOR_ATI,        CARD_ATI_RADEON_HD4700,         "ATI Radeon HD 4700 Series",        14, 10, 6764    },
1024     {HW_VENDOR_ATI,        CARD_ATI_RADEON_HD4800,         "ATI Radeon HD 4800 Series",        14, 10, 6764    },
1025     {HW_VENDOR_ATI,        CARD_ATI_RADEON_HD5700,         "ATI Radeon HD 5700 Series",        14, 10, 8681    },
1026     {HW_VENDOR_ATI,        CARD_ATI_RADEON_HD5800,         "ATI Radeon HD 5800 Series",        14, 10, 8681    },
1027
1028     /* TODO: Add information about legacy ATI hardware, Intel and other cards. */
1029 };
1030
1031 static void init_driver_info(struct wined3d_driver_info *driver_info,
1032         enum wined3d_pci_vendor vendor, enum wined3d_pci_device device)
1033 {
1034     OSVERSIONINFOW os_version;
1035     WORD driver_os_version;
1036     unsigned int i;
1037
1038     if (wined3d_settings.pci_vendor_id != PCI_VENDOR_NONE)
1039     {
1040         TRACE_(d3d_caps)("Overriding PCI vendor ID with: %04x\n", wined3d_settings.pci_vendor_id);
1041         vendor = wined3d_settings.pci_vendor_id;
1042     }
1043     driver_info->vendor = vendor;
1044
1045     if (wined3d_settings.pci_device_id != PCI_DEVICE_NONE)
1046     {
1047         TRACE_(d3d_caps)("Overriding PCI device ID with: %04x\n", wined3d_settings.pci_device_id);
1048         device = wined3d_settings.pci_device_id;
1049     }
1050     driver_info->device = device;
1051
1052     switch (vendor)
1053     {
1054         case HW_VENDOR_ATI:
1055             driver_info->name = "ati2dvag.dll";
1056             break;
1057
1058         case HW_VENDOR_NVIDIA:
1059             driver_info->name = "nv4_disp.dll";
1060             break;
1061
1062         case HW_VENDOR_INTEL:
1063         default:
1064             FIXME_(d3d_caps)("Unhandled vendor %04x.\n", vendor);
1065             driver_info->name = "Display";
1066             break;
1067     }
1068
1069     memset(&os_version, 0, sizeof(os_version));
1070     os_version.dwOSVersionInfoSize = sizeof(os_version);
1071     if (!GetVersionExW(&os_version))
1072     {
1073         ERR("Failed to get OS version, reporting 2000/XP.\n");
1074         driver_os_version = 6;
1075     }
1076     else
1077     {
1078         TRACE("OS version %u.%u.\n", os_version.dwMajorVersion, os_version.dwMinorVersion);
1079         switch (os_version.dwMajorVersion)
1080         {
1081             case 4:
1082                 driver_os_version = 4;
1083                 break;
1084
1085             case 5:
1086                 driver_os_version = 6;
1087                 break;
1088
1089             case 6:
1090                 if (os_version.dwMinorVersion == 0)
1091                 {
1092                     driver_os_version = 7;
1093                 }
1094                 else
1095                 {
1096                     if (os_version.dwMinorVersion > 1)
1097                     {
1098                         FIXME("Unhandled OS version %u.%u, reporting Win 7.\n",
1099                                 os_version.dwMajorVersion, os_version.dwMinorVersion);
1100                     }
1101                     driver_os_version = 8;
1102                 }
1103                 break;
1104
1105             default:
1106                 FIXME("Unhandled OS version %u.%u, reporting 2000/XP.\n",
1107                         os_version.dwMajorVersion, os_version.dwMinorVersion);
1108                 driver_os_version = 6;
1109                 break;
1110         }
1111     }
1112
1113     driver_info->description = "Direct3D HAL";
1114     driver_info->version_high = MAKEDWORD_VERSION(driver_os_version, 15);
1115     driver_info->version_low = MAKEDWORD_VERSION(8, 6); /* Nvidia RIVA TNT, arbitrary */
1116
1117     for (i = 0; i < (sizeof(driver_version_table) / sizeof(driver_version_table[0])); ++i)
1118     {
1119         if (vendor == driver_version_table[i].vendor && device == driver_version_table[i].card)
1120         {
1121             TRACE_(d3d_caps)("Found card %04x:%04x in driver DB.\n", vendor, device);
1122
1123             driver_info->description = driver_version_table[i].description;
1124             driver_info->version_high = MAKEDWORD_VERSION(driver_os_version, driver_version_table[i].d3d_level);
1125             driver_info->version_low = MAKEDWORD_VERSION(driver_version_table[i].lopart_hi,
1126                     driver_version_table[i].lopart_lo);
1127             break;
1128         }
1129     }
1130
1131     TRACE_(d3d_caps)("Reporting (fake) driver version 0x%08x-0x%08x.\n",
1132             driver_info->version_high, driver_info->version_low);
1133 }
1134
1135 /* Context activation is done by the caller. */
1136 static void fixup_extensions(struct wined3d_gl_info *gl_info, const char *gl_renderer,
1137         enum wined3d_gl_vendor gl_vendor, enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device)
1138 {
1139     unsigned int i;
1140
1141     for (i = 0; i < (sizeof(quirk_table) / sizeof(*quirk_table)); ++i)
1142     {
1143         if (!quirk_table[i].match(gl_info, gl_renderer, gl_vendor, card_vendor, device)) continue;
1144         TRACE_(d3d_caps)("Applying driver quirk \"%s\".\n", quirk_table[i].description);
1145         quirk_table[i].apply(gl_info);
1146     }
1147
1148     /* Find out if PBOs work as they are supposed to. */
1149     test_pbo_functionality(gl_info);
1150 }
1151
1152 static DWORD wined3d_parse_gl_version(const char *gl_version)
1153 {
1154     const char *ptr = gl_version;
1155     int major, minor;
1156
1157     major = atoi(ptr);
1158     if (major <= 0) ERR_(d3d_caps)("Invalid opengl major version: %d.\n", major);
1159
1160     while (isdigit(*ptr)) ++ptr;
1161     if (*ptr++ != '.') ERR_(d3d_caps)("Invalid opengl version string: %s.\n", debugstr_a(gl_version));
1162
1163     minor = atoi(ptr);
1164
1165     TRACE_(d3d_caps)("Found OpenGL version: %d.%d.\n", major, minor);
1166
1167     return MAKEDWORD_VERSION(major, minor);
1168 }
1169
1170 static enum wined3d_gl_vendor wined3d_guess_gl_vendor(struct wined3d_gl_info *gl_info, const char *gl_vendor_string, const char *gl_renderer)
1171 {
1172
1173     /* MacOS has various specialities in the extensions it advertises. Some have to be loaded from
1174      * the opengl 1.2+ core, while other extensions are advertised, but software emulated. So try to
1175      * detect the Apple OpenGL implementation to apply some extension fixups afterwards.
1176      *
1177      * Detecting this isn't really easy. The vendor string doesn't mention Apple. Compile-time checks
1178      * aren't sufficient either because a Linux binary may display on a macos X server via remote X11.
1179      * So try to detect the GL implementation by looking at certain Apple extensions. Some extensions
1180      * like client storage might be supported on other implementations too, but GL_APPLE_flush_render
1181      * is specific to the Mac OS X window management, and GL_APPLE_ycbcr_422 is QuickTime specific. So
1182      * the chance that other implementations support them is rather small since Win32 QuickTime uses
1183      * DirectDraw, not OpenGL. */
1184     if (gl_info->supported[APPLE_FENCE]
1185             && gl_info->supported[APPLE_CLIENT_STORAGE]
1186             && gl_info->supported[APPLE_FLUSH_RENDER]
1187             && gl_info->supported[APPLE_YCBCR_422])
1188         return GL_VENDOR_APPLE;
1189
1190     if (strstr(gl_vendor_string, "NVIDIA"))
1191         return GL_VENDOR_NVIDIA;
1192
1193     if (strstr(gl_vendor_string, "ATI"))
1194         return GL_VENDOR_ATI;
1195
1196     if (strstr(gl_vendor_string, "Intel(R)")
1197             || strstr(gl_renderer, "Intel(R)")
1198             || strstr(gl_vendor_string, "Intel Inc."))
1199         return GL_VENDOR_INTEL;
1200
1201     if (strstr(gl_vendor_string, "Mesa")
1202             || strstr(gl_vendor_string, "Advanced Micro Devices, Inc.")
1203             || strstr(gl_vendor_string, "DRI R300 Project")
1204             || strstr(gl_vendor_string, "X.Org R300 Project")
1205             || strstr(gl_vendor_string, "Tungsten Graphics, Inc")
1206             || strstr(gl_vendor_string, "VMware, Inc.")
1207             || strstr(gl_renderer, "Mesa")
1208             || strstr(gl_renderer, "Gallium"))
1209         return GL_VENDOR_MESA;
1210
1211     FIXME_(d3d_caps)("Received unrecognized GL_VENDOR %s. Returning GL_VENDOR_WINE.\n", debugstr_a(gl_vendor_string));
1212
1213     return GL_VENDOR_WINE;
1214 }
1215
1216 static enum wined3d_pci_vendor wined3d_guess_card_vendor(const char *gl_vendor_string, const char *gl_renderer)
1217 {
1218     if (strstr(gl_vendor_string, "NVIDIA"))
1219         return HW_VENDOR_NVIDIA;
1220
1221     if (strstr(gl_vendor_string, "ATI")
1222             || strstr(gl_vendor_string, "Advanced Micro Devices, Inc.")
1223             || strstr(gl_vendor_string, "X.Org R300 Project")
1224             || strstr(gl_vendor_string, "DRI R300 Project"))
1225         return HW_VENDOR_ATI;
1226
1227     if (strstr(gl_vendor_string, "Intel(R)")
1228             || strstr(gl_renderer, "Intel(R)")
1229             || strstr(gl_vendor_string, "Intel Inc."))
1230         return HW_VENDOR_INTEL;
1231
1232     if (strstr(gl_vendor_string, "Mesa")
1233             || strstr(gl_vendor_string, "Tungsten Graphics, Inc")
1234             || strstr(gl_vendor_string, "VMware, Inc."))
1235         return HW_VENDOR_WINE;
1236
1237     FIXME_(d3d_caps)("Received unrecognized GL_VENDOR %s. Returning HW_VENDOR_NVIDIA.\n", debugstr_a(gl_vendor_string));
1238
1239     return HW_VENDOR_NVIDIA;
1240 }
1241
1242
1243
1244 enum wined3d_pci_device select_card_nvidia_binary(const struct wined3d_gl_info *gl_info, const char *gl_renderer,
1245             unsigned int *vidmem )
1246 {
1247     /* Both the GeforceFX, 6xxx and 7xxx series support D3D9. The last two types have more
1248      * shader capabilities, so we use the shader capabilities to distinguish between FX and 6xxx/7xxx.
1249      */
1250     if (WINE_D3D9_CAPABLE(gl_info) && gl_info->supported[NV_VERTEX_PROGRAM3])
1251     {
1252         /* Geforce 200 - highend */
1253         if (strstr(gl_renderer, "GTX 280")
1254                 || strstr(gl_renderer, "GTX 285")
1255                 || strstr(gl_renderer, "GTX 295"))
1256         {
1257             *vidmem = 1024;
1258             return CARD_NVIDIA_GEFORCE_GTX280;
1259         }
1260
1261         /* Geforce 200 - midend high */
1262         if (strstr(gl_renderer, "GTX 275"))
1263         {
1264             *vidmem = 896;
1265             return CARD_NVIDIA_GEFORCE_GTX275;
1266         }
1267
1268         /* Geforce 200 - midend */
1269         if (strstr(gl_renderer, "GTX 260"))
1270         {
1271             *vidmem = 1024;
1272             return CARD_NVIDIA_GEFORCE_GTX260;
1273         }
1274         /* Geforce 200 - midend */
1275         if (strstr(gl_renderer, "GT 240"))
1276         {
1277            *vidmem = 512;
1278            return CARD_NVIDIA_GEFORCE_GT240;
1279         }
1280
1281         /* Geforce9 - highend / Geforce 200 - midend (GTS 150/250 are based on the same core) */
1282         if (strstr(gl_renderer, "9800")
1283                 || strstr(gl_renderer, "GTS 150")
1284                 || strstr(gl_renderer, "GTS 250"))
1285         {
1286             *vidmem = 512;
1287             return CARD_NVIDIA_GEFORCE_9800GT;
1288         }
1289
1290         /* Geforce9 - midend */
1291         if (strstr(gl_renderer, "9600"))
1292         {
1293             *vidmem = 384; /* The 9600GSO has 384MB, the 9600GT has 512-1024MB */
1294             return CARD_NVIDIA_GEFORCE_9600GT;
1295         }
1296
1297         /* Geforce9 - midend low / Geforce 200 - low */
1298         if (strstr(gl_renderer, "9500")
1299                 || strstr(gl_renderer, "GT 120")
1300                 || strstr(gl_renderer, "GT 130"))
1301         {
1302             *vidmem = 256; /* The 9500GT has 256-1024MB */
1303             return CARD_NVIDIA_GEFORCE_9500GT;
1304         }
1305
1306         /* Geforce9 - lowend */
1307         if (strstr(gl_renderer, "9400"))
1308         {
1309             *vidmem = 256; /* The 9400GT has 256-1024MB */
1310             return CARD_NVIDIA_GEFORCE_9400GT;
1311         }
1312
1313         /* Geforce9 - lowend low */
1314         if (strstr(gl_renderer, "9100")
1315                 || strstr(gl_renderer, "9200")
1316                 || strstr(gl_renderer, "9300")
1317                 || strstr(gl_renderer, "G 100"))
1318         {
1319             *vidmem = 256; /* The 9100-9300 cards have 256MB */
1320             return CARD_NVIDIA_GEFORCE_9200;
1321         }
1322
1323         /* Geforce8 - highend */
1324         if (strstr(gl_renderer, "8800"))
1325         {
1326             *vidmem = 320; /* The 8800GTS uses 320MB, a 8800GTX can have 768MB */
1327             return CARD_NVIDIA_GEFORCE_8800GTS;
1328         }
1329
1330         /* Geforce8 - midend mobile */
1331         if (strstr(gl_renderer, "8600 M"))
1332         {
1333             *vidmem = 512;
1334             return CARD_NVIDIA_GEFORCE_8600MGT;
1335         }
1336
1337         /* Geforce8 - midend */
1338         if (strstr(gl_renderer, "8600")
1339                 || strstr(gl_renderer, "8700"))
1340         {
1341             *vidmem = 256;
1342             return CARD_NVIDIA_GEFORCE_8600GT;
1343         }
1344
1345         /* Geforce8 - lowend */
1346         if (strstr(gl_renderer, "8100")
1347                 || strstr(gl_renderer, "8200")
1348                 || strstr(gl_renderer, "8300")
1349                 || strstr(gl_renderer, "8400")
1350                 || strstr(gl_renderer, "8500"))
1351         {
1352             *vidmem = 128; /* 128-256MB for a 8300, 256-512MB for a 8400 */
1353             return CARD_NVIDIA_GEFORCE_8300GS;
1354         }
1355
1356         /* Geforce7 - highend */
1357         if (strstr(gl_renderer, "7800")
1358                 || strstr(gl_renderer, "7900")
1359                 || strstr(gl_renderer, "7950")
1360                 || strstr(gl_renderer, "Quadro FX 4")
1361                 || strstr(gl_renderer, "Quadro FX 5"))
1362         {
1363             *vidmem = 256; /* A 7800GT uses 256MB while highend 7900 cards can use 512MB */
1364             return CARD_NVIDIA_GEFORCE_7800GT;
1365         }
1366
1367         /* Geforce7 midend */
1368         if (strstr(gl_renderer, "7600")
1369                 || strstr(gl_renderer, "7700"))
1370         {
1371             *vidmem = 256; /* The 7600 uses 256-512MB */
1372             return CARD_NVIDIA_GEFORCE_7600;
1373         }
1374
1375         /* Geforce7 lower medium */
1376         if (strstr(gl_renderer, "7400"))
1377         {
1378             *vidmem = 256; /* The 7400 uses 256-512MB */
1379             return CARD_NVIDIA_GEFORCE_7400;
1380         }
1381
1382         /* Geforce7 lowend */
1383         if (strstr(gl_renderer, "7300"))
1384         {
1385             *vidmem = 256; /* Mac Pros with this card have 256 MB */
1386             return CARD_NVIDIA_GEFORCE_7300;
1387         }
1388
1389         /* Geforce6 highend */
1390         if (strstr(gl_renderer, "6800"))
1391         {
1392             *vidmem = 128; /* The 6800 uses 128-256MB, the 7600 uses 256-512MB */
1393             return CARD_NVIDIA_GEFORCE_6800;
1394         }
1395
1396         /* Geforce6 - midend */
1397         if (strstr(gl_renderer, "6600")
1398                 || strstr(gl_renderer, "6610")
1399                 || strstr(gl_renderer, "6700"))
1400         {
1401             *vidmem = 128; /* A 6600GT has 128-256MB */
1402             return CARD_NVIDIA_GEFORCE_6600GT;
1403         }
1404
1405         /* Geforce6/7 lowend */
1406         *vidmem = 64; /* */
1407         return CARD_NVIDIA_GEFORCE_6200; /* Geforce 6100/6150/6200/7300/7400/7500 */
1408     }
1409
1410     if (WINE_D3D9_CAPABLE(gl_info))
1411     {
1412         /* GeforceFX - highend */
1413         if (strstr(gl_renderer, "5800")
1414                 || strstr(gl_renderer, "5900")
1415                 || strstr(gl_renderer, "5950")
1416                 || strstr(gl_renderer, "Quadro FX"))
1417         {
1418             *vidmem = 256; /* 5800-5900 cards use 256MB */
1419             return CARD_NVIDIA_GEFORCEFX_5800;
1420         }
1421
1422         /* GeforceFX - midend */
1423         if (strstr(gl_renderer, "5600")
1424                 || strstr(gl_renderer, "5650")
1425                 || strstr(gl_renderer, "5700")
1426                 || strstr(gl_renderer, "5750"))
1427         {
1428             *vidmem = 128; /* A 5600 uses 128-256MB */
1429             return CARD_NVIDIA_GEFORCEFX_5600;
1430         }
1431
1432         /* GeforceFX - lowend */
1433         *vidmem = 64; /* Normal FX5200 cards use 64-256MB; laptop (non-standard) can have less */
1434         return CARD_NVIDIA_GEFORCEFX_5200; /* GeforceFX 5100/5200/5250/5300/5500 */
1435     }
1436
1437     if (WINE_D3D8_CAPABLE(gl_info))
1438     {
1439         if (strstr(gl_renderer, "GeForce4 Ti") || strstr(gl_renderer, "Quadro4"))
1440         {
1441             *vidmem = 64; /* Geforce4 Ti cards have 64-128MB */
1442             return CARD_NVIDIA_GEFORCE4_TI4200; /* Geforce4 Ti4200/Ti4400/Ti4600/Ti4800, Quadro4 */
1443         }
1444
1445         *vidmem = 64; /* Geforce3 cards have 64-128MB */
1446         return CARD_NVIDIA_GEFORCE3; /* Geforce3 standard/Ti200/Ti500, Quadro DCC */
1447     }
1448
1449     if (WINE_D3D7_CAPABLE(gl_info))
1450     {
1451         if (strstr(gl_renderer, "GeForce4 MX"))
1452         {
1453             /* Most Geforce4MX GPUs have at least 64MB of memory, some
1454              * early models had 32MB but most have 64MB or even 128MB. */
1455             *vidmem = 64;
1456             return CARD_NVIDIA_GEFORCE4_MX; /* MX420/MX440/MX460/MX4000 */
1457         }
1458
1459         if (strstr(gl_renderer, "GeForce2 MX") || strstr(gl_renderer, "Quadro2 MXR"))
1460         {
1461             *vidmem = 32; /* Geforce2MX GPUs have 32-64MB of video memory */
1462             return CARD_NVIDIA_GEFORCE2_MX; /* Geforce2 standard/MX100/MX200/MX400, Quadro2 MXR */
1463         }
1464
1465         if (strstr(gl_renderer, "GeForce2") || strstr(gl_renderer, "Quadro2"))
1466         {
1467             *vidmem = 32; /* Geforce2 GPUs have 32-64MB of video memory */
1468             return CARD_NVIDIA_GEFORCE2; /* Geforce2 GTS/Pro/Ti/Ultra, Quadro2 */
1469         }
1470
1471         /* Most Geforce1 cards have 32MB, there are also some rare 16
1472          * and 64MB (Dell) models. */
1473         *vidmem = 32;
1474         return CARD_NVIDIA_GEFORCE; /* Geforce 256/DDR, Quadro */
1475     }
1476
1477     if (strstr(gl_renderer, "TNT2"))
1478     {
1479         *vidmem = 32; /* Most TNT2 boards have 32MB, though there are 16MB boards too */
1480         return CARD_NVIDIA_RIVA_TNT2; /* Riva TNT2 standard/M64/Pro/Ultra */
1481     }
1482
1483     *vidmem = 16; /* Most TNT boards have 16MB, some rare models have 8MB */
1484     return CARD_NVIDIA_RIVA_TNT; /* Riva TNT, Vanta */
1485
1486 }
1487
1488 enum wined3d_pci_device select_card_ati_binary(const struct wined3d_gl_info *gl_info, const char *gl_renderer,
1489     unsigned int *vidmem )
1490 {
1491     /* See http://developer.amd.com/drivers/pc_vendor_id/Pages/default.aspx
1492      *
1493      * Beware: renderer string do not match exact card model,
1494      * eg HD 4800 is returned for multiple cards, even for RV790 based ones. */
1495     if (WINE_D3D9_CAPABLE(gl_info))
1496     {
1497         /* Radeon EG CYPRESS XT / PRO HD5800 - highend */
1498         if (strstr(gl_renderer, "HD 5800")          /* Radeon EG CYPRESS HD58xx generic renderer string */
1499                 || strstr(gl_renderer, "HD 5850")   /* Radeon EG CYPRESS XT */
1500                 || strstr(gl_renderer, "HD 5870"))  /* Radeon EG CYPRESS PRO */
1501         {
1502             *vidmem = 1024; /* note: HD58xx cards use 1024MB  */
1503             return CARD_ATI_RADEON_HD5800;
1504         }
1505
1506         /* Radeon EG JUNIPER XT / LE HD5700 - midend */
1507         if (strstr(gl_renderer, "HD 5700")          /* Radeon EG JUNIPER HD57xx generic renderer string */
1508                 || strstr(gl_renderer, "HD 5750")   /* Radeon EG JUNIPER LE */
1509                 || strstr(gl_renderer, "HD 5770"))  /* Radeon EG JUNIPER XT */
1510         {
1511             *vidmem = 512; /* note: HD5770 cards use 1024MB and HD5750 cards use 512MB or 1024MB  */
1512             return CARD_ATI_RADEON_HD5700;
1513         }
1514
1515         /* Radeon R7xx HD4800 - highend */
1516         if (strstr(gl_renderer, "HD 4800")          /* Radeon RV7xx HD48xx generic renderer string */
1517                 || strstr(gl_renderer, "HD 4830")   /* Radeon RV770 */
1518                 || strstr(gl_renderer, "HD 4850")   /* Radeon RV770 */
1519                 || strstr(gl_renderer, "HD 4870")   /* Radeon RV770 */
1520                 || strstr(gl_renderer, "HD 4890"))  /* Radeon RV790 */
1521         {
1522             *vidmem = 512; /* note: HD4890 cards use 1024MB */
1523             return CARD_ATI_RADEON_HD4800;
1524         }
1525
1526         /* Radeon R740 HD4700 - midend */
1527         if (strstr(gl_renderer, "HD 4700")          /* Radeon RV770 */
1528                 || strstr(gl_renderer, "HD 4770"))  /* Radeon RV740 */
1529         {
1530             *vidmem = 512;
1531             return CARD_ATI_RADEON_HD4700;
1532         }
1533
1534         /* Radeon R730 HD4600 - midend */
1535         if (strstr(gl_renderer, "HD 4600")          /* Radeon RV730 */
1536                 || strstr(gl_renderer, "HD 4650")   /* Radeon RV730 */
1537                 || strstr(gl_renderer, "HD 4670"))  /* Radeon RV730 */
1538         {
1539             *vidmem = 512;
1540             return CARD_ATI_RADEON_HD4600;
1541         }
1542
1543         /* Radeon R710 HD4500/HD4350 - lowend */
1544         if (strstr(gl_renderer, "HD 4350")          /* Radeon RV710 */
1545                 || strstr(gl_renderer, "HD 4550"))  /* Radeon RV710 */
1546         {
1547             *vidmem = 256;
1548             return CARD_ATI_RADEON_HD4350;
1549         }
1550
1551         /* Radeon R6xx HD2900/HD3800 - highend */
1552         if (strstr(gl_renderer, "HD 2900")
1553                 || strstr(gl_renderer, "HD 3870")
1554                 || strstr(gl_renderer, "HD 3850"))
1555         {
1556             *vidmem = 512; /* HD2900/HD3800 uses 256-1024MB */
1557             return CARD_ATI_RADEON_HD2900;
1558         }
1559
1560         /* Radeon R6xx HD2600/HD3600 - midend; HD3830 is China-only midend */
1561         if (strstr(gl_renderer, "HD 2600")
1562                 || strstr(gl_renderer, "HD 3830")
1563                 || strstr(gl_renderer, "HD 3690")
1564                 || strstr(gl_renderer, "HD 3650"))
1565         {
1566             *vidmem = 256; /* HD2600/HD3600 uses 256-512MB */
1567             return CARD_ATI_RADEON_HD2600;
1568         }
1569
1570         /* Radeon R6xx HD2300/HD2400/HD3400 - lowend */
1571         if (strstr(gl_renderer, "HD 2300")
1572                 || strstr(gl_renderer, "HD 2400")
1573                 || strstr(gl_renderer, "HD 3470")
1574                 || strstr(gl_renderer, "HD 3450")
1575                 || strstr(gl_renderer, "HD 3430")
1576                 || strstr(gl_renderer, "HD 3400"))
1577         {
1578             *vidmem = 128; /* HD2300 uses at least 128MB, HD2400 uses 256MB */
1579             return CARD_ATI_RADEON_HD2300;
1580         }
1581
1582         /* Radeon R6xx/R7xx integrated */
1583         if (strstr(gl_renderer, "HD 3100")
1584                 || strstr(gl_renderer, "HD 3200")
1585                 || strstr(gl_renderer, "HD 3300"))
1586         {
1587             *vidmem = 128; /* 128MB */
1588             return CARD_ATI_RADEON_HD3200;
1589         }
1590
1591         /* Radeon R5xx */
1592         if (strstr(gl_renderer, "X1600")
1593                 || strstr(gl_renderer, "X1650")
1594                 || strstr(gl_renderer, "X1800")
1595                 || strstr(gl_renderer, "X1900")
1596                 || strstr(gl_renderer, "X1950"))
1597         {
1598             *vidmem = 128; /* X1600 uses 128-256MB, >=X1800 uses 256MB */
1599             return CARD_ATI_RADEON_X1600;
1600         }
1601
1602         /* Radeon R4xx + X1300/X1400/X1450/X1550/X2300 (lowend R5xx) */
1603         if (strstr(gl_renderer, "X700")
1604                 || strstr(gl_renderer, "X800")
1605                 || strstr(gl_renderer, "X850")
1606                 || strstr(gl_renderer, "X1300")
1607                 || strstr(gl_renderer, "X1400")
1608                 || strstr(gl_renderer, "X1450")
1609                 || strstr(gl_renderer, "X1550"))
1610         {
1611             *vidmem = 128; /* x700/x8*0 use 128-256MB, >=x1300 128-512MB */
1612             return CARD_ATI_RADEON_X700;
1613         }
1614
1615         /* Radeon Xpress Series - onboard, DX9b, Shader 2.0, 300-400MHz */
1616         if (strstr(gl_renderer, "Radeon Xpress"))
1617         {
1618             *vidmem = 64; /* Shared RAM, BIOS configurable, 64-256M */
1619             return CARD_ATI_RADEON_XPRESS_200M;
1620         }
1621
1622         /* Radeon R3xx */
1623         *vidmem = 64; /* Radeon 9500 uses 64MB, higher models use up to 256MB */
1624         return CARD_ATI_RADEON_9500; /* Radeon 9500/9550/9600/9700/9800/X300/X550/X600 */
1625     }
1626
1627     if (WINE_D3D8_CAPABLE(gl_info))
1628     {
1629         *vidmem = 64; /* 8500/9000 cards use mostly 64MB, though there are 32MB and 128MB models */
1630         return CARD_ATI_RADEON_8500; /* Radeon 8500/9000/9100/9200/9300 */
1631     }
1632
1633     if (WINE_D3D7_CAPABLE(gl_info))
1634     {
1635         *vidmem = 32; /* There are models with up to 64MB */
1636         return CARD_ATI_RADEON_7200; /* Radeon 7000/7100/7200/7500 */
1637     }
1638
1639     *vidmem = 16; /* There are 16-32MB models */
1640     return CARD_ATI_RAGE_128PRO;
1641
1642 }
1643
1644 enum wined3d_pci_device select_card_intel_binary(const struct wined3d_gl_info *gl_info, const char *gl_renderer,
1645     unsigned int *vidmem )
1646 {
1647     if (strstr(gl_renderer, "X3100"))
1648     {
1649         /* MacOS calls the card GMA X3100, Google findings also suggest the name GM965 */
1650         *vidmem = 128;
1651         return CARD_INTEL_X3100;
1652     }
1653
1654     if (strstr(gl_renderer, "GMA 950") || strstr(gl_renderer, "945GM"))
1655     {
1656         /* MacOS calls the card GMA 950, but everywhere else the PCI ID is named 945GM */
1657         *vidmem = 64;
1658         return CARD_INTEL_I945GM;
1659     }
1660
1661     if (strstr(gl_renderer, "915GM")) return CARD_INTEL_I915GM;
1662     if (strstr(gl_renderer, "915G")) return CARD_INTEL_I915G;
1663     if (strstr(gl_renderer, "865G")) return CARD_INTEL_I865G;
1664     if (strstr(gl_renderer, "855G")) return CARD_INTEL_I855G;
1665     if (strstr(gl_renderer, "830G")) return CARD_INTEL_I830G;
1666     return CARD_INTEL_I915G;
1667
1668 }
1669
1670 enum wined3d_pci_device (select_card_ati_mesa)(const struct wined3d_gl_info *gl_info, const char *gl_renderer,
1671             unsigned int *vidmem )
1672 {
1673     /* See http://developer.amd.com/drivers/pc_vendor_id/Pages/default.aspx
1674      *
1675      * Beware: renderer string do not match exact card model,
1676      * eg HD 4800 is returned for multiple cards, even for RV790 based ones. */
1677     if (strstr(gl_renderer, "Gallium"))
1678     {
1679         /* Radeon R7xx HD4800 - highend */
1680         if (strstr(gl_renderer, "R700")          /* Radeon R7xx HD48xx generic renderer string */
1681                 || strstr(gl_renderer, "RV770")  /* Radeon RV770 */
1682                 || strstr(gl_renderer, "RV790"))  /* Radeon RV790 */
1683         {
1684             *vidmem = 512; /* note: HD4890 cards use 1024MB */
1685             return CARD_ATI_RADEON_HD4800;
1686         }
1687
1688         /* Radeon R740 HD4700 - midend */
1689         if (strstr(gl_renderer, "RV740"))          /* Radeon RV740 */
1690         {
1691             *vidmem = 512;
1692             return CARD_ATI_RADEON_HD4700;
1693         }
1694
1695         /* Radeon R730 HD4600 - midend */
1696         if (strstr(gl_renderer, "RV730"))        /* Radeon RV730 */
1697         {
1698             *vidmem = 512;
1699             return CARD_ATI_RADEON_HD4600;
1700         }
1701
1702         /* Radeon R710 HD4500/HD4350 - lowend */
1703         if (strstr(gl_renderer, "RV710"))          /* Radeon RV710 */
1704         {
1705             *vidmem = 256;
1706             return CARD_ATI_RADEON_HD4350;
1707         }
1708
1709         /* Radeon R6xx HD2900/HD3800 - highend */
1710         if (strstr(gl_renderer, "R600")
1711                 || strstr(gl_renderer, "RV670")
1712                 || strstr(gl_renderer, "R680"))
1713         {
1714             *vidmem = 512; /* HD2900/HD3800 uses 256-1024MB */
1715             return CARD_ATI_RADEON_HD2900;
1716         }
1717
1718         /* Radeon R6xx HD2600/HD3600 - midend; HD3830 is China-only midend */
1719         if (strstr(gl_renderer, "RV630")
1720                 || strstr(gl_renderer, "RV635"))
1721         {
1722             *vidmem = 256; /* HD2600/HD3600 uses 256-512MB */
1723             return CARD_ATI_RADEON_HD2600;
1724         }
1725
1726         /* Radeon R6xx HD2300/HD2400/HD3400 - lowend */
1727         if (strstr(gl_renderer, "RV610")
1728                 || strstr(gl_renderer, "RV620"))
1729         {
1730             *vidmem = 128; /* HD2300 uses at least 128MB, HD2400 uses 256MB */
1731             return CARD_ATI_RADEON_HD2300;
1732         }
1733
1734         /* Radeon R6xx/R7xx integrated */
1735         if (strstr(gl_renderer, "RS780")
1736                 || strstr(gl_renderer, "RS880"))
1737         {
1738             *vidmem = 128; /* 128MB */
1739             return CARD_ATI_RADEON_HD3200;
1740         }
1741
1742         /* Radeon R5xx */
1743         if (strstr(gl_renderer, "RV530")
1744                 || strstr(gl_renderer, "RV535")
1745                 || strstr(gl_renderer, "RV560")
1746                 || strstr(gl_renderer, "R520")
1747                 || strstr(gl_renderer, "RV570")
1748                 || strstr(gl_renderer, "R580"))
1749         {
1750             *vidmem = 128; /* X1600 uses 128-256MB, >=X1800 uses 256MB */
1751             return CARD_ATI_RADEON_X1600;
1752         }
1753
1754         /* Radeon R4xx + X1300/X1400/X1450/X1550/X2300 (lowend R5xx) */
1755         if (strstr(gl_renderer, "R410")
1756                 || strstr(gl_renderer, "R420")
1757                 || strstr(gl_renderer, "R423")
1758                 || strstr(gl_renderer, "R430")
1759                 || strstr(gl_renderer, "R480")
1760                 || strstr(gl_renderer, "R481")
1761                 || strstr(gl_renderer, "RV410")
1762                 || strstr(gl_renderer, "RV515")
1763                 || strstr(gl_renderer, "RV516"))
1764         {
1765             *vidmem = 128; /* x700/x8*0 use 128-256MB, >=x1300 128-512MB */
1766             return CARD_ATI_RADEON_X700;
1767         }
1768
1769         /* Radeon Xpress Series - onboard, DX9b, Shader 2.0, 300-400MHz */
1770         if (strstr(gl_renderer, "RS400")
1771                 || strstr(gl_renderer, "RS480")
1772                 || strstr(gl_renderer, "RS482")
1773                 || strstr(gl_renderer, "RS485")
1774                 || strstr(gl_renderer, "RS600")
1775                 || strstr(gl_renderer, "RS690")
1776                 || strstr(gl_renderer, "RS740"))
1777         {
1778             *vidmem = 64; /* Shared RAM, BIOS configurable, 64-256M */
1779             return CARD_ATI_RADEON_XPRESS_200M;
1780         }
1781
1782         /* Radeon R3xx */
1783         if (strstr(gl_renderer, "R300")
1784                 || strstr(gl_renderer, "RV350")
1785                 || strstr(gl_renderer, "RV351")
1786                 || strstr(gl_renderer, "RV360")
1787                 || strstr(gl_renderer, "RV370")
1788                 || strstr(gl_renderer, "R350")
1789                 || strstr(gl_renderer, "R360"))
1790         {
1791             *vidmem = 64; /* Radeon 9500 uses 64MB, higher models use up to 256MB */
1792             return CARD_ATI_RADEON_9500; /* Radeon 9500/9550/9600/9700/9800/X300/X550/X600 */
1793         }
1794     }
1795
1796     if (WINE_D3D9_CAPABLE(gl_info))
1797     {
1798         /* Radeon R7xx HD4800 - highend */
1799         if (strstr(gl_renderer, "(R700")          /* Radeon R7xx HD48xx generic renderer string */
1800                 || strstr(gl_renderer, "(RV770")  /* Radeon RV770 */
1801                 || strstr(gl_renderer, "(RV790"))  /* Radeon RV790 */
1802         {
1803             *vidmem = 512; /* note: HD4890 cards use 1024MB */
1804             return CARD_ATI_RADEON_HD4800;
1805         }
1806
1807         /* Radeon R740 HD4700 - midend */
1808         if (strstr(gl_renderer, "(RV740"))          /* Radeon RV740 */
1809         {
1810             *vidmem = 512;
1811             return CARD_ATI_RADEON_HD4700;
1812         }
1813
1814         /* Radeon R730 HD4600 - midend */
1815         if (strstr(gl_renderer, "(RV730"))        /* Radeon RV730 */
1816         {
1817             *vidmem = 512;
1818             return CARD_ATI_RADEON_HD4600;
1819         }
1820
1821         /* Radeon R710 HD4500/HD4350 - lowend */
1822         if (strstr(gl_renderer, "(RV710"))          /* Radeon RV710 */
1823         {
1824             *vidmem = 256;
1825             return CARD_ATI_RADEON_HD4350;
1826         }
1827
1828         /* Radeon R6xx HD2900/HD3800 - highend */
1829         if (strstr(gl_renderer, "(R600")
1830                 || strstr(gl_renderer, "(RV670")
1831                 || strstr(gl_renderer, "(R680"))
1832         {
1833             *vidmem = 512; /* HD2900/HD3800 uses 256-1024MB */
1834             return CARD_ATI_RADEON_HD2900;
1835         }
1836
1837         /* Radeon R6xx HD2600/HD3600 - midend; HD3830 is China-only midend */
1838         if (strstr(gl_renderer, "(RV630")
1839                 || strstr(gl_renderer, "(RV635"))
1840         {
1841             *vidmem = 256; /* HD2600/HD3600 uses 256-512MB */
1842             return CARD_ATI_RADEON_HD2600;
1843         }
1844
1845         /* Radeon R6xx HD2300/HD2400/HD3400 - lowend */
1846         if (strstr(gl_renderer, "(RV610")
1847                 || strstr(gl_renderer, "(RV620"))
1848         {
1849             *vidmem = 128; /* HD2300 uses at least 128MB, HD2400 uses 256MB */
1850             return CARD_ATI_RADEON_HD2300;
1851         }
1852
1853         /* Radeon R6xx/R7xx integrated */
1854         if (strstr(gl_renderer, "(RS780")
1855                 || strstr(gl_renderer, "(RS880"))
1856         {
1857             *vidmem = 128; /* 128MB */
1858             return CARD_ATI_RADEON_HD3200;
1859         }
1860     }
1861
1862     if (WINE_D3D8_CAPABLE(gl_info))
1863     {
1864         *vidmem = 64; /* 8500/9000 cards use mostly 64MB, though there are 32MB and 128MB models */
1865         return CARD_ATI_RADEON_8500; /* Radeon 8500/9000/9100/9200/9300 */
1866     }
1867
1868     if (WINE_D3D7_CAPABLE(gl_info))
1869     {
1870         *vidmem = 32; /* There are models with up to 64MB */
1871         return CARD_ATI_RADEON_7200; /* Radeon 7000/7100/7200/7500 */
1872     }
1873
1874     *vidmem = 16; /* There are 16-32MB models */
1875     return CARD_ATI_RAGE_128PRO;
1876
1877 }
1878
1879 enum wined3d_pci_device (select_card_nvidia_mesa)(const struct wined3d_gl_info *gl_info, const char *gl_renderer,
1880     unsigned int *vidmem )
1881 {
1882     FIXME_(d3d_caps)("Card selection not handled for Mesa Nouveau driver\n");
1883     if (WINE_D3D9_CAPABLE(gl_info)) return CARD_NVIDIA_GEFORCEFX_5600;
1884     if (WINE_D3D8_CAPABLE(gl_info)) return CARD_NVIDIA_GEFORCE3;
1885     if (WINE_D3D7_CAPABLE(gl_info)) return CARD_NVIDIA_GEFORCE;
1886     if (WINE_D3D6_CAPABLE(gl_info)) return CARD_NVIDIA_RIVA_TNT;
1887     return CARD_NVIDIA_RIVA_128;
1888 }
1889
1890 enum wined3d_pci_device (select_card_intel_mesa)(const struct wined3d_gl_info *gl_info, const char *gl_renderer,
1891     unsigned int *vidmem )
1892 {
1893     FIXME_(d3d_caps)("Card selection not handled for Mesa Intel driver\n");
1894     return CARD_INTEL_I915G;
1895 }
1896
1897
1898 struct vendor_card_selection
1899 {
1900     enum wined3d_gl_vendor gl_vendor;
1901     enum wined3d_pci_vendor card_vendor;
1902     const char *description;        /* Description of the card selector i.e. Apple OS/X Intel */
1903     enum wined3d_pci_device (*select_card)(const struct wined3d_gl_info *gl_info, const char *gl_renderer,
1904             unsigned int *vidmem );
1905 };
1906
1907 static const struct vendor_card_selection vendor_card_select_table[] =
1908 {
1909     {GL_VENDOR_NVIDIA, HW_VENDOR_NVIDIA,  "Nvidia binary driver",     select_card_nvidia_binary},
1910     {GL_VENDOR_APPLE,  HW_VENDOR_NVIDIA,  "Apple OSX NVidia binary driver",   select_card_nvidia_binary},
1911     {GL_VENDOR_APPLE,  HW_VENDOR_ATI,     "Apple OSX AMD/ATI binary driver",  select_card_ati_binary},
1912     {GL_VENDOR_APPLE,  HW_VENDOR_INTEL,   "Apple OSX Intel binary driver",    select_card_intel_binary},
1913     {GL_VENDOR_ATI,    HW_VENDOR_ATI,     "AMD/ATI binary driver",    select_card_ati_binary},
1914     {GL_VENDOR_MESA,   HW_VENDOR_ATI,     "Mesa AMD/ATI driver",      select_card_ati_mesa},
1915     {GL_VENDOR_MESA,   HW_VENDOR_NVIDIA,  "Mesa Nouveau driver",      select_card_nvidia_mesa},
1916     {GL_VENDOR_MESA,   HW_VENDOR_INTEL,   "Mesa Intel driver",        select_card_intel_mesa}
1917 };
1918
1919
1920 static enum wined3d_pci_device wined3d_guess_card(const struct wined3d_gl_info *gl_info, const char *gl_renderer,
1921         enum wined3d_gl_vendor *gl_vendor, enum wined3d_pci_vendor *card_vendor, unsigned int *vidmem)
1922 {
1923     /* Above is a list of Nvidia and ATI GPUs. Both vendors have dozens of
1924      * different GPUs with roughly the same features. In most cases GPUs from a
1925      * certain family differ in clockspeeds, the amount of video memory and the
1926      * number of shader pipelines.
1927      *
1928      * A Direct3D device object contains the PCI id (vendor + device) of the
1929      * videocard which is used for rendering. Various applications use this
1930      * information to get a rough estimation of the features of the card and
1931      * some might use it for enabling 3d effects only on certain types of
1932      * videocards. In some cases games might even use it to work around bugs
1933      * which happen on certain videocards/driver combinations. The problem is
1934      * that OpenGL only exposes a rendering string containing the name of the
1935      * videocard and not the PCI id.
1936      *
1937      * Various games depend on the PCI id, so somehow we need to provide one.
1938      * A simple option is to parse the renderer string and translate this to
1939      * the right PCI id. This is a lot of work because there are more than 200
1940      * GPUs just for Nvidia. Various cards share the same renderer string, so
1941      * the amount of code might be 'small' but there are quite a number of
1942      * exceptions which would make this a pain to maintain. Another way would
1943      * be to query the PCI id from the operating system (assuming this is the
1944      * videocard which is used for rendering which is not always the case).
1945      * This would work but it is not very portable. Second it would not work
1946      * well in, let's say, a remote X situation in which the amount of 3d
1947      * features which can be used is limited.
1948      *
1949      * As said most games only use the PCI id to get an indication of the
1950      * capabilities of the card. It doesn't really matter if the given id is
1951      * the correct one if we return the id of a card with similar 3d features.
1952      *
1953      * The code below checks the OpenGL capabilities of a videocard and matches
1954      * that to a certain level of Direct3D functionality. Once a card passes
1955      * the Direct3D9 check, we know that the card (in case of Nvidia) is at
1956      * least a GeforceFX. To give a better estimate we do a basic check on the
1957      * renderer string but if that won't pass we return a default card. This
1958      * way is better than maintaining a full card database as even without a
1959      * full database we can return a card with similar features. Second the
1960      * size of the database can be made quite small because when you know what
1961      * type of 3d functionality a card has, you know to which GPU family the
1962      * GPU must belong. Because of this you only have to check a small part of
1963      * the renderer string to distinguishes between different models from that
1964      * family.
1965      *
1966      * The code also selects a default amount of video memory which we will
1967      * use for an estimation of the amount of free texture memory. In case of
1968      * real D3D the amount of texture memory includes video memory and system
1969      * memory (to be specific AGP memory or in case of PCIE TurboCache /
1970      * HyperMemory). We don't know how much system memory can be addressed by
1971      * the system but we can make a reasonable estimation about the amount of
1972      * video memory. If the value is slightly wrong it doesn't matter as we
1973      * didn't include AGP-like memory which makes the amount of addressable
1974      * memory higher and second OpenGL isn't that critical it moves to system
1975      * memory behind our backs if really needed. Note that the amount of video
1976      * memory can be overruled using a registry setting. */
1977
1978     int i;
1979
1980     for (i = 0; i < (sizeof(vendor_card_select_table) / sizeof(*vendor_card_select_table)); ++i)
1981     {
1982         if ((vendor_card_select_table[i].gl_vendor != *gl_vendor)
1983             || (vendor_card_select_table[i].card_vendor != *card_vendor))
1984                 continue;
1985         TRACE_(d3d_caps)("Applying card_selector \"%s\".\n", vendor_card_select_table[i].description);
1986         return vendor_card_select_table[i].select_card(gl_info, gl_renderer, vidmem);
1987     }
1988
1989     FIXME_(d3d_caps)("No card selector available for GL vendor %d and card vendor %04x.\n",
1990                      *gl_vendor, *card_vendor);
1991
1992     /* Default to generic Nvidia hardware based on the supported OpenGL extensions. The choice
1993      * for Nvidia was because the hardware and drivers they make are of good quality. This makes
1994      * them a good generic choice. */
1995     *card_vendor = HW_VENDOR_NVIDIA;
1996     if (WINE_D3D9_CAPABLE(gl_info)) return CARD_NVIDIA_GEFORCEFX_5600;
1997     if (WINE_D3D8_CAPABLE(gl_info)) return CARD_NVIDIA_GEFORCE3;
1998     if (WINE_D3D7_CAPABLE(gl_info)) return CARD_NVIDIA_GEFORCE;
1999     if (WINE_D3D6_CAPABLE(gl_info)) return CARD_NVIDIA_RIVA_TNT;
2000     return CARD_NVIDIA_RIVA_128;
2001 }
2002
2003 static const struct fragment_pipeline *select_fragment_implementation(struct wined3d_adapter *adapter)
2004 {
2005     const struct wined3d_gl_info *gl_info = &adapter->gl_info;
2006     int vs_selected_mode, ps_selected_mode;
2007
2008     select_shader_mode(gl_info, &ps_selected_mode, &vs_selected_mode);
2009     if ((ps_selected_mode == SHADER_ARB || ps_selected_mode == SHADER_GLSL)
2010             && gl_info->supported[ARB_FRAGMENT_PROGRAM]) return &arbfp_fragment_pipeline;
2011     else if (ps_selected_mode == SHADER_ATI) return &atifs_fragment_pipeline;
2012     else if (gl_info->supported[NV_REGISTER_COMBINERS]
2013             && gl_info->supported[NV_TEXTURE_SHADER2]) return &nvts_fragment_pipeline;
2014     else if (gl_info->supported[NV_REGISTER_COMBINERS]) return &nvrc_fragment_pipeline;
2015     else return &ffp_fragment_pipeline;
2016 }
2017
2018 static const shader_backend_t *select_shader_backend(struct wined3d_adapter *adapter)
2019 {
2020     int vs_selected_mode, ps_selected_mode;
2021
2022     select_shader_mode(&adapter->gl_info, &ps_selected_mode, &vs_selected_mode);
2023     if (vs_selected_mode == SHADER_GLSL || ps_selected_mode == SHADER_GLSL) return &glsl_shader_backend;
2024     if (vs_selected_mode == SHADER_ARB || ps_selected_mode == SHADER_ARB) return &arb_program_shader_backend;
2025     return &none_shader_backend;
2026 }
2027
2028 static const struct blit_shader *select_blit_implementation(struct wined3d_adapter *adapter)
2029 {
2030     const struct wined3d_gl_info *gl_info = &adapter->gl_info;
2031     int vs_selected_mode, ps_selected_mode;
2032
2033     select_shader_mode(gl_info, &ps_selected_mode, &vs_selected_mode);
2034     if ((ps_selected_mode == SHADER_ARB || ps_selected_mode == SHADER_GLSL)
2035             && gl_info->supported[ARB_FRAGMENT_PROGRAM]) return &arbfp_blit;
2036     else return &ffp_blit;
2037 }
2038
2039 /* Context activation is done by the caller. */
2040 static BOOL IWineD3DImpl_FillGLCaps(struct wined3d_adapter *adapter)
2041 {
2042     struct wined3d_driver_info *driver_info = &adapter->driver_info;
2043     struct wined3d_gl_info *gl_info = &adapter->gl_info;
2044     const char *GL_Extensions    = NULL;
2045     const char *WGL_Extensions   = NULL;
2046     const char *gl_vendor_str, *gl_renderer_str, *gl_version_str;
2047     struct fragment_caps fragment_caps;
2048     enum wined3d_gl_vendor gl_vendor;
2049     enum wined3d_pci_vendor card_vendor;
2050     enum wined3d_pci_device device;
2051     GLint       gl_max;
2052     GLfloat     gl_floatv[2];
2053     unsigned    i;
2054     HDC         hdc;
2055     unsigned int vidmem=0;
2056     DWORD gl_version;
2057     size_t len;
2058
2059     TRACE_(d3d_caps)("(%p)\n", gl_info);
2060
2061     ENTER_GL();
2062
2063     gl_renderer_str = (const char *)glGetString(GL_RENDERER);
2064     TRACE_(d3d_caps)("GL_RENDERER: %s.\n", debugstr_a(gl_renderer_str));
2065     if (!gl_renderer_str)
2066     {
2067         LEAVE_GL();
2068         ERR_(d3d_caps)("Received a NULL GL_RENDERER.\n");
2069         return FALSE;
2070     }
2071
2072     gl_vendor_str = (const char *)glGetString(GL_VENDOR);
2073     TRACE_(d3d_caps)("GL_VENDOR: %s.\n", debugstr_a(gl_vendor_str));
2074     if (!gl_vendor_str)
2075     {
2076         LEAVE_GL();
2077         ERR_(d3d_caps)("Received a NULL GL_VENDOR.\n");
2078         return FALSE;
2079     }
2080
2081     /* Parse the GL_VERSION field into major and minor information */
2082     gl_version_str = (const char *)glGetString(GL_VERSION);
2083     TRACE_(d3d_caps)("GL_VERSION: %s.\n", debugstr_a(gl_version_str));
2084     if (!gl_version_str)
2085     {
2086         LEAVE_GL();
2087         ERR_(d3d_caps)("Received a NULL GL_VERSION.\n");
2088         return FALSE;
2089     }
2090     gl_version = wined3d_parse_gl_version(gl_version_str);
2091
2092     /*
2093      * Initialize openGL extension related variables
2094      *  with Default values
2095      */
2096     memset(gl_info->supported, 0, sizeof(gl_info->supported));
2097     gl_info->limits.buffers = 1;
2098     gl_info->limits.textures = 1;
2099     gl_info->limits.fragment_samplers = 1;
2100     gl_info->limits.vertex_samplers = 0;
2101     gl_info->limits.combined_samplers = gl_info->limits.fragment_samplers + gl_info->limits.vertex_samplers;
2102     gl_info->limits.sampler_stages = 1;
2103     gl_info->limits.glsl_vs_float_constants = 0;
2104     gl_info->limits.glsl_ps_float_constants = 0;
2105     gl_info->limits.arb_vs_float_constants = 0;
2106     gl_info->limits.arb_vs_native_constants = 0;
2107     gl_info->limits.arb_vs_instructions = 0;
2108     gl_info->limits.arb_vs_temps = 0;
2109     gl_info->limits.arb_ps_float_constants = 0;
2110     gl_info->limits.arb_ps_local_constants = 0;
2111     gl_info->limits.arb_ps_instructions = 0;
2112     gl_info->limits.arb_ps_temps = 0;
2113
2114     /* Retrieve opengl defaults */
2115     glGetIntegerv(GL_MAX_CLIP_PLANES, &gl_max);
2116     gl_info->limits.clipplanes = min(WINED3DMAXUSERCLIPPLANES, gl_max);
2117     TRACE_(d3d_caps)("ClipPlanes support - num Planes=%d\n", gl_max);
2118
2119     glGetIntegerv(GL_MAX_LIGHTS, &gl_max);
2120     gl_info->limits.lights = gl_max;
2121     TRACE_(d3d_caps)("Lights support - max lights=%d\n", gl_max);
2122
2123     glGetIntegerv(GL_MAX_TEXTURE_SIZE, &gl_max);
2124     gl_info->limits.texture_size = gl_max;
2125     TRACE_(d3d_caps)("Maximum texture size support - max texture size=%d\n", gl_max);
2126
2127     glGetFloatv(GL_ALIASED_POINT_SIZE_RANGE, gl_floatv);
2128     gl_info->limits.pointsize_min = gl_floatv[0];
2129     gl_info->limits.pointsize_max = gl_floatv[1];
2130     TRACE_(d3d_caps)("Maximum point size support - max point size=%f\n", gl_floatv[1]);
2131
2132     /* Parse the gl supported features, in theory enabling parts of our code appropriately. */
2133     GL_Extensions = (const char *)glGetString(GL_EXTENSIONS);
2134     if (!GL_Extensions)
2135     {
2136         LEAVE_GL();
2137         ERR_(d3d_caps)("Received a NULL GL_EXTENSIONS.\n");
2138         return FALSE;
2139     }
2140
2141     LEAVE_GL();
2142
2143     TRACE_(d3d_caps)("GL_Extensions reported:\n");
2144
2145     gl_info->supported[WINED3D_GL_EXT_NONE] = TRUE;
2146
2147     while (*GL_Extensions)
2148     {
2149         const char *start;
2150         char current_ext[256];
2151
2152         while (isspace(*GL_Extensions)) ++GL_Extensions;
2153         start = GL_Extensions;
2154         while (!isspace(*GL_Extensions) && *GL_Extensions) ++GL_Extensions;
2155
2156         len = GL_Extensions - start;
2157         if (!len || len >= sizeof(current_ext)) continue;
2158
2159         memcpy(current_ext, start, len);
2160         current_ext[len] = '\0';
2161         TRACE_(d3d_caps)("- %s\n", debugstr_a(current_ext));
2162
2163         for (i = 0; i < (sizeof(EXTENSION_MAP) / sizeof(*EXTENSION_MAP)); ++i)
2164         {
2165             if (!strcmp(current_ext, EXTENSION_MAP[i].extension_string))
2166             {
2167                 TRACE_(d3d_caps)(" FOUND: %s support.\n", EXTENSION_MAP[i].extension_string);
2168                 gl_info->supported[EXTENSION_MAP[i].extension] = TRUE;
2169                 break;
2170             }
2171         }
2172     }
2173
2174     /* Now work out what GL support this card really has */
2175 #define USE_GL_FUNC(type, pfn, ext, replace) \
2176 { \
2177     DWORD ver = ver_for_ext(ext); \
2178     if (gl_info->supported[ext]) gl_info->pfn = (type)pwglGetProcAddress(#pfn); \
2179     else if (ver && ver <= gl_version) gl_info->pfn = (type)pwglGetProcAddress(#replace); \
2180     else gl_info->pfn = NULL; \
2181 }
2182     GL_EXT_FUNCS_GEN;
2183 #undef USE_GL_FUNC
2184
2185 #define USE_GL_FUNC(type, pfn, ext, replace) gl_info->pfn = (type)pwglGetProcAddress(#pfn);
2186     WGL_EXT_FUNCS_GEN;
2187 #undef USE_GL_FUNC
2188
2189     ENTER_GL();
2190
2191     /* Now mark all the extensions supported which are included in the opengl core version. Do this *after*
2192      * loading the functions, otherwise the code above will load the extension entry points instead of the
2193      * core functions, which may not work. */
2194     for (i = 0; i < (sizeof(EXTENSION_MAP) / sizeof(*EXTENSION_MAP)); ++i)
2195     {
2196         if (!gl_info->supported[EXTENSION_MAP[i].extension]
2197                 && EXTENSION_MAP[i].version <= gl_version && EXTENSION_MAP[i].version)
2198         {
2199             TRACE_(d3d_caps)(" GL CORE: %s support.\n", EXTENSION_MAP[i].extension_string);
2200             gl_info->supported[EXTENSION_MAP[i].extension] = TRUE;
2201         }
2202     }
2203
2204     if (gl_info->supported[APPLE_FENCE])
2205     {
2206         /* GL_NV_fence and GL_APPLE_fence provide the same functionality basically.
2207          * The apple extension interacts with some other apple exts. Disable the NV
2208          * extension if the apple one is support to prevent confusion in other parts
2209          * of the code. */
2210         gl_info->supported[NV_FENCE] = FALSE;
2211     }
2212     if (gl_info->supported[APPLE_FLOAT_PIXELS])
2213     {
2214         /* GL_APPLE_float_pixels == GL_ARB_texture_float + GL_ARB_half_float_pixel
2215          *
2216          * The enums are the same:
2217          * GL_RGBA16F_ARB     = GL_RGBA_FLOAT16_APPLE = 0x881A
2218          * GL_RGB16F_ARB      = GL_RGB_FLOAT16_APPLE  = 0x881B
2219          * GL_RGBA32F_ARB     = GL_RGBA_FLOAT32_APPLE = 0x8814
2220          * GL_RGB32F_ARB      = GL_RGB_FLOAT32_APPLE  = 0x8815
2221          * GL_HALF_FLOAT_ARB  = GL_HALF_APPLE         = 0x140B
2222          */
2223         if (!gl_info->supported[ARB_TEXTURE_FLOAT])
2224         {
2225             TRACE_(d3d_caps)(" IMPLIED: GL_ARB_texture_float support(from GL_APPLE_float_pixels.\n");
2226             gl_info->supported[ARB_TEXTURE_FLOAT] = TRUE;
2227         }
2228         if (!gl_info->supported[ARB_HALF_FLOAT_PIXEL])
2229         {
2230             TRACE_(d3d_caps)(" IMPLIED: GL_ARB_half_float_pixel support(from GL_APPLE_float_pixels.\n");
2231             gl_info->supported[ARB_HALF_FLOAT_PIXEL] = TRUE;
2232         }
2233     }
2234     if (gl_info->supported[ARB_MAP_BUFFER_RANGE])
2235     {
2236         /* GL_ARB_map_buffer_range and GL_APPLE_flush_buffer_range provide the same
2237          * functionality. Prefer the ARB extension */
2238         gl_info->supported[APPLE_FLUSH_BUFFER_RANGE] = FALSE;
2239     }
2240     if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
2241     {
2242         TRACE_(d3d_caps)(" IMPLIED: NVIDIA (NV) Texture Gen Reflection support.\n");
2243         gl_info->supported[NV_TEXGEN_REFLECTION] = TRUE;
2244     }
2245     if (!gl_info->supported[ARB_DEPTH_CLAMP] && gl_info->supported[NV_DEPTH_CLAMP])
2246     {
2247         TRACE_(d3d_caps)(" IMPLIED: ARB_depth_clamp support (by NV_depth_clamp).\n");
2248         gl_info->supported[ARB_DEPTH_CLAMP] = TRUE;
2249     }
2250     if (!gl_info->supported[ARB_VERTEX_ARRAY_BGRA] && gl_info->supported[EXT_VERTEX_ARRAY_BGRA])
2251     {
2252         TRACE_(d3d_caps)(" IMPLIED: ARB_vertex_array_bgra support (by EXT_vertex_array_bgra).\n");
2253         gl_info->supported[ARB_VERTEX_ARRAY_BGRA] = TRUE;
2254     }
2255     if (gl_info->supported[NV_TEXTURE_SHADER2])
2256     {
2257         if (gl_info->supported[NV_REGISTER_COMBINERS])
2258         {
2259             /* Also disable ATI_FRAGMENT_SHADER if register combiners and texture_shader2
2260              * are supported. The nv extensions provide the same functionality as the
2261              * ATI one, and a bit more(signed pixelformats). */
2262             gl_info->supported[ATI_FRAGMENT_SHADER] = FALSE;
2263         }
2264     }
2265
2266     if (gl_info->supported[NV_REGISTER_COMBINERS])
2267     {
2268         glGetIntegerv(GL_MAX_GENERAL_COMBINERS_NV, &gl_max);
2269         gl_info->limits.general_combiners = gl_max;
2270         TRACE_(d3d_caps)("Max general combiners: %d.\n", gl_max);
2271     }
2272     if (gl_info->supported[ARB_DRAW_BUFFERS])
2273     {
2274         glGetIntegerv(GL_MAX_DRAW_BUFFERS_ARB, &gl_max);
2275         gl_info->limits.buffers = gl_max;
2276         TRACE_(d3d_caps)("Max draw buffers: %u.\n", gl_max);
2277     }
2278     if (gl_info->supported[ARB_MULTITEXTURE])
2279     {
2280         glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, &gl_max);
2281         gl_info->limits.textures = min(MAX_TEXTURES, gl_max);
2282         TRACE_(d3d_caps)("Max textures: %d.\n", gl_info->limits.textures);
2283
2284         if (gl_info->supported[ARB_FRAGMENT_PROGRAM])
2285         {
2286             GLint tmp;
2287             glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS_ARB, &tmp);
2288             gl_info->limits.fragment_samplers = min(MAX_FRAGMENT_SAMPLERS, tmp);
2289         }
2290         else
2291         {
2292             gl_info->limits.fragment_samplers = max(gl_info->limits.fragment_samplers, gl_max);
2293         }
2294         TRACE_(d3d_caps)("Max fragment samplers: %d.\n", gl_info->limits.fragment_samplers);
2295
2296         if (gl_info->supported[ARB_VERTEX_SHADER])
2297         {
2298             GLint tmp;
2299             glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB, &tmp);
2300             gl_info->limits.vertex_samplers = tmp;
2301             glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB, &tmp);
2302             gl_info->limits.combined_samplers = tmp;
2303
2304             /* Loading GLSL sampler uniforms is much simpler if we can assume that the sampler setup
2305              * is known at shader link time. In a vertex shader + pixel shader combination this isn't
2306              * an issue because then the sampler setup only depends on the two shaders. If a pixel
2307              * shader is used with fixed function vertex processing we're fine too because fixed function
2308              * vertex processing doesn't use any samplers. If fixed function fragment processing is
2309              * used we have to make sure that all vertex sampler setups are valid together with all
2310              * possible fixed function fragment processing setups. This is true if vsamplers + MAX_TEXTURES
2311              * <= max_samplers. This is true on all d3d9 cards that support vtf(gf 6 and gf7 cards).
2312              * dx9 radeon cards do not support vertex texture fetch. DX10 cards have 128 samplers, and
2313              * dx9 is limited to 8 fixed function texture stages and 4 vertex samplers. DX10 does not have
2314              * a fixed function pipeline anymore.
2315              *
2316              * So this is just a check to check that our assumption holds true. If not, write a warning
2317              * and reduce the number of vertex samplers or probably disable vertex texture fetch. */
2318             if (gl_info->limits.vertex_samplers && gl_info->limits.combined_samplers < 12
2319                     && MAX_TEXTURES + gl_info->limits.vertex_samplers > gl_info->limits.combined_samplers)
2320             {
2321                 FIXME("OpenGL implementation supports %u vertex samplers and %u total samplers.\n",
2322                         gl_info->limits.vertex_samplers, gl_info->limits.combined_samplers);
2323                 FIXME("Expected vertex samplers + MAX_TEXTURES(=8) > combined_samplers.\n");
2324                 if (gl_info->limits.combined_samplers > MAX_TEXTURES)
2325                     gl_info->limits.vertex_samplers = gl_info->limits.combined_samplers - MAX_TEXTURES;
2326                 else
2327                     gl_info->limits.vertex_samplers = 0;
2328             }
2329         }
2330         else
2331         {
2332             gl_info->limits.combined_samplers = gl_info->limits.fragment_samplers;
2333         }
2334         TRACE_(d3d_caps)("Max vertex samplers: %u.\n", gl_info->limits.vertex_samplers);
2335         TRACE_(d3d_caps)("Max combined samplers: %u.\n", gl_info->limits.combined_samplers);
2336     }
2337     if (gl_info->supported[ARB_VERTEX_BLEND])
2338     {
2339         glGetIntegerv(GL_MAX_VERTEX_UNITS_ARB, &gl_max);
2340         gl_info->limits.blends = gl_max;
2341         TRACE_(d3d_caps)("Max blends: %u.\n", gl_info->limits.blends);
2342     }
2343     if (gl_info->supported[EXT_TEXTURE3D])
2344     {
2345         glGetIntegerv(GL_MAX_3D_TEXTURE_SIZE_EXT, &gl_max);
2346         gl_info->limits.texture3d_size = gl_max;
2347         TRACE_(d3d_caps)("Max texture3D size: %d.\n", gl_info->limits.texture3d_size);
2348     }
2349     if (gl_info->supported[EXT_TEXTURE_FILTER_ANISOTROPIC])
2350     {
2351         glGetIntegerv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &gl_max);
2352         gl_info->limits.anisotropy = gl_max;
2353         TRACE_(d3d_caps)("Max anisotropy: %d.\n", gl_info->limits.anisotropy);
2354     }
2355     if (gl_info->supported[ARB_FRAGMENT_PROGRAM])
2356     {
2357         GL_EXTCALL(glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_ENV_PARAMETERS_ARB, &gl_max));
2358         gl_info->limits.arb_ps_float_constants = gl_max;
2359         TRACE_(d3d_caps)("Max ARB_FRAGMENT_PROGRAM float constants: %d.\n", gl_info->limits.arb_ps_float_constants);
2360         GL_EXTCALL(glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB, &gl_max));
2361         gl_info->limits.arb_ps_native_constants = gl_max;
2362         TRACE_(d3d_caps)("Max ARB_FRAGMENT_PROGRAM native float constants: %d.\n",
2363                 gl_info->limits.arb_ps_native_constants);
2364         GL_EXTCALL(glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB, &gl_max));
2365         gl_info->limits.arb_ps_temps = gl_max;
2366         TRACE_(d3d_caps)("Max ARB_FRAGMENT_PROGRAM native temporaries: %d.\n", gl_info->limits.arb_ps_temps);
2367         GL_EXTCALL(glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB, &gl_max));
2368         gl_info->limits.arb_ps_instructions = gl_max;
2369         TRACE_(d3d_caps)("Max ARB_FRAGMENT_PROGRAM native instructions: %d.\n", gl_info->limits.arb_ps_instructions);
2370         GL_EXTCALL(glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB, &gl_max));
2371         gl_info->limits.arb_ps_local_constants = gl_max;
2372         TRACE_(d3d_caps)("Max ARB_FRAGMENT_PROGRAM local parameters: %d.\n", gl_info->limits.arb_ps_instructions);
2373     }
2374     if (gl_info->supported[ARB_VERTEX_PROGRAM])
2375     {
2376         GL_EXTCALL(glGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_MAX_PROGRAM_ENV_PARAMETERS_ARB, &gl_max));
2377         gl_info->limits.arb_vs_float_constants = gl_max;
2378         TRACE_(d3d_caps)("Max ARB_VERTEX_PROGRAM float constants: %d.\n", gl_info->limits.arb_vs_float_constants);
2379         GL_EXTCALL(glGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB, &gl_max));
2380         gl_info->limits.arb_vs_native_constants = gl_max;
2381         TRACE_(d3d_caps)("Max ARB_VERTEX_PROGRAM native float constants: %d.\n",
2382                 gl_info->limits.arb_vs_native_constants);
2383         GL_EXTCALL(glGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB, &gl_max));
2384         gl_info->limits.arb_vs_temps = gl_max;
2385         TRACE_(d3d_caps)("Max ARB_VERTEX_PROGRAM native temporaries: %d.\n", gl_info->limits.arb_vs_temps);
2386         GL_EXTCALL(glGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB, &gl_max));
2387         gl_info->limits.arb_vs_instructions = gl_max;
2388         TRACE_(d3d_caps)("Max ARB_VERTEX_PROGRAM native instructions: %d.\n", gl_info->limits.arb_vs_instructions);
2389
2390         if (test_arb_vs_offset_limit(gl_info)) gl_info->quirks |= WINED3D_QUIRK_ARB_VS_OFFSET_LIMIT;
2391     }
2392     if (gl_info->supported[ARB_VERTEX_SHADER])
2393     {
2394         glGetIntegerv(GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB, &gl_max);
2395         gl_info->limits.glsl_vs_float_constants = gl_max / 4;
2396         TRACE_(d3d_caps)("Max ARB_VERTEX_SHADER float constants: %u.\n", gl_info->limits.glsl_vs_float_constants);
2397     }
2398     if (gl_info->supported[ARB_FRAGMENT_SHADER])
2399     {
2400         glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB, &gl_max);
2401         gl_info->limits.glsl_ps_float_constants = gl_max / 4;
2402         TRACE_(d3d_caps)("Max ARB_FRAGMENT_SHADER float constants: %u.\n", gl_info->limits.glsl_ps_float_constants);
2403         glGetIntegerv(GL_MAX_VARYING_FLOATS_ARB, &gl_max);
2404         gl_info->limits.glsl_varyings = gl_max;
2405         TRACE_(d3d_caps)("Max GLSL varyings: %u (%u 4 component varyings).\n", gl_max, gl_max / 4);
2406     }
2407     if (gl_info->supported[ARB_SHADING_LANGUAGE_100])
2408     {
2409         const char *str = (const char *)glGetString(GL_SHADING_LANGUAGE_VERSION_ARB);
2410         TRACE_(d3d_caps)("GLSL version string: %s.\n", debugstr_a(str));
2411     }
2412     if (gl_info->supported[NV_LIGHT_MAX_EXPONENT])
2413     {
2414         glGetFloatv(GL_MAX_SHININESS_NV, &gl_info->limits.shininess);
2415     }
2416     else
2417     {
2418         gl_info->limits.shininess = 128.0f;
2419     }
2420     if (gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO])
2421     {
2422         /* If we have full NP2 texture support, disable
2423          * GL_ARB_texture_rectangle because we will never use it.
2424          * This saves a few redundant glDisable calls. */
2425         gl_info->supported[ARB_TEXTURE_RECTANGLE] = FALSE;
2426     }
2427     if (gl_info->supported[ATI_FRAGMENT_SHADER])
2428     {
2429         /* Disable NV_register_combiners and fragment shader if this is supported.
2430          * generally the NV extensions are preferred over the ATI ones, and this
2431          * extension is disabled if register_combiners and texture_shader2 are both
2432          * supported. So we reach this place only if we have incomplete NV dxlevel 8
2433          * fragment processing support. */
2434         gl_info->supported[NV_REGISTER_COMBINERS] = FALSE;
2435         gl_info->supported[NV_REGISTER_COMBINERS2] = FALSE;
2436         gl_info->supported[NV_TEXTURE_SHADER] = FALSE;
2437         gl_info->supported[NV_TEXTURE_SHADER2] = FALSE;
2438     }
2439     if (gl_info->supported[NV_HALF_FLOAT])
2440     {
2441         /* GL_ARB_half_float_vertex is a subset of GL_NV_half_float. */
2442         gl_info->supported[ARB_HALF_FLOAT_VERTEX] = TRUE;
2443     }
2444     if (gl_info->supported[ARB_POINT_SPRITE])
2445     {
2446         gl_info->limits.point_sprite_units = gl_info->limits.textures;
2447     }
2448     else
2449     {
2450         gl_info->limits.point_sprite_units = 0;
2451     }
2452     checkGLcall("extension detection");
2453
2454     LEAVE_GL();
2455
2456     adapter->fragment_pipe = select_fragment_implementation(adapter);
2457     adapter->shader_backend = select_shader_backend(adapter);
2458     adapter->blitter = select_blit_implementation(adapter);
2459
2460     adapter->fragment_pipe->get_caps(gl_info, &fragment_caps);
2461     gl_info->limits.texture_stages = fragment_caps.MaxTextureBlendStages;
2462     TRACE_(d3d_caps)("Max texture stages: %u.\n", gl_info->limits.texture_stages);
2463
2464     /* In some cases the number of texture stages can be larger than the number
2465      * of samplers. The GF4 for example can use only 2 samplers (no fragment
2466      * shaders), but 8 texture stages (register combiners). */
2467     gl_info->limits.sampler_stages = max(gl_info->limits.fragment_samplers, gl_info->limits.texture_stages);
2468
2469     if (gl_info->supported[ARB_FRAMEBUFFER_OBJECT])
2470     {
2471         gl_info->fbo_ops.glIsRenderbuffer = gl_info->glIsRenderbuffer;
2472         gl_info->fbo_ops.glBindRenderbuffer = gl_info->glBindRenderbuffer;
2473         gl_info->fbo_ops.glDeleteRenderbuffers = gl_info->glDeleteRenderbuffers;
2474         gl_info->fbo_ops.glGenRenderbuffers = gl_info->glGenRenderbuffers;
2475         gl_info->fbo_ops.glRenderbufferStorage = gl_info->glRenderbufferStorage;
2476         gl_info->fbo_ops.glRenderbufferStorageMultisample = gl_info->glRenderbufferStorageMultisample;
2477         gl_info->fbo_ops.glGetRenderbufferParameteriv = gl_info->glGetRenderbufferParameteriv;
2478         gl_info->fbo_ops.glIsFramebuffer = gl_info->glIsFramebuffer;
2479         gl_info->fbo_ops.glBindFramebuffer = gl_info->glBindFramebuffer;
2480         gl_info->fbo_ops.glDeleteFramebuffers = gl_info->glDeleteFramebuffers;
2481         gl_info->fbo_ops.glGenFramebuffers = gl_info->glGenFramebuffers;
2482         gl_info->fbo_ops.glCheckFramebufferStatus = gl_info->glCheckFramebufferStatus;
2483         gl_info->fbo_ops.glFramebufferTexture1D = gl_info->glFramebufferTexture1D;
2484         gl_info->fbo_ops.glFramebufferTexture2D = gl_info->glFramebufferTexture2D;
2485         gl_info->fbo_ops.glFramebufferTexture3D = gl_info->glFramebufferTexture3D;
2486         gl_info->fbo_ops.glFramebufferRenderbuffer = gl_info->glFramebufferRenderbuffer;
2487         gl_info->fbo_ops.glGetFramebufferAttachmentParameteriv = gl_info->glGetFramebufferAttachmentParameteriv;
2488         gl_info->fbo_ops.glBlitFramebuffer = gl_info->glBlitFramebuffer;
2489         gl_info->fbo_ops.glGenerateMipmap = gl_info->glGenerateMipmap;
2490     }
2491     else
2492     {
2493         if (gl_info->supported[EXT_FRAMEBUFFER_OBJECT])
2494         {
2495             gl_info->fbo_ops.glIsRenderbuffer = gl_info->glIsRenderbufferEXT;
2496             gl_info->fbo_ops.glBindRenderbuffer = gl_info->glBindRenderbufferEXT;
2497             gl_info->fbo_ops.glDeleteRenderbuffers = gl_info->glDeleteRenderbuffersEXT;
2498             gl_info->fbo_ops.glGenRenderbuffers = gl_info->glGenRenderbuffersEXT;
2499             gl_info->fbo_ops.glRenderbufferStorage = gl_info->glRenderbufferStorageEXT;
2500             gl_info->fbo_ops.glGetRenderbufferParameteriv = gl_info->glGetRenderbufferParameterivEXT;
2501             gl_info->fbo_ops.glIsFramebuffer = gl_info->glIsFramebufferEXT;
2502             gl_info->fbo_ops.glBindFramebuffer = gl_info->glBindFramebufferEXT;
2503             gl_info->fbo_ops.glDeleteFramebuffers = gl_info->glDeleteFramebuffersEXT;
2504             gl_info->fbo_ops.glGenFramebuffers = gl_info->glGenFramebuffersEXT;
2505             gl_info->fbo_ops.glCheckFramebufferStatus = gl_info->glCheckFramebufferStatusEXT;
2506             gl_info->fbo_ops.glFramebufferTexture1D = gl_info->glFramebufferTexture1DEXT;
2507             gl_info->fbo_ops.glFramebufferTexture2D = gl_info->glFramebufferTexture2DEXT;
2508             gl_info->fbo_ops.glFramebufferTexture3D = gl_info->glFramebufferTexture3DEXT;
2509             gl_info->fbo_ops.glFramebufferRenderbuffer = gl_info->glFramebufferRenderbufferEXT;
2510             gl_info->fbo_ops.glGetFramebufferAttachmentParameteriv = gl_info->glGetFramebufferAttachmentParameterivEXT;
2511             gl_info->fbo_ops.glGenerateMipmap = gl_info->glGenerateMipmapEXT;
2512         }
2513         else if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
2514         {
2515             WARN_(d3d_caps)("Framebuffer objects not supported, falling back to backbuffer offscreen rendering mode.\n");
2516             wined3d_settings.offscreen_rendering_mode = ORM_BACKBUFFER;
2517         }
2518         if (gl_info->supported[EXT_FRAMEBUFFER_BLIT])
2519         {
2520             gl_info->fbo_ops.glBlitFramebuffer = gl_info->glBlitFramebufferEXT;
2521         }
2522         if (gl_info->supported[EXT_FRAMEBUFFER_MULTISAMPLE])
2523         {
2524             gl_info->fbo_ops.glRenderbufferStorageMultisample = gl_info->glRenderbufferStorageMultisampleEXT;
2525         }
2526     }
2527
2528     /* MRTs are currently only supported when FBOs are used. */
2529     if (wined3d_settings.offscreen_rendering_mode != ORM_FBO)
2530     {
2531         gl_info->limits.buffers = 1;
2532     }
2533
2534     gl_vendor = wined3d_guess_gl_vendor(gl_info, gl_vendor_str, gl_renderer_str);
2535     card_vendor = wined3d_guess_card_vendor(gl_vendor_str, gl_renderer_str);
2536     TRACE_(d3d_caps)("found GL_VENDOR (%s)->(0x%04x/0x%04x)\n", debugstr_a(gl_vendor_str), gl_vendor, card_vendor);
2537
2538     device = wined3d_guess_card(gl_info, gl_renderer_str, &gl_vendor, &card_vendor, &vidmem);
2539     TRACE_(d3d_caps)("FOUND (fake) card: 0x%x (vendor id), 0x%x (device id)\n", card_vendor, device);
2540
2541     /* If we have an estimate use it, else default to 64MB;  */
2542     if(vidmem)
2543         gl_info->vidmem = vidmem*1024*1024; /* convert from MBs to bytes */
2544     else
2545         gl_info->vidmem = WINE_DEFAULT_VIDMEM;
2546
2547     gl_info->wrap_lookup[WINED3DTADDRESS_WRAP - WINED3DTADDRESS_WRAP] = GL_REPEAT;
2548     gl_info->wrap_lookup[WINED3DTADDRESS_MIRROR - WINED3DTADDRESS_WRAP] =
2549             gl_info->supported[ARB_TEXTURE_MIRRORED_REPEAT] ? GL_MIRRORED_REPEAT_ARB : GL_REPEAT;
2550     gl_info->wrap_lookup[WINED3DTADDRESS_CLAMP - WINED3DTADDRESS_WRAP] = GL_CLAMP_TO_EDGE;
2551     gl_info->wrap_lookup[WINED3DTADDRESS_BORDER - WINED3DTADDRESS_WRAP] =
2552             gl_info->supported[ARB_TEXTURE_BORDER_CLAMP] ? GL_CLAMP_TO_BORDER_ARB : GL_REPEAT;
2553     gl_info->wrap_lookup[WINED3DTADDRESS_MIRRORONCE - WINED3DTADDRESS_WRAP] =
2554             gl_info->supported[ATI_TEXTURE_MIRROR_ONCE] ? GL_MIRROR_CLAMP_TO_EDGE_ATI : GL_REPEAT;
2555
2556     /* Make sure there's an active HDC else the WGL extensions will fail */
2557     hdc = pwglGetCurrentDC();
2558     if (hdc) {
2559         /* Not all GL drivers might offer WGL extensions e.g. VirtualBox */
2560         if(GL_EXTCALL(wglGetExtensionsStringARB))
2561             WGL_Extensions = GL_EXTCALL(wglGetExtensionsStringARB(hdc));
2562
2563         if (NULL == WGL_Extensions) {
2564             ERR("   WGL_Extensions returns NULL\n");
2565         } else {
2566             TRACE_(d3d_caps)("WGL_Extensions reported:\n");
2567             while (*WGL_Extensions != 0x00) {
2568                 const char *Start;
2569                 char ThisExtn[256];
2570
2571                 while (isspace(*WGL_Extensions)) WGL_Extensions++;
2572                 Start = WGL_Extensions;
2573                 while (!isspace(*WGL_Extensions) && *WGL_Extensions != 0x00) {
2574                     WGL_Extensions++;
2575                 }
2576
2577                 len = WGL_Extensions - Start;
2578                 if (len == 0 || len >= sizeof(ThisExtn))
2579                     continue;
2580
2581                 memcpy(ThisExtn, Start, len);
2582                 ThisExtn[len] = '\0';
2583                 TRACE_(d3d_caps)("- %s\n", debugstr_a(ThisExtn));
2584
2585                 if (!strcmp(ThisExtn, "WGL_ARB_pixel_format")) {
2586                     gl_info->supported[WGL_ARB_PIXEL_FORMAT] = TRUE;
2587                     TRACE_(d3d_caps)("FOUND: WGL_ARB_pixel_format support\n");
2588                 }
2589                 if (!strcmp(ThisExtn, "WGL_WINE_pixel_format_passthrough")) {
2590                     gl_info->supported[WGL_WINE_PIXEL_FORMAT_PASSTHROUGH] = TRUE;
2591                     TRACE_(d3d_caps)("FOUND: WGL_WINE_pixel_format_passthrough support\n");
2592                 }
2593             }
2594         }
2595     }
2596
2597     fixup_extensions(gl_info, gl_renderer_str, gl_vendor, card_vendor, device);
2598     init_driver_info(driver_info, card_vendor, device);
2599     add_gl_compat_wrappers(gl_info);
2600
2601     return TRUE;
2602 }
2603
2604 /**********************************************************
2605  * IWineD3D implementation follows
2606  **********************************************************/
2607
2608 static UINT     WINAPI IWineD3DImpl_GetAdapterCount (IWineD3D *iface) {
2609     IWineD3DImpl *This = (IWineD3DImpl *)iface;
2610
2611     TRACE_(d3d_caps)("(%p): Reporting %u adapters\n", This, This->adapter_count);
2612
2613     return This->adapter_count;
2614 }
2615
2616 static HRESULT WINAPI IWineD3DImpl_RegisterSoftwareDevice(IWineD3D *iface, void *init_function)
2617 {
2618     FIXME("iface %p, init_function %p stub!\n", iface, init_function);
2619
2620     return WINED3D_OK;
2621 }
2622
2623 static HMONITOR WINAPI IWineD3DImpl_GetAdapterMonitor(IWineD3D *iface, UINT Adapter) {
2624     IWineD3DImpl *This = (IWineD3DImpl *)iface;
2625
2626     TRACE_(d3d_caps)("(%p)->(%d)\n", This, Adapter);
2627
2628     if (Adapter >= IWineD3DImpl_GetAdapterCount(iface)) {
2629         return NULL;
2630     }
2631
2632     return MonitorFromPoint(This->adapters[Adapter].monitorPoint, MONITOR_DEFAULTTOPRIMARY);
2633 }
2634
2635 /* FIXME: GetAdapterModeCount and EnumAdapterModes currently only returns modes
2636      of the same bpp but different resolutions                                  */
2637
2638 /* Note: dx9 supplies a format. Calls from d3d8 supply WINED3DFMT_UNKNOWN */
2639 static UINT     WINAPI IWineD3DImpl_GetAdapterModeCount(IWineD3D *iface, UINT Adapter, WINED3DFORMAT Format) {
2640     IWineD3DImpl *This = (IWineD3DImpl *)iface;
2641     TRACE_(d3d_caps)("(%p}->(Adapter: %d, Format: %s)\n", This, Adapter, debug_d3dformat(Format));
2642
2643     if (Adapter >= IWineD3D_GetAdapterCount(iface)) {
2644         return 0;
2645     }
2646
2647     /* TODO: Store modes per adapter and read it from the adapter structure */
2648     if (Adapter == 0) { /* Display */
2649         const struct wined3d_format_desc *format_desc = getFormatDescEntry(Format, &This->adapters[Adapter].gl_info);
2650         UINT format_bits = format_desc->byte_count * CHAR_BIT;
2651         unsigned int i = 0;
2652         unsigned int j = 0;
2653         DEVMODEW mode;
2654
2655         memset(&mode, 0, sizeof(mode));
2656         mode.dmSize = sizeof(mode);
2657
2658         while (EnumDisplaySettingsExW(NULL, j, &mode, 0))
2659         {
2660             ++j;
2661
2662             if (Format == WINED3DFMT_UNKNOWN)
2663             {
2664                 /* This is for D3D8, do not enumerate P8 here */
2665                 if (mode.dmBitsPerPel == 32 || mode.dmBitsPerPel == 16) ++i;
2666             }
2667             else if (mode.dmBitsPerPel == format_bits)
2668             {
2669                 ++i;
2670             }
2671         }
2672
2673         TRACE_(d3d_caps)("(%p}->(Adapter: %d) => %d (out of %d)\n", This, Adapter, i, j);
2674         return i;
2675     } else {
2676         FIXME_(d3d_caps)("Adapter not primary display\n");
2677     }
2678     return 0;
2679 }
2680
2681 /* Note: dx9 supplies a format. Calls from d3d8 supply WINED3DFMT_UNKNOWN */
2682 static HRESULT WINAPI IWineD3DImpl_EnumAdapterModes(IWineD3D *iface, UINT Adapter, WINED3DFORMAT Format, UINT Mode, WINED3DDISPLAYMODE* pMode) {
2683     IWineD3DImpl *This = (IWineD3DImpl *)iface;
2684     TRACE_(d3d_caps)("(%p}->(Adapter:%d, mode:%d, pMode:%p, format:%s)\n", This, Adapter, Mode, pMode, debug_d3dformat(Format));
2685
2686     /* Validate the parameters as much as possible */
2687     if (NULL == pMode ||
2688         Adapter >= IWineD3DImpl_GetAdapterCount(iface) ||
2689         Mode    >= IWineD3DImpl_GetAdapterModeCount(iface, Adapter, Format)) {
2690         return WINED3DERR_INVALIDCALL;
2691     }
2692
2693     /* TODO: Store modes per adapter and read it from the adapter structure */
2694     if (Adapter == 0)
2695     {
2696         const struct wined3d_format_desc *format_desc = getFormatDescEntry(Format, &This->adapters[Adapter].gl_info);
2697         UINT format_bits = format_desc->byte_count * CHAR_BIT;
2698         DEVMODEW DevModeW;
2699         int ModeIdx = 0;
2700         UINT i = 0;
2701         int j = 0;
2702
2703         ZeroMemory(&DevModeW, sizeof(DevModeW));
2704         DevModeW.dmSize = sizeof(DevModeW);
2705
2706         /* If we are filtering to a specific format (D3D9), then need to skip
2707            all unrelated modes, but if mode is irrelevant (D3D8), then we can
2708            just count through the ones with valid bit depths */
2709         while ((i<=Mode) && EnumDisplaySettingsExW(NULL, j++, &DevModeW, 0))
2710         {
2711             if (Format == WINED3DFMT_UNKNOWN)
2712             {
2713                 /* This is for D3D8, do not enumerate P8 here */
2714                 if (DevModeW.dmBitsPerPel == 32 || DevModeW.dmBitsPerPel == 16) ++i;
2715             }
2716             else if (DevModeW.dmBitsPerPel == format_bits)
2717             {
2718                 ++i;
2719             }
2720         }
2721
2722         if (i == 0) {
2723             TRACE_(d3d_caps)("No modes found for format (%x - %s)\n", Format, debug_d3dformat(Format));
2724             return WINED3DERR_INVALIDCALL;
2725         }
2726         ModeIdx = j - 1;
2727
2728         /* Now get the display mode via the calculated index */
2729         if (EnumDisplaySettingsExW(NULL, ModeIdx, &DevModeW, 0)) {
2730             pMode->Width        = DevModeW.dmPelsWidth;
2731             pMode->Height       = DevModeW.dmPelsHeight;
2732             pMode->RefreshRate  = DEFAULT_REFRESH_RATE;
2733             if (DevModeW.dmFields & DM_DISPLAYFREQUENCY)
2734                 pMode->RefreshRate = DevModeW.dmDisplayFrequency;
2735
2736             if (Format == WINED3DFMT_UNKNOWN) {
2737                 pMode->Format = pixelformat_for_depth(DevModeW.dmBitsPerPel);
2738             } else {
2739                 pMode->Format = Format;
2740             }
2741         } else {
2742             TRACE_(d3d_caps)("Requested mode out of range %d\n", Mode);
2743             return WINED3DERR_INVALIDCALL;
2744         }
2745
2746         TRACE_(d3d_caps)("W %d H %d rr %d fmt (%x - %s) bpp %u\n", pMode->Width, pMode->Height,
2747                 pMode->RefreshRate, pMode->Format, debug_d3dformat(pMode->Format),
2748                 DevModeW.dmBitsPerPel);
2749
2750     }
2751     else
2752     {
2753         FIXME_(d3d_caps)("Adapter not primary display\n");
2754     }
2755
2756     return WINED3D_OK;
2757 }
2758
2759 static HRESULT WINAPI IWineD3DImpl_GetAdapterDisplayMode(IWineD3D *iface, UINT Adapter, WINED3DDISPLAYMODE *pMode)
2760 {
2761     TRACE("iface %p, adapter_idx %u, display_mode %p.\n", iface, Adapter, pMode);
2762
2763     if (NULL == pMode ||
2764         Adapter >= IWineD3D_GetAdapterCount(iface)) {
2765         return WINED3DERR_INVALIDCALL;
2766     }
2767
2768     if (Adapter == 0) { /* Display */
2769         int bpp = 0;
2770         DEVMODEW DevModeW;
2771
2772         ZeroMemory(&DevModeW, sizeof(DevModeW));
2773         DevModeW.dmSize = sizeof(DevModeW);
2774
2775         EnumDisplaySettingsExW(NULL, ENUM_CURRENT_SETTINGS, &DevModeW, 0);
2776         pMode->Width        = DevModeW.dmPelsWidth;
2777         pMode->Height       = DevModeW.dmPelsHeight;
2778         bpp                 = DevModeW.dmBitsPerPel;
2779         pMode->RefreshRate  = DEFAULT_REFRESH_RATE;
2780         if (DevModeW.dmFields&DM_DISPLAYFREQUENCY)
2781         {
2782             pMode->RefreshRate = DevModeW.dmDisplayFrequency;
2783         }
2784
2785         pMode->Format = pixelformat_for_depth(bpp);
2786     } else {
2787         FIXME_(d3d_caps)("Adapter not primary display\n");
2788     }
2789
2790     TRACE_(d3d_caps)("returning w:%d, h:%d, ref:%d, fmt:%s\n", pMode->Width,
2791           pMode->Height, pMode->RefreshRate, debug_d3dformat(pMode->Format));
2792     return WINED3D_OK;
2793 }
2794
2795 /* NOTE: due to structure differences between dx8 and dx9 D3DADAPTER_IDENTIFIER,
2796    and fields being inserted in the middle, a new structure is used in place    */
2797 static HRESULT WINAPI IWineD3DImpl_GetAdapterIdentifier(IWineD3D *iface, UINT Adapter, DWORD Flags,
2798                                                    WINED3DADAPTER_IDENTIFIER* pIdentifier) {
2799     IWineD3DImpl *This = (IWineD3DImpl *)iface;
2800     struct wined3d_adapter *adapter;
2801     size_t len;
2802
2803     TRACE_(d3d_caps)("(%p}->(Adapter: %d, Flags: %x, pId=%p)\n", This, Adapter, Flags, pIdentifier);
2804
2805     if (Adapter >= IWineD3D_GetAdapterCount(iface)) {
2806         return WINED3DERR_INVALIDCALL;
2807     }
2808
2809     adapter = &This->adapters[Adapter];
2810
2811     /* Return the information requested */
2812     TRACE_(d3d_caps)("device/Vendor Name and Version detection using FillGLCaps\n");
2813
2814     if (pIdentifier->driver_size)
2815     {
2816         const char *name = adapter->driver_info.name;
2817         len = min(strlen(name), pIdentifier->driver_size - 1);
2818         memcpy(pIdentifier->driver, name, len);
2819         pIdentifier->driver[len] = '\0';
2820     }
2821
2822     if (pIdentifier->description_size)
2823     {
2824         const char *description = adapter->driver_info.description;
2825         len = min(strlen(description), pIdentifier->description_size - 1);
2826         memcpy(pIdentifier->description, description, len);
2827         pIdentifier->description[len] = '\0';
2828     }
2829
2830     /* Note that d3d8 doesn't supply a device name. */
2831     if (pIdentifier->device_name_size)
2832     {
2833         static const char *device_name = "\\\\.\\DISPLAY1"; /* FIXME: May depend on desktop? */
2834
2835         len = strlen(device_name);
2836         if (len >= pIdentifier->device_name_size)
2837         {
2838             ERR("Device name size too small.\n");
2839             return WINED3DERR_INVALIDCALL;
2840         }
2841
2842         memcpy(pIdentifier->device_name, device_name, len);
2843         pIdentifier->device_name[len] = '\0';
2844     }
2845
2846     pIdentifier->driver_version.u.HighPart = adapter->driver_info.version_high;
2847     pIdentifier->driver_version.u.LowPart = adapter->driver_info.version_low;
2848     pIdentifier->vendor_id = adapter->driver_info.vendor;
2849     pIdentifier->device_id = adapter->driver_info.device;
2850     pIdentifier->subsystem_id = 0;
2851     pIdentifier->revision = 0;
2852     memcpy(&pIdentifier->device_identifier, &IID_D3DDEVICE_D3DUID, sizeof(pIdentifier->device_identifier));
2853     pIdentifier->whql_level = (Flags & WINED3DENUM_NO_WHQL_LEVEL) ? 0 : 1;
2854     memcpy(&pIdentifier->adapter_luid, &adapter->luid, sizeof(pIdentifier->adapter_luid));
2855     pIdentifier->video_memory = adapter->TextureRam;
2856
2857     return WINED3D_OK;
2858 }
2859
2860 static BOOL IWineD3DImpl_IsPixelFormatCompatibleWithRenderFmt(const struct wined3d_gl_info *gl_info,
2861         const WineD3D_PixelFormat *cfg, const struct wined3d_format_desc *format_desc)
2862 {
2863     short redSize, greenSize, blueSize, alphaSize, colorBits;
2864
2865     if(!cfg)
2866         return FALSE;
2867
2868     if(cfg->iPixelType == WGL_TYPE_RGBA_ARB) { /* Integer RGBA formats */
2869         if (!getColorBits(format_desc, &redSize, &greenSize, &blueSize, &alphaSize, &colorBits))
2870         {
2871             ERR("Unable to check compatibility for Format=%s\n", debug_d3dformat(format_desc->format));
2872             return FALSE;
2873         }
2874
2875         if(cfg->redSize < redSize)
2876             return FALSE;
2877
2878         if(cfg->greenSize < greenSize)
2879             return FALSE;
2880
2881         if(cfg->blueSize < blueSize)
2882             return FALSE;
2883
2884         if(cfg->alphaSize < alphaSize)
2885             return FALSE;
2886
2887         return TRUE;
2888     } else if(cfg->iPixelType == WGL_TYPE_RGBA_FLOAT_ARB) { /* Float RGBA formats; TODO: WGL_NV_float_buffer */
2889         if (format_desc->format == WINED3DFMT_R16_FLOAT)
2890             return (cfg->redSize == 16 && cfg->greenSize == 0 && cfg->blueSize == 0 && cfg->alphaSize == 0);
2891         if (format_desc->format == WINED3DFMT_R16G16_FLOAT)
2892             return (cfg->redSize == 16 && cfg->greenSize == 16 && cfg->blueSize == 0 && cfg->alphaSize == 0);
2893         if (format_desc->format == WINED3DFMT_R16G16B16A16_FLOAT)
2894             return (cfg->redSize == 16 && cfg->greenSize == 16 && cfg->blueSize == 16 && cfg->alphaSize == 16);
2895         if (format_desc->format == WINED3DFMT_R32_FLOAT)
2896             return (cfg->redSize == 32 && cfg->greenSize == 0 && cfg->blueSize == 0 && cfg->alphaSize == 0);
2897         if (format_desc->format == WINED3DFMT_R32G32_FLOAT)
2898             return (cfg->redSize == 32 && cfg->greenSize == 32 && cfg->blueSize == 0 && cfg->alphaSize == 0);
2899         if (format_desc->format == WINED3DFMT_R32G32B32A32_FLOAT)
2900             return (cfg->redSize == 32 && cfg->greenSize == 32 && cfg->blueSize == 32 && cfg->alphaSize == 32);
2901     } else {
2902         /* Probably a color index mode */
2903         return FALSE;
2904     }
2905
2906     return FALSE;
2907 }
2908
2909 static BOOL IWineD3DImpl_IsPixelFormatCompatibleWithDepthFmt(const struct wined3d_gl_info *gl_info,
2910         const WineD3D_PixelFormat *cfg, const struct wined3d_format_desc *format_desc)
2911 {
2912     short depthSize, stencilSize;
2913     BOOL lockable = FALSE;
2914
2915     if(!cfg)
2916         return FALSE;
2917
2918     if (!getDepthStencilBits(format_desc, &depthSize, &stencilSize))
2919     {
2920         ERR("Unable to check compatibility for Format=%s\n", debug_d3dformat(format_desc->format));
2921         return FALSE;
2922     }
2923
2924     if ((format_desc->format == WINED3DFMT_D16_LOCKABLE) || (format_desc->format == WINED3DFMT_D32_FLOAT))
2925         lockable = TRUE;
2926
2927     /* On some modern cards like the Geforce8/9 GLX doesn't offer some dephthstencil formats which D3D9 reports.
2928      * We can safely report 'compatible' formats (e.g. D24 can be used for D16) as long as we aren't dealing with
2929      * a lockable format. This also helps D3D <= 7 as they expect D16 which isn't offered without this on Geforce8 cards. */
2930     if(!(cfg->depthSize == depthSize || (!lockable && cfg->depthSize > depthSize)))
2931         return FALSE;
2932
2933     /* Some cards like Intel i915 ones only offer D24S8 but lots of games also need a format without stencil, so
2934      * allow more stencil bits than requested. */
2935     if(cfg->stencilSize < stencilSize)
2936         return FALSE;
2937
2938     return TRUE;
2939 }
2940
2941 static HRESULT WINAPI IWineD3DImpl_CheckDepthStencilMatch(IWineD3D *iface, UINT Adapter, WINED3DDEVTYPE DeviceType,
2942                                                    WINED3DFORMAT AdapterFormat,
2943                                                    WINED3DFORMAT RenderTargetFormat,
2944                                                    WINED3DFORMAT DepthStencilFormat) {
2945     IWineD3DImpl *This = (IWineD3DImpl *)iface;
2946     int nCfgs;
2947     const WineD3D_PixelFormat *cfgs;
2948     const struct wined3d_adapter *adapter;
2949     const struct wined3d_format_desc *rt_format_desc;
2950     const struct wined3d_format_desc *ds_format_desc;
2951     int it;
2952
2953     WARN_(d3d_caps)("(%p)-> (STUB) (Adptr:%d, DevType:(%x,%s), AdptFmt:(%x,%s), RendrTgtFmt:(%x,%s), DepthStencilFmt:(%x,%s))\n",
2954            This, Adapter,
2955            DeviceType, debug_d3ddevicetype(DeviceType),
2956            AdapterFormat, debug_d3dformat(AdapterFormat),
2957            RenderTargetFormat, debug_d3dformat(RenderTargetFormat),
2958            DepthStencilFormat, debug_d3dformat(DepthStencilFormat));
2959
2960     if (Adapter >= IWineD3D_GetAdapterCount(iface)) {
2961         TRACE("(%p) Failed: Atapter (%u) higher than supported adapters (%u) returning WINED3DERR_INVALIDCALL\n", This, Adapter, IWineD3D_GetAdapterCount(iface));
2962         return WINED3DERR_INVALIDCALL;
2963     }
2964
2965     adapter = &This->adapters[Adapter];
2966     rt_format_desc = getFormatDescEntry(RenderTargetFormat, &adapter->gl_info);
2967     ds_format_desc = getFormatDescEntry(DepthStencilFormat, &adapter->gl_info);
2968     cfgs = adapter->cfgs;
2969     nCfgs = adapter->nCfgs;
2970     for (it = 0; it < nCfgs; ++it) {
2971         if (IWineD3DImpl_IsPixelFormatCompatibleWithRenderFmt(&adapter->gl_info, &cfgs[it], rt_format_desc))
2972         {
2973             if (IWineD3DImpl_IsPixelFormatCompatibleWithDepthFmt(&adapter->gl_info, &cfgs[it], ds_format_desc))
2974             {
2975                 TRACE_(d3d_caps)("(%p) : Formats matched\n", This);
2976                 return WINED3D_OK;
2977             }
2978         }
2979     }
2980     WARN_(d3d_caps)("unsupported format pair: %s and %s\n", debug_d3dformat(RenderTargetFormat), debug_d3dformat(DepthStencilFormat));
2981
2982     return WINED3DERR_NOTAVAILABLE;
2983 }
2984
2985 static HRESULT WINAPI IWineD3DImpl_CheckDeviceMultiSampleType(IWineD3D *iface, UINT Adapter, WINED3DDEVTYPE DeviceType,
2986         WINED3DFORMAT SurfaceFormat, BOOL Windowed, WINED3DMULTISAMPLE_TYPE MultiSampleType, DWORD *pQualityLevels)
2987 {
2988     IWineD3DImpl *This = (IWineD3DImpl *)iface;
2989     const struct wined3d_format_desc *glDesc;
2990     const struct wined3d_adapter *adapter;
2991
2992     TRACE_(d3d_caps)("(%p)-> (Adptr:%d, DevType:(%x,%s), SurfFmt:(%x,%s), Win?%d, MultiSamp:%x, pQual:%p)\n",
2993           This,
2994           Adapter,
2995           DeviceType, debug_d3ddevicetype(DeviceType),
2996           SurfaceFormat, debug_d3dformat(SurfaceFormat),
2997           Windowed,
2998           MultiSampleType,
2999           pQualityLevels);
3000
3001     if (Adapter >= IWineD3D_GetAdapterCount(iface)) {
3002         return WINED3DERR_INVALIDCALL;
3003     }
3004
3005     /* TODO: handle Windowed, add more quality levels */
3006
3007     if (WINED3DMULTISAMPLE_NONE == MultiSampleType) {
3008         if(pQualityLevels) *pQualityLevels = 1;
3009         return WINED3D_OK;
3010     }
3011
3012     /* By default multisampling is disabled right now as it causes issues
3013      * on some Nvidia driver versions and it doesn't work well in combination
3014      * with FBOs yet. */
3015     if(!wined3d_settings.allow_multisampling)
3016         return WINED3DERR_NOTAVAILABLE;
3017
3018     adapter = &This->adapters[Adapter];
3019     glDesc = getFormatDescEntry(SurfaceFormat, &adapter->gl_info);
3020     if (!glDesc) return WINED3DERR_INVALIDCALL;
3021
3022     if(glDesc->Flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL)) {
3023         int i, nCfgs;
3024         const WineD3D_PixelFormat *cfgs;
3025
3026         cfgs = adapter->cfgs;
3027         nCfgs = adapter->nCfgs;
3028         for(i=0; i<nCfgs; i++) {
3029             if(cfgs[i].numSamples != MultiSampleType)
3030                 continue;
3031
3032             if (!IWineD3DImpl_IsPixelFormatCompatibleWithDepthFmt(&adapter->gl_info, &cfgs[i], glDesc))
3033                 continue;
3034
3035             TRACE("Found iPixelFormat=%d to support MultiSampleType=%d for format %s\n", cfgs[i].iPixelFormat, MultiSampleType, debug_d3dformat(SurfaceFormat));
3036
3037             if(pQualityLevels)
3038                 *pQualityLevels = 1; /* Guess at a value! */
3039             return WINED3D_OK;
3040         }
3041     }
3042     else if(glDesc->Flags & WINED3DFMT_FLAG_RENDERTARGET) {
3043         short redSize, greenSize, blueSize, alphaSize, colorBits;
3044         int i, nCfgs;
3045         const WineD3D_PixelFormat *cfgs;
3046
3047         if (!getColorBits(glDesc, &redSize, &greenSize, &blueSize, &alphaSize, &colorBits))
3048         {
3049             ERR("Unable to color bits for format %#x, can't check multisampling capability!\n", SurfaceFormat);
3050             return WINED3DERR_NOTAVAILABLE;
3051         }
3052
3053         cfgs = adapter->cfgs;
3054         nCfgs = adapter->nCfgs;
3055         for(i=0; i<nCfgs; i++) {
3056             if(cfgs[i].numSamples != MultiSampleType)
3057                 continue;
3058             if(cfgs[i].redSize != redSize)
3059                 continue;
3060             if(cfgs[i].greenSize != greenSize)
3061                 continue;
3062             if(cfgs[i].blueSize != blueSize)
3063                 continue;
3064             /* Not all drivers report alpha-less formats since they use 32-bit anyway, so accept alpha even if we didn't ask for it. */
3065             if(alphaSize && cfgs[i].alphaSize != alphaSize)
3066                 continue;
3067             if(cfgs[i].colorSize != (glDesc->byte_count << 3))
3068                 continue;
3069
3070             TRACE("Found iPixelFormat=%d to support MultiSampleType=%d for format %s\n", cfgs[i].iPixelFormat, MultiSampleType, debug_d3dformat(SurfaceFormat));
3071
3072             if(pQualityLevels)
3073                 *pQualityLevels = 1; /* Guess at a value! */
3074             return WINED3D_OK;
3075         }
3076     }
3077     return WINED3DERR_NOTAVAILABLE;
3078 }
3079
3080 static HRESULT WINAPI IWineD3DImpl_CheckDeviceType(IWineD3D *iface, UINT Adapter, WINED3DDEVTYPE DeviceType,
3081         WINED3DFORMAT DisplayFormat, WINED3DFORMAT BackBufferFormat, BOOL Windowed)
3082 {
3083     HRESULT hr = WINED3DERR_NOTAVAILABLE;
3084     UINT nmodes;
3085
3086     TRACE("iface %p, adapter_idx %u, device_type %s, display_format %s, backbuffer_format %s, windowed %#x.\n",
3087             iface, Adapter, debug_d3ddevicetype(DeviceType), debug_d3dformat(DisplayFormat),
3088             debug_d3dformat(BackBufferFormat), Windowed);
3089
3090     if (Adapter >= IWineD3D_GetAdapterCount(iface)) {
3091         WARN_(d3d_caps)("Adapter >= IWineD3D_GetAdapterCount(iface), returning WINED3DERR_INVALIDCALL\n");
3092         return WINED3DERR_INVALIDCALL;
3093     }
3094
3095     /* The task of this function is to check whether a certain display / backbuffer format
3096      * combination is available on the given adapter. In fullscreen mode microsoft specified
3097      * that the display format shouldn't provide alpha and that ignoring alpha the backbuffer
3098      * and display format should match exactly.
3099      * In windowed mode format conversion can occur and this depends on the driver. When format
3100      * conversion is done, this function should nevertheless fail and applications need to use
3101      * CheckDeviceFormatConversion.
3102      * At the moment we assume that fullscreen and windowed have the same capabilities */
3103
3104     /* There are only 4 display formats */
3105     if (!(DisplayFormat == WINED3DFMT_B5G6R5_UNORM
3106             || DisplayFormat == WINED3DFMT_B5G5R5X1_UNORM
3107             || DisplayFormat == WINED3DFMT_B8G8R8X8_UNORM
3108             || DisplayFormat == WINED3DFMT_B10G10R10A2_UNORM))
3109     {
3110         TRACE_(d3d_caps)("Format %s unsupported as display format\n", debug_d3dformat(DisplayFormat));
3111         return WINED3DERR_NOTAVAILABLE;
3112     }
3113
3114     /* If the requested DisplayFormat is not available, don't continue */
3115     nmodes = IWineD3DImpl_GetAdapterModeCount(iface, Adapter, DisplayFormat);
3116     if(!nmodes) {
3117         TRACE_(d3d_caps)("No available modes for display format %s\n", debug_d3dformat(DisplayFormat));
3118         return WINED3DERR_NOTAVAILABLE;
3119     }
3120
3121     /* Windowed mode allows you to specify WINED3DFMT_UNKNOWN for the backbufferformat, it means 'reuse' the display format for the backbuffer */
3122     if(!Windowed && BackBufferFormat == WINED3DFMT_UNKNOWN) {
3123         TRACE_(d3d_caps)("BackBufferFormat WINED3FMT_UNKNOWN not available in Windowed mode\n");
3124         return WINED3DERR_NOTAVAILABLE;
3125     }
3126
3127     /* In FULLSCREEN mode R5G6B5 can only be mixed with backbuffer format R5G6B5 */
3128     if (DisplayFormat == WINED3DFMT_B5G6R5_UNORM && BackBufferFormat != WINED3DFMT_B5G6R5_UNORM)
3129     {
3130         TRACE_(d3d_caps)("Unsupported display/backbuffer format combination %s/%s\n", debug_d3dformat(DisplayFormat), debug_d3dformat(BackBufferFormat));
3131         return WINED3DERR_NOTAVAILABLE;
3132     }
3133
3134     /* In FULLSCREEN mode X1R5G5B5 can only be mixed with backbuffer format *1R5G5B5 */
3135     if (DisplayFormat == WINED3DFMT_B5G5R5X1_UNORM
3136             && !(BackBufferFormat == WINED3DFMT_B5G5R5X1_UNORM || BackBufferFormat == WINED3DFMT_B5G5R5A1_UNORM))
3137     {
3138         TRACE_(d3d_caps)("Unsupported display/backbuffer format combination %s/%s\n", debug_d3dformat(DisplayFormat), debug_d3dformat(BackBufferFormat));
3139         return WINED3DERR_NOTAVAILABLE;
3140     }
3141
3142     /* In FULLSCREEN mode X8R8G8B8 can only be mixed with backbuffer format *8R8G8B8 */
3143     if (DisplayFormat == WINED3DFMT_B8G8R8X8_UNORM
3144             && !(BackBufferFormat == WINED3DFMT_B8G8R8X8_UNORM || BackBufferFormat == WINED3DFMT_B8G8R8A8_UNORM))
3145     {
3146         TRACE_(d3d_caps)("Unsupported display/backbuffer format combination %s/%s\n", debug_d3dformat(DisplayFormat), debug_d3dformat(BackBufferFormat));
3147         return WINED3DERR_NOTAVAILABLE;
3148     }
3149
3150     /* A2R10G10B10 is only allowed in fullscreen mode and it can only be mixed with backbuffer format A2R10G10B10 */
3151     if (DisplayFormat == WINED3DFMT_B10G10R10A2_UNORM
3152             && (BackBufferFormat != WINED3DFMT_B10G10R10A2_UNORM || Windowed))
3153     {
3154         TRACE_(d3d_caps)("Unsupported display/backbuffer format combination %s/%s\n", debug_d3dformat(DisplayFormat), debug_d3dformat(BackBufferFormat));
3155         return WINED3DERR_NOTAVAILABLE;
3156     }
3157
3158     /* Use CheckDeviceFormat to see if the BackBufferFormat is usable with the given DisplayFormat */
3159     hr = IWineD3DImpl_CheckDeviceFormat(iface, Adapter, DeviceType, DisplayFormat, WINED3DUSAGE_RENDERTARGET, WINED3DRTYPE_SURFACE, BackBufferFormat, SURFACE_OPENGL);
3160     if(FAILED(hr))
3161         TRACE_(d3d_caps)("Unsupported display/backbuffer format combination %s/%s\n", debug_d3dformat(DisplayFormat), debug_d3dformat(BackBufferFormat));
3162
3163     return hr;
3164 }
3165
3166
3167 /* Check if we support bumpmapping for a format */
3168 static BOOL CheckBumpMapCapability(struct wined3d_adapter *adapter,
3169         WINED3DDEVTYPE DeviceType, const struct wined3d_format_desc *format_desc)
3170 {
3171     switch(format_desc->format)
3172     {
3173         case WINED3DFMT_R8G8_SNORM:
3174         case WINED3DFMT_R16G16_SNORM:
3175         case WINED3DFMT_R5G5_SNORM_L6_UNORM:
3176         case WINED3DFMT_R8G8_SNORM_L8X8_UNORM:
3177         case WINED3DFMT_R8G8B8A8_SNORM:
3178             /* Ask the fixed function pipeline implementation if it can deal
3179              * with the conversion. If we've got a GL extension giving native
3180              * support this will be an identity conversion. */
3181             if (adapter->fragment_pipe->color_fixup_supported(format_desc->color_fixup))
3182             {
3183                 TRACE_(d3d_caps)("[OK]\n");
3184                 return TRUE;
3185             }
3186             TRACE_(d3d_caps)("[FAILED]\n");
3187             return FALSE;
3188
3189         default:
3190             TRACE_(d3d_caps)("[FAILED]\n");
3191             return FALSE;
3192     }
3193 }
3194
3195 /* Check if the given DisplayFormat + DepthStencilFormat combination is valid for the Adapter */
3196 static BOOL CheckDepthStencilCapability(struct wined3d_adapter *adapter,
3197         const struct wined3d_format_desc *display_format_desc, const struct wined3d_format_desc *ds_format_desc)
3198 {
3199     int it=0;
3200
3201     /* Only allow depth/stencil formats */
3202     if (!(ds_format_desc->depth_size || ds_format_desc->stencil_size)) return FALSE;
3203
3204     /* Walk through all WGL pixel formats to find a match */
3205     for (it = 0; it < adapter->nCfgs; ++it)
3206     {
3207         WineD3D_PixelFormat *cfg = &adapter->cfgs[it];
3208         if (IWineD3DImpl_IsPixelFormatCompatibleWithRenderFmt(&adapter->gl_info, cfg, display_format_desc))
3209         {
3210             if (IWineD3DImpl_IsPixelFormatCompatibleWithDepthFmt(&adapter->gl_info, cfg, ds_format_desc))
3211             {
3212                 return TRUE;
3213             }
3214         }
3215     }
3216
3217     return FALSE;
3218 }
3219
3220 static BOOL CheckFilterCapability(struct wined3d_adapter *adapter, const struct wined3d_format_desc *format_desc)
3221 {
3222     /* The flags entry of a format contains the filtering capability */
3223     if (format_desc->Flags & WINED3DFMT_FLAG_FILTERING) return TRUE;
3224
3225     return FALSE;
3226 }
3227
3228 /* Check the render target capabilities of a format */
3229 static BOOL CheckRenderTargetCapability(struct wined3d_adapter *adapter,
3230         const struct wined3d_format_desc *adapter_format_desc, const struct wined3d_format_desc *check_format_desc)
3231 {
3232     /* Filter out non-RT formats */
3233     if (!(check_format_desc->Flags & WINED3DFMT_FLAG_RENDERTARGET)) return FALSE;
3234
3235     if(wined3d_settings.offscreen_rendering_mode == ORM_BACKBUFFER) {
3236         WineD3D_PixelFormat *cfgs = adapter->cfgs;
3237         int it;
3238         short AdapterRed, AdapterGreen, AdapterBlue, AdapterAlpha, AdapterTotalSize;
3239         short CheckRed, CheckGreen, CheckBlue, CheckAlpha, CheckTotalSize;
3240
3241         getColorBits(adapter_format_desc, &AdapterRed, &AdapterGreen, &AdapterBlue, &AdapterAlpha, &AdapterTotalSize);
3242         getColorBits(check_format_desc, &CheckRed, &CheckGreen, &CheckBlue, &CheckAlpha, &CheckTotalSize);
3243
3244         /* In backbuffer mode the front and backbuffer share the same WGL pixelformat.
3245          * The format must match in RGB, alpha is allowed to be different. (Only the backbuffer can have alpha) */
3246         if(!((AdapterRed == CheckRed) && (AdapterGreen == CheckGreen) && (AdapterBlue == CheckBlue))) {
3247             TRACE_(d3d_caps)("[FAILED]\n");
3248             return FALSE;
3249         }
3250
3251         /* Check if there is a WGL pixel format matching the requirements, the format should also be window
3252          * drawable (not offscreen; e.g. Nvidia offers R5G6B5 for pbuffers even when X is running at 24bit) */
3253         for (it = 0; it < adapter->nCfgs; ++it)
3254         {
3255             if (cfgs[it].windowDrawable && IWineD3DImpl_IsPixelFormatCompatibleWithRenderFmt(&adapter->gl_info,
3256                     &cfgs[it], check_format_desc))
3257             {
3258                 TRACE_(d3d_caps)("iPixelFormat=%d is compatible with CheckFormat=%s\n",
3259                         cfgs[it].iPixelFormat, debug_d3dformat(check_format_desc->format));
3260                 return TRUE;
3261             }
3262         }
3263     }
3264     else if(wined3d_settings.offscreen_rendering_mode == ORM_FBO)
3265     {
3266         /* For now return TRUE for FBOs until we have some proper checks.
3267          * Note that this function will only be called when the format is around for texturing. */
3268         return TRUE;
3269     }
3270     return FALSE;
3271 }
3272
3273 static BOOL CheckSrgbReadCapability(struct wined3d_adapter *adapter, const struct wined3d_format_desc *format_desc)
3274 {
3275     const struct wined3d_gl_info *gl_info = &adapter->gl_info;
3276
3277     /* Check for supported sRGB formats (Texture loading and framebuffer) */
3278     if (!gl_info->supported[EXT_TEXTURE_SRGB])
3279     {
3280         TRACE_(d3d_caps)("[FAILED] GL_EXT_texture_sRGB not supported\n");
3281         return FALSE;
3282     }
3283
3284     switch (format_desc->format)
3285     {
3286         case WINED3DFMT_B8G8R8A8_UNORM:
3287         case WINED3DFMT_B8G8R8X8_UNORM:
3288         case WINED3DFMT_B4G4R4A4_UNORM:
3289         case WINED3DFMT_L8_UNORM:
3290         case WINED3DFMT_L8A8_UNORM:
3291         case WINED3DFMT_DXT1:
3292         case WINED3DFMT_DXT2:
3293         case WINED3DFMT_DXT3:
3294         case WINED3DFMT_DXT4:
3295         case WINED3DFMT_DXT5:
3296             TRACE_(d3d_caps)("[OK]\n");
3297             return TRUE;
3298
3299         default:
3300             TRACE_(d3d_caps)("[FAILED] Gamma texture format %s not supported.\n", debug_d3dformat(format_desc->format));
3301             return FALSE;
3302     }
3303     return FALSE;
3304 }
3305
3306 static BOOL CheckSrgbWriteCapability(struct wined3d_adapter *adapter,
3307         WINED3DDEVTYPE DeviceType, const struct wined3d_format_desc *format_desc)
3308 {
3309     /* Only offer SRGB writing on X8R8G8B8/A8R8G8B8 when we use ARB or GLSL shaders as we are
3310      * doing the color fixup in shaders.
3311      * Note Windows drivers (at least on the Geforce 8800) also offer this on R5G6B5. */
3312     if ((format_desc->format == WINED3DFMT_B8G8R8X8_UNORM) || (format_desc->format == WINED3DFMT_B8G8R8A8_UNORM))
3313     {
3314         int vs_selected_mode;
3315         int ps_selected_mode;
3316         select_shader_mode(&adapter->gl_info, &ps_selected_mode, &vs_selected_mode);
3317
3318         if((ps_selected_mode == SHADER_ARB) || (ps_selected_mode == SHADER_GLSL)) {
3319             TRACE_(d3d_caps)("[OK]\n");
3320             return TRUE;
3321         }
3322     }
3323
3324     TRACE_(d3d_caps)("[FAILED] - no SRGB writing support on format=%s\n", debug_d3dformat(format_desc->format));
3325     return FALSE;
3326 }
3327
3328 /* Check if a format support blending in combination with pixel shaders */
3329 static BOOL CheckPostPixelShaderBlendingCapability(struct wined3d_adapter *adapter,
3330         const struct wined3d_format_desc *format_desc)
3331 {
3332     /* The flags entry of a format contains the post pixel shader blending capability */
3333     if (format_desc->Flags & WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING) return TRUE;
3334
3335     return FALSE;
3336 }
3337
3338 static BOOL CheckWrapAndMipCapability(struct wined3d_adapter *adapter, const struct wined3d_format_desc *format_desc)
3339 {
3340     /* OpenGL supports mipmapping on all formats basically. Wrapping is unsupported,
3341      * but we have to report mipmapping so we cannot reject this flag. Tests show that
3342      * windows reports WRAPANDMIP on unfilterable surfaces as well, apparently to show
3343      * that wrapping is supported. The lack of filtering will sort out the mipmapping
3344      * capability anyway.
3345      *
3346      * For now lets report this on all formats, but in the future we may want to
3347      * restrict it to some should games need that
3348      */
3349     return TRUE;
3350 }
3351
3352 /* Check if a texture format is supported on the given adapter */
3353 static BOOL CheckTextureCapability(struct wined3d_adapter *adapter,
3354         WINED3DDEVTYPE DeviceType, const struct wined3d_format_desc *format_desc)
3355 {
3356     const struct wined3d_gl_info *gl_info = &adapter->gl_info;
3357
3358     switch (format_desc->format)
3359     {
3360         /*****
3361          *  supported: RGB(A) formats
3362          */
3363         case WINED3DFMT_B8G8R8_UNORM: /* Enable for dx7, blacklisted for 8 and 9 above */
3364         case WINED3DFMT_B8G8R8A8_UNORM:
3365         case WINED3DFMT_B8G8R8X8_UNORM:
3366         case WINED3DFMT_B5G6R5_UNORM:
3367         case WINED3DFMT_B5G5R5X1_UNORM:
3368         case WINED3DFMT_B5G5R5A1_UNORM:
3369         case WINED3DFMT_B4G4R4A4_UNORM:
3370         case WINED3DFMT_A8_UNORM:
3371         case WINED3DFMT_B4G4R4X4_UNORM:
3372         case WINED3DFMT_R8G8B8A8_UNORM:
3373         case WINED3DFMT_R8G8B8X8_UNORM:
3374         case WINED3DFMT_B10G10R10A2_UNORM:
3375         case WINED3DFMT_R10G10B10A2_UNORM:
3376         case WINED3DFMT_R16G16_UNORM:
3377             TRACE_(d3d_caps)("[OK]\n");
3378             return TRUE;
3379
3380         case WINED3DFMT_B2G3R3_UNORM:
3381             TRACE_(d3d_caps)("[FAILED] - Not supported on Windows\n");
3382             return FALSE;
3383
3384         /*****
3385          *  supported: Palettized
3386          */
3387         case WINED3DFMT_P8_UINT:
3388             TRACE_(d3d_caps)("[OK]\n");
3389             return TRUE;
3390         /* No Windows driver offers WINED3DFMT_P8_UINT_A8_UNORM, so don't offer it either */
3391         case WINED3DFMT_P8_UINT_A8_UNORM:
3392             return FALSE;
3393
3394         /*****
3395          *  Supported: (Alpha)-Luminance
3396          */
3397         case WINED3DFMT_L8_UNORM:
3398         case WINED3DFMT_L8A8_UNORM:
3399         case WINED3DFMT_L16_UNORM:
3400             TRACE_(d3d_caps)("[OK]\n");
3401             return TRUE;
3402
3403         /* Not supported on Windows, thus disabled */
3404         case WINED3DFMT_L4A4_UNORM:
3405             TRACE_(d3d_caps)("[FAILED] - not supported on windows\n");
3406             return FALSE;
3407
3408         /*****
3409          *  Supported: Depth/Stencil formats
3410          */
3411         case WINED3DFMT_D16_LOCKABLE:
3412         case WINED3DFMT_D16_UNORM:
3413         case WINED3DFMT_S1_UINT_D15_UNORM:
3414         case WINED3DFMT_X8D24_UNORM:
3415         case WINED3DFMT_S4X4_UINT_D24_UNORM:
3416         case WINED3DFMT_D24_UNORM_S8_UINT:
3417         case WINED3DFMT_S8_UINT_D24_FLOAT:
3418         case WINED3DFMT_D32_UNORM:
3419         case WINED3DFMT_D32_FLOAT:
3420             return TRUE;
3421
3422         /*****
3423          *  Not supported everywhere(depends on GL_ATI_envmap_bumpmap or
3424          *  GL_NV_texture_shader). Emulated by shaders
3425          */
3426         case WINED3DFMT_R8G8_SNORM:
3427         case WINED3DFMT_R8G8_SNORM_L8X8_UNORM:
3428         case WINED3DFMT_R5G5_SNORM_L6_UNORM:
3429         case WINED3DFMT_R8G8B8A8_SNORM:
3430         case WINED3DFMT_R16G16_SNORM:
3431             /* Ask the shader backend if it can deal with the conversion. If
3432              * we've got a GL extension giving native support this will be an
3433              * identity conversion. */
3434             if (adapter->shader_backend->shader_color_fixup_supported(format_desc->color_fixup))
3435             {
3436                 TRACE_(d3d_caps)("[OK]\n");
3437                 return TRUE;
3438             }
3439             TRACE_(d3d_caps)("[FAILED]\n");
3440             return FALSE;
3441
3442         case WINED3DFMT_DXT1:
3443         case WINED3DFMT_DXT2:
3444         case WINED3DFMT_DXT3:
3445         case WINED3DFMT_DXT4:
3446         case WINED3DFMT_DXT5:
3447             if (gl_info->supported[EXT_TEXTURE_COMPRESSION_S3TC])
3448             {
3449                 TRACE_(d3d_caps)("[OK]\n");
3450                 return TRUE;
3451             }
3452             TRACE_(d3d_caps)("[FAILED]\n");
3453             return FALSE;
3454
3455
3456         /*****
3457          *  Odd formats - not supported
3458          */
3459         case WINED3DFMT_VERTEXDATA:
3460         case WINED3DFMT_R16_UINT:
3461         case WINED3DFMT_R32_UINT:
3462         case WINED3DFMT_R16G16B16A16_SNORM:
3463         case WINED3DFMT_R10G10B10_SNORM_A2_UNORM:
3464         case WINED3DFMT_R10G11B11_SNORM:
3465             TRACE_(d3d_caps)("[FAILED]\n"); /* Enable when implemented */
3466             return FALSE;
3467
3468         /*****
3469          *  WINED3DFMT_R8G8_SNORM_Cx: Not supported right now
3470          */
3471         case WINED3DFMT_R8G8_SNORM_Cx:
3472             TRACE_(d3d_caps)("[FAILED]\n"); /* Enable when implemented */
3473             return FALSE;
3474
3475         /* YUV formats */
3476         case WINED3DFMT_UYVY:
3477         case WINED3DFMT_YUY2:
3478             if (gl_info->supported[APPLE_YCBCR_422])
3479             {
3480                 TRACE_(d3d_caps)("[OK]\n");
3481                 return TRUE;
3482             }
3483             TRACE_(d3d_caps)("[FAILED]\n");
3484             return FALSE;
3485         case WINED3DFMT_YV12:
3486             TRACE_(d3d_caps)("[FAILED]\n");
3487             return FALSE;
3488
3489             /* Not supported */
3490         case WINED3DFMT_R16G16B16A16_UNORM:
3491         case WINED3DFMT_B2G3R3A8_UNORM:
3492             TRACE_(d3d_caps)("[FAILED]\n"); /* Enable when implemented */
3493             return FALSE;
3494
3495             /* Floating point formats */
3496         case WINED3DFMT_R16_FLOAT:
3497         case WINED3DFMT_R16G16_FLOAT:
3498         case WINED3DFMT_R16G16B16A16_FLOAT:
3499             if (gl_info->supported[ARB_TEXTURE_FLOAT] && gl_info->supported[ARB_HALF_FLOAT_PIXEL])
3500             {
3501                 TRACE_(d3d_caps)("[OK]\n");
3502                 return TRUE;
3503             }
3504             TRACE_(d3d_caps)("[FAILED]\n");
3505             return FALSE;
3506
3507         case WINED3DFMT_R32_FLOAT:
3508         case WINED3DFMT_R32G32_FLOAT:
3509         case WINED3DFMT_R32G32B32A32_FLOAT:
3510             if (gl_info->supported[ARB_TEXTURE_FLOAT])
3511             {
3512                 TRACE_(d3d_caps)("[OK]\n");
3513                 return TRUE;
3514             }
3515             TRACE_(d3d_caps)("[FAILED]\n");
3516             return FALSE;
3517
3518         /* ATI instancing hack: Although ATI cards do not support Shader Model 3.0, they support
3519          * instancing. To query if the card supports instancing CheckDeviceFormat with the special format
3520          * MAKEFOURCC('I','N','S','T') is used. Should a (broken) app check for this provide a proper return value.
3521          * We can do instancing with all shader versions, but we need vertex shaders.
3522          *
3523          * Additionally applications have to set the D3DRS_POINTSIZE render state to MAKEFOURCC('I','N','S','T') once
3524          * to enable instancing. WineD3D doesn't need that and just ignores it.
3525          *
3526          * With Shader Model 3.0 capable cards Instancing 'just works' in Windows.
3527          */
3528         case WINED3DFMT_INST:
3529             TRACE("ATI Instancing check hack\n");
3530             if (gl_info->supported[ARB_VERTEX_PROGRAM] || gl_info->supported[ARB_VERTEX_SHADER])
3531             {
3532                 TRACE_(d3d_caps)("[OK]\n");
3533                 return TRUE;
3534             }
3535             TRACE_(d3d_caps)("[FAILED]\n");
3536             return FALSE;
3537
3538         /* Some weird FOURCC formats */
3539         case WINED3DFMT_R8G8_B8G8:
3540         case WINED3DFMT_G8R8_G8B8:
3541         case WINED3DFMT_MULTI2_ARGB8:
3542             TRACE_(d3d_caps)("[FAILED]\n");
3543             return FALSE;
3544
3545         /* Vendor specific formats */
3546         case WINED3DFMT_ATI2N:
3547             if (gl_info->supported[ATI_TEXTURE_COMPRESSION_3DC]
3548                     || gl_info->supported[EXT_TEXTURE_COMPRESSION_RGTC])
3549             {
3550                 if (adapter->shader_backend->shader_color_fixup_supported(format_desc->color_fixup)
3551                         && adapter->fragment_pipe->color_fixup_supported(format_desc->color_fixup))
3552                 {
3553                     TRACE_(d3d_caps)("[OK]\n");
3554                     return TRUE;
3555                 }
3556
3557                 TRACE_(d3d_caps)("[OK]\n");
3558                 return TRUE;
3559             }
3560             TRACE_(d3d_caps)("[FAILED]\n");
3561             return FALSE;
3562
3563         case WINED3DFMT_NVHU:
3564         case WINED3DFMT_NVHS:
3565             /* These formats seem to be similar to the HILO formats in GL_NV_texture_shader. NVHU
3566              * is said to be GL_UNSIGNED_HILO16, NVHS GL_SIGNED_HILO16. Rumours say that d3d computes
3567              * a 3rd channel similarly to D3DFMT_CxV8U8(So NVHS could be called D3DFMT_CxV16U16).
3568              * ATI refused to support formats which can easilly be emulated with pixel shaders, so
3569              * Applications have to deal with not having NVHS and NVHU.
3570              */
3571             TRACE_(d3d_caps)("[FAILED]\n");
3572             return FALSE;
3573
3574         case WINED3DFMT_UNKNOWN:
3575             return FALSE;
3576
3577         default:
3578             ERR("Unhandled format=%s\n", debug_d3dformat(format_desc->format));
3579             break;
3580     }
3581     return FALSE;
3582 }
3583
3584 static BOOL CheckSurfaceCapability(struct wined3d_adapter *adapter,
3585         const struct wined3d_format_desc *adapter_format_desc,
3586         WINED3DDEVTYPE DeviceType, const struct wined3d_format_desc *check_format_desc,
3587         WINED3DSURFTYPE SurfaceType)
3588 {
3589     if(SurfaceType == SURFACE_GDI) {
3590         switch(check_format_desc->format)
3591         {
3592             case WINED3DFMT_B8G8R8_UNORM:
3593             case WINED3DFMT_B8G8R8A8_UNORM:
3594             case WINED3DFMT_B8G8R8X8_UNORM:
3595             case WINED3DFMT_B5G6R5_UNORM:
3596             case WINED3DFMT_B5G5R5X1_UNORM:
3597             case WINED3DFMT_B5G5R5A1_UNORM:
3598             case WINED3DFMT_B4G4R4A4_UNORM:
3599             case WINED3DFMT_B2G3R3_UNORM:
3600             case WINED3DFMT_A8_UNORM:
3601             case WINED3DFMT_B2G3R3A8_UNORM:
3602             case WINED3DFMT_B4G4R4X4_UNORM:
3603             case WINED3DFMT_R10G10B10A2_UNORM:
3604             case WINED3DFMT_R8G8B8A8_UNORM:
3605             case WINED3DFMT_R8G8B8X8_UNORM:
3606             case WINED3DFMT_R16G16_UNORM:
3607             case WINED3DFMT_B10G10R10A2_UNORM:
3608             case WINED3DFMT_R16G16B16A16_UNORM:
3609             case WINED3DFMT_P8_UINT:
3610                 TRACE_(d3d_caps)("[OK]\n");
3611                 return TRUE;
3612             default:
3613                 TRACE_(d3d_caps)("[FAILED] - not available on GDI surfaces\n");
3614                 return FALSE;
3615         }
3616     }
3617
3618     /* All format that are supported for textures are supported for surfaces as well */
3619     if (CheckTextureCapability(adapter, DeviceType, check_format_desc)) return TRUE;
3620     /* All depth stencil formats are supported on surfaces */
3621     if (CheckDepthStencilCapability(adapter, adapter_format_desc, check_format_desc)) return TRUE;
3622
3623     /* If opengl can't process the format natively, the blitter may be able to convert it */
3624     if (adapter->blitter->color_fixup_supported(&adapter->gl_info, check_format_desc->color_fixup))
3625     {
3626         TRACE_(d3d_caps)("[OK]\n");
3627         return TRUE;
3628     }
3629
3630     /* Reject other formats */
3631     TRACE_(d3d_caps)("[FAILED]\n");
3632     return FALSE;
3633 }
3634
3635 static BOOL CheckVertexTextureCapability(struct wined3d_adapter *adapter,
3636         const struct wined3d_format_desc *format_desc)
3637 {
3638     const struct wined3d_gl_info *gl_info = &adapter->gl_info;
3639
3640     if (!gl_info->limits.vertex_samplers)
3641     {
3642         TRACE_(d3d_caps)("[FAILED]\n");
3643         return FALSE;
3644     }
3645
3646     switch (format_desc->format)
3647     {
3648         case WINED3DFMT_R32G32B32A32_FLOAT:
3649             if (!gl_info->supported[ARB_TEXTURE_FLOAT])
3650             {
3651                 TRACE_(d3d_caps)("[FAILED]\n");
3652                 return FALSE;
3653             }
3654             TRACE_(d3d_caps)("[OK]\n");
3655             return TRUE;
3656
3657         default:
3658             TRACE_(d3d_caps)("[FAILED]\n");
3659             return FALSE;
3660     }
3661     return FALSE;
3662 }
3663
3664 static HRESULT WINAPI IWineD3DImpl_CheckDeviceFormat(IWineD3D *iface, UINT Adapter, WINED3DDEVTYPE DeviceType,
3665         WINED3DFORMAT AdapterFormat, DWORD Usage, WINED3DRESOURCETYPE RType, WINED3DFORMAT CheckFormat,
3666         WINED3DSURFTYPE SurfaceType)
3667 {
3668     IWineD3DImpl *This = (IWineD3DImpl *)iface;
3669     struct wined3d_adapter *adapter = &This->adapters[Adapter];
3670     const struct wined3d_gl_info *gl_info = &adapter->gl_info;
3671     const struct wined3d_format_desc *format_desc = getFormatDescEntry(CheckFormat, gl_info);
3672     const struct wined3d_format_desc *adapter_format_desc = getFormatDescEntry(AdapterFormat, gl_info);
3673     DWORD UsageCaps = 0;
3674
3675     TRACE_(d3d_caps)("(%p)-> (STUB) (Adptr:%d, DevType:(%u,%s), AdptFmt:(%u,%s), Use:(%u,%s,%s), ResTyp:(%x,%s), CheckFmt:(%u,%s))\n",
3676           This,
3677           Adapter,
3678           DeviceType, debug_d3ddevicetype(DeviceType),
3679           AdapterFormat, debug_d3dformat(AdapterFormat),
3680           Usage, debug_d3dusage(Usage), debug_d3dusagequery(Usage),
3681           RType, debug_d3dresourcetype(RType),
3682           CheckFormat, debug_d3dformat(CheckFormat));
3683
3684     if (Adapter >= IWineD3D_GetAdapterCount(iface)) {
3685         return WINED3DERR_INVALIDCALL;
3686     }
3687
3688     if(RType == WINED3DRTYPE_CUBETEXTURE) {
3689
3690         if(SurfaceType != SURFACE_OPENGL) {
3691             TRACE("[FAILED]\n");
3692             return WINED3DERR_NOTAVAILABLE;
3693         }
3694
3695         /* Cubetexture allows:
3696          *                    - D3DUSAGE_AUTOGENMIPMAP
3697          *                    - D3DUSAGE_DEPTHSTENCIL
3698          *                    - D3DUSAGE_DYNAMIC
3699          *                    - D3DUSAGE_NONSECURE (d3d9ex)
3700          *                    - D3DUSAGE_RENDERTARGET
3701          *                    - D3DUSAGE_SOFTWAREPROCESSING
3702          *                    - D3DUSAGE_QUERY_WRAPANDMIP
3703          */
3704         if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
3705         {
3706             /* Check if the texture format is around */
3707             if (CheckTextureCapability(adapter, DeviceType, format_desc))
3708             {
3709                 if(Usage & WINED3DUSAGE_AUTOGENMIPMAP) {
3710                     /* Check for automatic mipmap generation support */
3711                     if (gl_info->supported[SGIS_GENERATE_MIPMAP])
3712                     {
3713                         UsageCaps |= WINED3DUSAGE_AUTOGENMIPMAP;
3714                     } else {
3715                         /* When autogenmipmap isn't around continue and return WINED3DOK_NOAUTOGEN instead of D3D_OK */
3716                         TRACE_(d3d_caps)("[FAILED] - No autogenmipmap support, but continuing\n");
3717                     }
3718                 }
3719
3720                 /* Always report dynamic locking */
3721                 if(Usage & WINED3DUSAGE_DYNAMIC)
3722                     UsageCaps |= WINED3DUSAGE_DYNAMIC;
3723
3724                 if(Usage & WINED3DUSAGE_RENDERTARGET) {
3725                     if(CheckRenderTargetCapability(adapter, adapter_format_desc, format_desc))
3726                     {
3727                         UsageCaps |= WINED3DUSAGE_RENDERTARGET;
3728                     } else {
3729                         TRACE_(d3d_caps)("[FAILED] - No rendertarget support\n");
3730                         return WINED3DERR_NOTAVAILABLE;
3731                     }
3732                 }
3733
3734                 /* Always report software processing */
3735                 if(Usage & WINED3DUSAGE_SOFTWAREPROCESSING)
3736                     UsageCaps |= WINED3DUSAGE_SOFTWAREPROCESSING;
3737
3738                 /* Check QUERY_FILTER support */
3739                 if(Usage & WINED3DUSAGE_QUERY_FILTER) {
3740                     if (CheckFilterCapability(adapter, format_desc))
3741                     {
3742                         UsageCaps |= WINED3DUSAGE_QUERY_FILTER;
3743                     } else {
3744                         TRACE_(d3d_caps)("[FAILED] - No query filter support\n");
3745                         return WINED3DERR_NOTAVAILABLE;
3746                     }
3747                 }
3748
3749                 /* Check QUERY_POSTPIXELSHADER_BLENDING support */
3750                 if(Usage & WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING) {
3751                     if (CheckPostPixelShaderBlendingCapability(adapter, format_desc))
3752                     {
3753                         UsageCaps |= WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING;
3754                     } else {
3755                         TRACE_(d3d_caps)("[FAILED] - No query post pixelshader blending support\n");
3756                         return WINED3DERR_NOTAVAILABLE;
3757                     }
3758                 }
3759
3760                 /* Check QUERY_SRGBREAD support */
3761                 if(Usage & WINED3DUSAGE_QUERY_SRGBREAD) {
3762                     if (CheckSrgbReadCapability(adapter, format_desc))
3763                     {
3764                         UsageCaps |= WINED3DUSAGE_QUERY_SRGBREAD;
3765                     } else {
3766                         TRACE_(d3d_caps)("[FAILED] - No query srgbread support\n");
3767                         return WINED3DERR_NOTAVAILABLE;
3768                     }
3769                 }
3770
3771                 /* Check QUERY_SRGBWRITE support */
3772                 if(Usage & WINED3DUSAGE_QUERY_SRGBWRITE) {
3773                     if (CheckSrgbWriteCapability(adapter, DeviceType, format_desc))
3774                     {
3775                         UsageCaps |= WINED3DUSAGE_QUERY_SRGBWRITE;
3776                     } else {
3777                         TRACE_(d3d_caps)("[FAILED] - No query srgbwrite support\n");
3778                         return WINED3DERR_NOTAVAILABLE;
3779                     }
3780                 }
3781
3782                 /* Check QUERY_VERTEXTEXTURE support */
3783                 if(Usage & WINED3DUSAGE_QUERY_VERTEXTEXTURE) {
3784                     if (CheckVertexTextureCapability(adapter, format_desc))
3785                     {
3786                         UsageCaps |= WINED3DUSAGE_QUERY_VERTEXTEXTURE;
3787                     } else {
3788                         TRACE_(d3d_caps)("[FAILED] - No query vertextexture support\n");
3789                         return WINED3DERR_NOTAVAILABLE;
3790                     }
3791                 }
3792
3793                 /* Check QUERY_WRAPANDMIP support */
3794                 if(Usage & WINED3DUSAGE_QUERY_WRAPANDMIP) {
3795                     if (CheckWrapAndMipCapability(adapter, format_desc))
3796                     {
3797                         UsageCaps |= WINED3DUSAGE_QUERY_WRAPANDMIP;
3798                     } else {
3799                         TRACE_(d3d_caps)("[FAILED] - No wrapping and mipmapping support\n");
3800                         return WINED3DERR_NOTAVAILABLE;
3801                     }
3802                 }
3803             } else {
3804                 TRACE_(d3d_caps)("[FAILED] - Cube texture format not supported\n");
3805                 return WINED3DERR_NOTAVAILABLE;
3806             }
3807         } else {
3808             TRACE_(d3d_caps)("[FAILED] - No cube texture support\n");
3809             return WINED3DERR_NOTAVAILABLE;
3810         }
3811     } else if(RType == WINED3DRTYPE_SURFACE) {
3812         /* Surface allows:
3813          *                - D3DUSAGE_DEPTHSTENCIL
3814          *                - D3DUSAGE_NONSECURE (d3d9ex)
3815          *                - D3DUSAGE_RENDERTARGET
3816          */
3817
3818         if (CheckSurfaceCapability(adapter, adapter_format_desc, DeviceType, format_desc, SurfaceType))
3819         {
3820             if(Usage & WINED3DUSAGE_DEPTHSTENCIL) {
3821                 if (CheckDepthStencilCapability(adapter, adapter_format_desc, format_desc))
3822                 {
3823                     UsageCaps |= WINED3DUSAGE_DEPTHSTENCIL;
3824                 } else {
3825                     TRACE_(d3d_caps)("[FAILED] - No depthstencil support\n");
3826                     return WINED3DERR_NOTAVAILABLE;
3827                 }
3828             }
3829
3830             if(Usage & WINED3DUSAGE_RENDERTARGET) {
3831                 if (CheckRenderTargetCapability(adapter, adapter_format_desc, format_desc))
3832                 {
3833                     UsageCaps |= WINED3DUSAGE_RENDERTARGET;
3834                 } else {
3835                     TRACE_(d3d_caps)("[FAILED] - No rendertarget support\n");
3836                     return WINED3DERR_NOTAVAILABLE;
3837                 }
3838             }
3839
3840             /* Check QUERY_POSTPIXELSHADER_BLENDING support */
3841             if(Usage & WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING) {
3842                 if (CheckPostPixelShaderBlendingCapability(adapter, format_desc))
3843                 {
3844                     UsageCaps |= WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING;
3845                 } else {
3846                     TRACE_(d3d_caps)("[FAILED] - No query post pixelshader blending support\n");
3847                     return WINED3DERR_NOTAVAILABLE;
3848                 }
3849             }
3850         } else {
3851             TRACE_(d3d_caps)("[FAILED] - Not supported for plain surfaces\n");
3852             return WINED3DERR_NOTAVAILABLE;
3853         }
3854
3855     } else if(RType == WINED3DRTYPE_TEXTURE) {
3856         /* Texture allows:
3857          *                - D3DUSAGE_AUTOGENMIPMAP
3858          *                - D3DUSAGE_DEPTHSTENCIL
3859          *                - D3DUSAGE_DMAP
3860          *                - D3DUSAGE_DYNAMIC
3861          *                - D3DUSAGE_NONSECURE (d3d9ex)
3862          *                - D3DUSAGE_RENDERTARGET
3863          *                - D3DUSAGE_SOFTWAREPROCESSING
3864          *                - D3DUSAGE_TEXTAPI (d3d9ex)
3865          *                - D3DUSAGE_QUERY_WRAPANDMIP
3866          */
3867
3868         if(SurfaceType != SURFACE_OPENGL) {
3869             TRACE("[FAILED]\n");
3870             return WINED3DERR_NOTAVAILABLE;
3871         }
3872
3873         /* Check if the texture format is around */
3874         if (CheckTextureCapability(adapter, DeviceType, format_desc))
3875         {
3876             if(Usage & WINED3DUSAGE_AUTOGENMIPMAP) {
3877                 /* Check for automatic mipmap generation support */
3878                 if (gl_info->supported[SGIS_GENERATE_MIPMAP])
3879                 {
3880                     UsageCaps |= WINED3DUSAGE_AUTOGENMIPMAP;
3881                 } else {
3882                     /* When autogenmipmap isn't around continue and return WINED3DOK_NOAUTOGEN instead of D3D_OK */
3883                     TRACE_(d3d_caps)("[FAILED] - No autogenmipmap support, but continuing\n");
3884                 }
3885             }
3886
3887             /* Always report dynamic locking */
3888             if(Usage & WINED3DUSAGE_DYNAMIC)
3889                 UsageCaps |= WINED3DUSAGE_DYNAMIC;
3890
3891             if(Usage & WINED3DUSAGE_RENDERTARGET) {
3892                 if (CheckRenderTargetCapability(adapter, adapter_format_desc, format_desc))
3893                 {
3894                     UsageCaps |= WINED3DUSAGE_RENDERTARGET;
3895                 } else {
3896                     TRACE_(d3d_caps)("[FAILED] - No rendertarget support\n");
3897                      return WINED3DERR_NOTAVAILABLE;
3898                  }
3899             }
3900
3901             /* Always report software processing */
3902             if(Usage & WINED3DUSAGE_SOFTWAREPROCESSING)
3903                 UsageCaps |= WINED3DUSAGE_SOFTWAREPROCESSING;
3904
3905             /* Check QUERY_FILTER support */
3906             if(Usage & WINED3DUSAGE_QUERY_FILTER) {
3907                 if (CheckFilterCapability(adapter, format_desc))
3908                 {
3909                     UsageCaps |= WINED3DUSAGE_QUERY_FILTER;
3910                 } else {
3911                     TRACE_(d3d_caps)("[FAILED] - No query filter support\n");
3912                     return WINED3DERR_NOTAVAILABLE;
3913                 }
3914             }
3915
3916             /* Check QUERY_LEGACYBUMPMAP support */
3917             if(Usage & WINED3DUSAGE_QUERY_LEGACYBUMPMAP) {
3918                 if (CheckBumpMapCapability(adapter, DeviceType, format_desc))
3919                 {
3920                     UsageCaps |= WINED3DUSAGE_QUERY_LEGACYBUMPMAP;
3921                 } else {
3922                     TRACE_(d3d_caps)("[FAILED] - No legacy bumpmap support\n");
3923                     return WINED3DERR_NOTAVAILABLE;
3924                 }
3925             }
3926
3927             /* Check QUERY_POSTPIXELSHADER_BLENDING support */
3928             if(Usage & WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING) {
3929                 if (CheckPostPixelShaderBlendingCapability(adapter, format_desc))
3930                 {
3931                     UsageCaps |= WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING;
3932                 } else {
3933                     TRACE_(d3d_caps)("[FAILED] - No query post pixelshader blending support\n");
3934                     return WINED3DERR_NOTAVAILABLE;
3935                 }
3936             }
3937
3938             /* Check QUERY_SRGBREAD support */
3939             if(Usage & WINED3DUSAGE_QUERY_SRGBREAD) {
3940                 if (CheckSrgbReadCapability(adapter, format_desc))
3941                 {
3942                     UsageCaps |= WINED3DUSAGE_QUERY_SRGBREAD;
3943                 } else {
3944                     TRACE_(d3d_caps)("[FAILED] - No query srgbread support\n");
3945                     return WINED3DERR_NOTAVAILABLE;
3946                 }
3947             }
3948
3949             /* Check QUERY_SRGBWRITE support */
3950             if(Usage & WINED3DUSAGE_QUERY_SRGBWRITE) {
3951                 if (CheckSrgbWriteCapability(adapter, DeviceType, format_desc))
3952                 {
3953                     UsageCaps |= WINED3DUSAGE_QUERY_SRGBWRITE;
3954                 } else {
3955                     TRACE_(d3d_caps)("[FAILED] - No query srgbwrite support\n");
3956                     return WINED3DERR_NOTAVAILABLE;
3957                 }
3958             }
3959
3960             /* Check QUERY_VERTEXTEXTURE support */
3961             if(Usage & WINED3DUSAGE_QUERY_VERTEXTEXTURE) {
3962                 if (CheckVertexTextureCapability(adapter, format_desc))
3963                 {
3964                     UsageCaps |= WINED3DUSAGE_QUERY_VERTEXTEXTURE;
3965                 } else {
3966                     TRACE_(d3d_caps)("[FAILED] - No query vertextexture support\n");
3967                     return WINED3DERR_NOTAVAILABLE;
3968                 }
3969             }
3970
3971             /* Check QUERY_WRAPANDMIP support */
3972             if(Usage & WINED3DUSAGE_QUERY_WRAPANDMIP) {
3973                 if (CheckWrapAndMipCapability(adapter, format_desc))
3974                 {
3975                     UsageCaps |= WINED3DUSAGE_QUERY_WRAPANDMIP;
3976                 } else {
3977                     TRACE_(d3d_caps)("[FAILED] - No wrapping and mipmapping support\n");
3978                     return WINED3DERR_NOTAVAILABLE;
3979                 }
3980             }
3981
3982             if(Usage & WINED3DUSAGE_DEPTHSTENCIL) {
3983                 if (CheckDepthStencilCapability(adapter, adapter_format_desc, format_desc))
3984                 {
3985                     UsageCaps |= WINED3DUSAGE_DEPTHSTENCIL;
3986                 } else {
3987                     TRACE_(d3d_caps)("[FAILED] - No depth stencil support\n");
3988                     return WINED3DERR_NOTAVAILABLE;
3989                 }
3990             }
3991         } else {
3992             TRACE_(d3d_caps)("[FAILED] - Texture format not supported\n");
3993             return WINED3DERR_NOTAVAILABLE;
3994         }
3995     } else if((RType == WINED3DRTYPE_VOLUME) || (RType == WINED3DRTYPE_VOLUMETEXTURE)) {
3996         /* Volume is to VolumeTexture what Surface is to Texture but its usage caps are not documented.
3997          * Most driver seem to offer (nearly) the same on Volume and VolumeTexture, so do that too.
3998          *
3999          * Volumetexture allows:
4000          *                      - D3DUSAGE_DYNAMIC
4001          *                      - D3DUSAGE_NONSECURE (d3d9ex)
4002          *                      - D3DUSAGE_SOFTWAREPROCESSING
4003          *                      - D3DUSAGE_QUERY_WRAPANDMIP
4004          */
4005
4006         if(SurfaceType != SURFACE_OPENGL) {
4007             TRACE("[FAILED]\n");
4008             return WINED3DERR_NOTAVAILABLE;
4009         }
4010
4011         /* Check volume texture and volume usage caps */
4012         if (gl_info->supported[EXT_TEXTURE3D])
4013         {
4014             if (!CheckTextureCapability(adapter, DeviceType, format_desc))
4015             {
4016                 TRACE_(d3d_caps)("[FAILED] - Format not supported\n");
4017                 return WINED3DERR_NOTAVAILABLE;
4018             }
4019
4020             /* Always report dynamic locking */
4021             if(Usage & WINED3DUSAGE_DYNAMIC)
4022                 UsageCaps |= WINED3DUSAGE_DYNAMIC;
4023
4024             /* Always report software processing */
4025             if(Usage & WINED3DUSAGE_SOFTWAREPROCESSING)
4026                 UsageCaps |= WINED3DUSAGE_SOFTWAREPROCESSING;
4027
4028             /* Check QUERY_FILTER support */
4029             if(Usage & WINED3DUSAGE_QUERY_FILTER) {
4030                 if (CheckFilterCapability(adapter, format_desc))
4031                 {
4032                     UsageCaps |= WINED3DUSAGE_QUERY_FILTER;
4033                 } else {
4034                     TRACE_(d3d_caps)("[FAILED] - No query filter support\n");
4035                     return WINED3DERR_NOTAVAILABLE;
4036                 }
4037             }
4038
4039             /* Check QUERY_POSTPIXELSHADER_BLENDING support */
4040             if(Usage & WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING) {
4041                 if (CheckPostPixelShaderBlendingCapability(adapter, format_desc))
4042                 {
4043                     UsageCaps |= WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING;
4044                 } else {
4045                     TRACE_(d3d_caps)("[FAILED] - No query post pixelshader blending support\n");
4046                     return WINED3DERR_NOTAVAILABLE;
4047                 }
4048             }
4049
4050             /* Check QUERY_SRGBREAD support */
4051             if(Usage & WINED3DUSAGE_QUERY_SRGBREAD) {
4052                 if (CheckSrgbReadCapability(adapter, format_desc))
4053                 {
4054                     UsageCaps |= WINED3DUSAGE_QUERY_SRGBREAD;
4055                 } else {
4056                     TRACE_(d3d_caps)("[FAILED] - No query srgbread support\n");
4057                     return WINED3DERR_NOTAVAILABLE;
4058                 }
4059             }
4060
4061             /* Check QUERY_SRGBWRITE support */
4062             if(Usage & WINED3DUSAGE_QUERY_SRGBWRITE) {
4063                 if (CheckSrgbWriteCapability(adapter, DeviceType, format_desc))
4064                 {
4065                     UsageCaps |= WINED3DUSAGE_QUERY_SRGBWRITE;
4066                 } else {
4067                     TRACE_(d3d_caps)("[FAILED] - No query srgbwrite support\n");
4068                     return WINED3DERR_NOTAVAILABLE;
4069                 }
4070             }
4071
4072             /* Check QUERY_VERTEXTEXTURE support */
4073             if(Usage & WINED3DUSAGE_QUERY_VERTEXTEXTURE) {
4074                 if (CheckVertexTextureCapability(adapter, format_desc))
4075                 {
4076                     UsageCaps |= WINED3DUSAGE_QUERY_VERTEXTEXTURE;
4077                 } else {
4078                     TRACE_(d3d_caps)("[FAILED] - No query vertextexture support\n");
4079                     return WINED3DERR_NOTAVAILABLE;
4080                 }
4081             }
4082
4083             /* Check QUERY_WRAPANDMIP support */
4084             if(Usage & WINED3DUSAGE_QUERY_WRAPANDMIP) {
4085                 if (CheckWrapAndMipCapability(adapter, format_desc))
4086                 {
4087                     UsageCaps |= WINED3DUSAGE_QUERY_WRAPANDMIP;
4088                 } else {
4089                     TRACE_(d3d_caps)("[FAILED] - No wrapping and mipmapping support\n");
4090                     return WINED3DERR_NOTAVAILABLE;
4091                 }
4092             }
4093         } else {
4094             TRACE_(d3d_caps)("[FAILED] - No volume texture support\n");
4095             return WINED3DERR_NOTAVAILABLE;
4096         }
4097
4098         /* Filter formats that need conversion; For one part, this conversion is unimplemented,
4099          * and volume textures are huge, so it would be a big performance hit. Unless we hit an
4100          * app needing one of those formats, don't advertize them to avoid leading apps into
4101          * temptation. The windows drivers don't support most of those formats on volumes anyway,
4102          * except of R32F.
4103          */
4104         switch(CheckFormat) {
4105             case WINED3DFMT_P8_UINT:
4106             case WINED3DFMT_L4A4_UNORM:
4107             case WINED3DFMT_R32_FLOAT:
4108             case WINED3DFMT_R16_FLOAT:
4109             case WINED3DFMT_R8G8_SNORM_L8X8_UNORM:
4110             case WINED3DFMT_R5G5_SNORM_L6_UNORM:
4111             case WINED3DFMT_R16G16_UNORM:
4112                 TRACE_(d3d_caps)("[FAILED] - No converted formats on volumes\n");
4113                 return WINED3DERR_NOTAVAILABLE;
4114
4115             case WINED3DFMT_R8G8B8A8_SNORM:
4116             case WINED3DFMT_R16G16_SNORM:
4117             if (!gl_info->supported[NV_TEXTURE_SHADER])
4118             {
4119                 TRACE_(d3d_caps)("[FAILED] - No converted formats on volumes\n");
4120                 return WINED3DERR_NOTAVAILABLE;
4121             }
4122             break;
4123
4124             case WINED3DFMT_R8G8_SNORM:
4125             if (!gl_info->supported[NV_TEXTURE_SHADER])
4126             {
4127                 TRACE_(d3d_caps)("[FAILED] - No converted formats on volumes\n");
4128                 return WINED3DERR_NOTAVAILABLE;
4129             }
4130             break;
4131
4132             case WINED3DFMT_DXT1:
4133             case WINED3DFMT_DXT2:
4134             case WINED3DFMT_DXT3:
4135             case WINED3DFMT_DXT4:
4136             case WINED3DFMT_DXT5:
4137                 /* The GL_EXT_texture_compression_s3tc spec requires that loading an s3tc
4138                  * compressed texture results in an error. While the D3D refrast does
4139                  * support s3tc volumes, at least the nvidia windows driver does not, so
4140                  * we're free not to support this format.
4141                  */
4142                 TRACE_(d3d_caps)("[FAILED] - DXTn does not support 3D textures\n");
4143                 return WINED3DERR_NOTAVAILABLE;
4144
4145             default:
4146                 /* Do nothing, continue with checking the format below */
4147                 break;
4148         }
4149     } else if(RType == WINED3DRTYPE_BUFFER){
4150         /* For instance vertexbuffer/indexbuffer aren't supported yet because no Windows drivers seem to offer it */
4151         TRACE_(d3d_caps)("Unhandled resource type D3DRTYPE_INDEXBUFFER / D3DRTYPE_VERTEXBUFFER\n");
4152         return WINED3DERR_NOTAVAILABLE;
4153     }
4154
4155     /* When the UsageCaps exactly matches Usage return WINED3D_OK except for the situation in which
4156      * WINED3DUSAGE_AUTOGENMIPMAP isn't around, then WINED3DOK_NOAUTOGEN is returned if all the other
4157      * usage flags match. */
4158     if(UsageCaps == Usage) {
4159         return WINED3D_OK;
4160     } else if((UsageCaps == (Usage & ~WINED3DUSAGE_AUTOGENMIPMAP)) && (Usage & WINED3DUSAGE_AUTOGENMIPMAP)){
4161         return WINED3DOK_NOAUTOGEN;
4162     } else {
4163         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);
4164         return WINED3DERR_NOTAVAILABLE;
4165     }
4166 }
4167
4168 static HRESULT WINAPI IWineD3DImpl_CheckDeviceFormatConversion(IWineD3D *iface, UINT adapter_idx,
4169         WINED3DDEVTYPE device_type, WINED3DFORMAT src_format, WINED3DFORMAT dst_format)
4170 {
4171     FIXME("iface %p, adapter_idx %u, device_type %s, src_format %s, dst_format %s stub!\n",
4172             iface, adapter_idx, debug_d3ddevicetype(device_type), debug_d3dformat(src_format),
4173             debug_d3dformat(dst_format));
4174
4175     return WINED3D_OK;
4176 }
4177
4178 /* Note: d3d8 passes in a pointer to a D3DCAPS8 structure, which is a true
4179       subset of a D3DCAPS9 structure. However, it has to come via a void *
4180       as the d3d8 interface cannot import the d3d9 header                  */
4181 static HRESULT WINAPI IWineD3DImpl_GetDeviceCaps(IWineD3D *iface, UINT Adapter, WINED3DDEVTYPE DeviceType, WINED3DCAPS* pCaps) {
4182
4183     IWineD3DImpl    *This = (IWineD3DImpl *)iface;
4184     struct wined3d_adapter *adapter = &This->adapters[Adapter];
4185     const struct wined3d_gl_info *gl_info = &adapter->gl_info;
4186     int vs_selected_mode;
4187     int ps_selected_mode;
4188     struct shader_caps shader_caps;
4189     struct fragment_caps fragment_caps;
4190     DWORD ckey_caps, blit_caps, fx_caps;
4191
4192     TRACE_(d3d_caps)("(%p)->(Adptr:%d, DevType: %x, pCaps: %p)\n", This, Adapter, DeviceType, pCaps);
4193
4194     if (Adapter >= IWineD3D_GetAdapterCount(iface)) {
4195         return WINED3DERR_INVALIDCALL;
4196     }
4197
4198     select_shader_mode(&adapter->gl_info, &ps_selected_mode, &vs_selected_mode);
4199
4200     /* ------------------------------------------------
4201        The following fields apply to both d3d8 and d3d9
4202        ------------------------------------------------ */
4203     pCaps->DeviceType              = (DeviceType == WINED3DDEVTYPE_HAL) ? WINED3DDEVTYPE_HAL : WINED3DDEVTYPE_REF;  /* Not quite true, but use h/w supported by opengl I suppose */
4204     pCaps->AdapterOrdinal          = Adapter;
4205
4206     pCaps->Caps                    = 0;
4207     pCaps->Caps2                   = WINED3DCAPS2_CANRENDERWINDOWED |
4208                                      WINED3DCAPS2_FULLSCREENGAMMA |
4209                                      WINED3DCAPS2_DYNAMICTEXTURES;
4210     if (gl_info->supported[SGIS_GENERATE_MIPMAP])
4211     {
4212         pCaps->Caps2 |= WINED3DCAPS2_CANAUTOGENMIPMAP;
4213     }
4214
4215     pCaps->Caps3                   = WINED3DCAPS3_ALPHA_FULLSCREEN_FLIP_OR_DISCARD |
4216                                      WINED3DCAPS3_COPY_TO_VIDMEM                   |
4217                                      WINED3DCAPS3_COPY_TO_SYSTEMMEM;
4218
4219     pCaps->PresentationIntervals   = WINED3DPRESENT_INTERVAL_IMMEDIATE  |
4220                                      WINED3DPRESENT_INTERVAL_ONE;
4221
4222     pCaps->CursorCaps              = WINED3DCURSORCAPS_COLOR            |
4223                                      WINED3DCURSORCAPS_LOWRES;
4224
4225     pCaps->DevCaps                 = WINED3DDEVCAPS_FLOATTLVERTEX       |
4226                                      WINED3DDEVCAPS_EXECUTESYSTEMMEMORY |
4227                                      WINED3DDEVCAPS_TLVERTEXSYSTEMMEMORY|
4228                                      WINED3DDEVCAPS_TLVERTEXVIDEOMEMORY |
4229                                      WINED3DDEVCAPS_DRAWPRIMTLVERTEX    |
4230                                      WINED3DDEVCAPS_HWTRANSFORMANDLIGHT |
4231                                      WINED3DDEVCAPS_EXECUTEVIDEOMEMORY  |
4232                                      WINED3DDEVCAPS_PUREDEVICE          |
4233                                      WINED3DDEVCAPS_HWRASTERIZATION     |
4234                                      WINED3DDEVCAPS_TEXTUREVIDEOMEMORY  |
4235                                      WINED3DDEVCAPS_TEXTURESYSTEMMEMORY |
4236                                      WINED3DDEVCAPS_CANRENDERAFTERFLIP  |
4237                                      WINED3DDEVCAPS_DRAWPRIMITIVES2     |
4238                                      WINED3DDEVCAPS_DRAWPRIMITIVES2EX   |
4239                                      WINED3DDEVCAPS_RTPATCHES;
4240
4241     pCaps->PrimitiveMiscCaps       = WINED3DPMISCCAPS_CULLNONE              |
4242                                      WINED3DPMISCCAPS_CULLCCW               |
4243                                      WINED3DPMISCCAPS_CULLCW                |
4244                                      WINED3DPMISCCAPS_COLORWRITEENABLE      |
4245                                      WINED3DPMISCCAPS_CLIPTLVERTS           |
4246                                      WINED3DPMISCCAPS_CLIPPLANESCALEDPOINTS |
4247                                      WINED3DPMISCCAPS_MASKZ                 |
4248                                      WINED3DPMISCCAPS_BLENDOP               |
4249                                      WINED3DPMISCCAPS_MRTPOSTPIXELSHADERBLENDING;
4250                                     /* TODO:
4251                                         WINED3DPMISCCAPS_NULLREFERENCE
4252                                         WINED3DPMISCCAPS_INDEPENDENTWRITEMASKS
4253                                         WINED3DPMISCCAPS_FOGANDSPECULARALPHA
4254                                         WINED3DPMISCCAPS_MRTINDEPENDENTBITDEPTHS
4255                                         WINED3DPMISCCAPS_FOGVERTEXCLAMPED */
4256
4257     if (gl_info->supported[EXT_BLEND_EQUATION_SEPARATE] && gl_info->supported[EXT_BLEND_FUNC_SEPARATE])
4258         pCaps->PrimitiveMiscCaps |= WINED3DPMISCCAPS_SEPARATEALPHABLEND;
4259
4260     pCaps->RasterCaps              = WINED3DPRASTERCAPS_DITHER    |
4261                                      WINED3DPRASTERCAPS_PAT       |
4262                                      WINED3DPRASTERCAPS_WFOG      |
4263                                      WINED3DPRASTERCAPS_ZFOG      |
4264                                      WINED3DPRASTERCAPS_FOGVERTEX |
4265                                      WINED3DPRASTERCAPS_FOGTABLE  |
4266                                      WINED3DPRASTERCAPS_STIPPLE   |
4267                                      WINED3DPRASTERCAPS_SUBPIXEL  |
4268                                      WINED3DPRASTERCAPS_ZTEST     |
4269                                      WINED3DPRASTERCAPS_SCISSORTEST   |
4270                                      WINED3DPRASTERCAPS_SLOPESCALEDEPTHBIAS |
4271                                      WINED3DPRASTERCAPS_DEPTHBIAS;
4272
4273     if (gl_info->supported[EXT_TEXTURE_FILTER_ANISOTROPIC])
4274     {
4275         pCaps->RasterCaps |= WINED3DPRASTERCAPS_ANISOTROPY    |
4276                              WINED3DPRASTERCAPS_ZBIAS         |
4277                              WINED3DPRASTERCAPS_MIPMAPLODBIAS;
4278     }
4279     if (gl_info->supported[NV_FOG_DISTANCE])
4280     {
4281         pCaps->RasterCaps         |= WINED3DPRASTERCAPS_FOGRANGE;
4282     }
4283                         /* FIXME Add:
4284                            WINED3DPRASTERCAPS_COLORPERSPECTIVE
4285                            WINED3DPRASTERCAPS_STRETCHBLTMULTISAMPLE
4286                            WINED3DPRASTERCAPS_ANTIALIASEDGES
4287                            WINED3DPRASTERCAPS_ZBUFFERLESSHSR
4288                            WINED3DPRASTERCAPS_WBUFFER */
4289
4290     pCaps->ZCmpCaps = WINED3DPCMPCAPS_ALWAYS       |
4291                       WINED3DPCMPCAPS_EQUAL        |
4292                       WINED3DPCMPCAPS_GREATER      |
4293                       WINED3DPCMPCAPS_GREATEREQUAL |
4294                       WINED3DPCMPCAPS_LESS         |
4295                       WINED3DPCMPCAPS_LESSEQUAL    |
4296                       WINED3DPCMPCAPS_NEVER        |
4297                       WINED3DPCMPCAPS_NOTEQUAL;
4298
4299     pCaps->SrcBlendCaps  = WINED3DPBLENDCAPS_BOTHINVSRCALPHA |
4300                            WINED3DPBLENDCAPS_BOTHSRCALPHA    |
4301                            WINED3DPBLENDCAPS_DESTALPHA       |
4302                            WINED3DPBLENDCAPS_DESTCOLOR       |
4303                            WINED3DPBLENDCAPS_INVDESTALPHA    |
4304                            WINED3DPBLENDCAPS_INVDESTCOLOR    |
4305                            WINED3DPBLENDCAPS_INVSRCALPHA     |
4306                            WINED3DPBLENDCAPS_INVSRCCOLOR     |
4307                            WINED3DPBLENDCAPS_ONE             |
4308                            WINED3DPBLENDCAPS_SRCALPHA        |
4309                            WINED3DPBLENDCAPS_SRCALPHASAT     |
4310                            WINED3DPBLENDCAPS_SRCCOLOR        |
4311                            WINED3DPBLENDCAPS_ZERO;
4312
4313     pCaps->DestBlendCaps = WINED3DPBLENDCAPS_DESTALPHA       |
4314                            WINED3DPBLENDCAPS_DESTCOLOR       |
4315                            WINED3DPBLENDCAPS_INVDESTALPHA    |
4316                            WINED3DPBLENDCAPS_INVDESTCOLOR    |
4317                            WINED3DPBLENDCAPS_INVSRCALPHA     |
4318                            WINED3DPBLENDCAPS_INVSRCCOLOR     |
4319                            WINED3DPBLENDCAPS_ONE             |
4320                            WINED3DPBLENDCAPS_SRCALPHA        |
4321                            WINED3DPBLENDCAPS_SRCCOLOR        |
4322                            WINED3DPBLENDCAPS_ZERO;
4323     /* NOTE: WINED3DPBLENDCAPS_SRCALPHASAT is not supported as dest blend factor,
4324      * according to the glBlendFunc manpage
4325      *
4326      * WINED3DPBLENDCAPS_BOTHINVSRCALPHA and WINED3DPBLENDCAPS_BOTHSRCALPHA are
4327      * legacy settings for srcblend only
4328      */
4329
4330     if (gl_info->supported[EXT_BLEND_COLOR])
4331     {
4332         pCaps->SrcBlendCaps |= WINED3DPBLENDCAPS_BLENDFACTOR;
4333         pCaps->DestBlendCaps |= WINED3DPBLENDCAPS_BLENDFACTOR;
4334     }
4335
4336
4337     pCaps->AlphaCmpCaps = WINED3DPCMPCAPS_ALWAYS       |
4338                           WINED3DPCMPCAPS_EQUAL        |
4339                           WINED3DPCMPCAPS_GREATER      |
4340                           WINED3DPCMPCAPS_GREATEREQUAL |
4341                           WINED3DPCMPCAPS_LESS         |
4342                           WINED3DPCMPCAPS_LESSEQUAL    |
4343                           WINED3DPCMPCAPS_NEVER        |
4344                           WINED3DPCMPCAPS_NOTEQUAL;
4345
4346     pCaps->ShadeCaps     = WINED3DPSHADECAPS_SPECULARGOURAUDRGB |
4347                            WINED3DPSHADECAPS_COLORGOURAUDRGB    |
4348                            WINED3DPSHADECAPS_ALPHAFLATBLEND     |
4349                            WINED3DPSHADECAPS_ALPHAGOURAUDBLEND  |
4350                            WINED3DPSHADECAPS_COLORFLATRGB       |
4351                            WINED3DPSHADECAPS_FOGFLAT            |
4352                            WINED3DPSHADECAPS_FOGGOURAUD         |
4353                            WINED3DPSHADECAPS_SPECULARFLATRGB;
4354
4355     pCaps->TextureCaps =  WINED3DPTEXTURECAPS_ALPHA              |
4356                           WINED3DPTEXTURECAPS_ALPHAPALETTE       |
4357                           WINED3DPTEXTURECAPS_TRANSPARENCY       |
4358                           WINED3DPTEXTURECAPS_BORDER             |
4359                           WINED3DPTEXTURECAPS_MIPMAP             |
4360                           WINED3DPTEXTURECAPS_PROJECTED          |
4361                           WINED3DPTEXTURECAPS_PERSPECTIVE;
4362
4363     if (!gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO])
4364     {
4365         pCaps->TextureCaps |= WINED3DPTEXTURECAPS_POW2 |
4366                               WINED3DPTEXTURECAPS_NONPOW2CONDITIONAL;
4367     }
4368
4369     if (gl_info->supported[EXT_TEXTURE3D])
4370     {
4371         pCaps->TextureCaps |=  WINED3DPTEXTURECAPS_VOLUMEMAP      |
4372                                WINED3DPTEXTURECAPS_MIPVOLUMEMAP   |
4373                                WINED3DPTEXTURECAPS_VOLUMEMAP_POW2;
4374     }
4375
4376     if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
4377     {
4378         pCaps->TextureCaps |= WINED3DPTEXTURECAPS_CUBEMAP     |
4379                               WINED3DPTEXTURECAPS_MIPCUBEMAP    |
4380                               WINED3DPTEXTURECAPS_CUBEMAP_POW2;
4381
4382     }
4383
4384     pCaps->TextureFilterCaps = WINED3DPTFILTERCAPS_MAGFLINEAR       |
4385                                WINED3DPTFILTERCAPS_MAGFPOINT        |
4386                                WINED3DPTFILTERCAPS_MINFLINEAR       |
4387                                WINED3DPTFILTERCAPS_MINFPOINT        |
4388                                WINED3DPTFILTERCAPS_MIPFLINEAR       |
4389                                WINED3DPTFILTERCAPS_MIPFPOINT        |
4390                                WINED3DPTFILTERCAPS_LINEAR           |
4391                                WINED3DPTFILTERCAPS_LINEARMIPLINEAR  |
4392                                WINED3DPTFILTERCAPS_LINEARMIPNEAREST |
4393                                WINED3DPTFILTERCAPS_MIPLINEAR        |
4394                                WINED3DPTFILTERCAPS_MIPNEAREST       |
4395                                WINED3DPTFILTERCAPS_NEAREST;
4396
4397     if (gl_info->supported[EXT_TEXTURE_FILTER_ANISOTROPIC])
4398     {
4399         pCaps->TextureFilterCaps |= WINED3DPTFILTERCAPS_MAGFANISOTROPIC |
4400                                     WINED3DPTFILTERCAPS_MINFANISOTROPIC;
4401     }
4402
4403     if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
4404     {
4405         pCaps->CubeTextureFilterCaps = WINED3DPTFILTERCAPS_MAGFLINEAR       |
4406                                        WINED3DPTFILTERCAPS_MAGFPOINT        |
4407                                        WINED3DPTFILTERCAPS_MINFLINEAR       |
4408                                        WINED3DPTFILTERCAPS_MINFPOINT        |
4409                                        WINED3DPTFILTERCAPS_MIPFLINEAR       |
4410                                        WINED3DPTFILTERCAPS_MIPFPOINT        |
4411                                        WINED3DPTFILTERCAPS_LINEAR           |
4412                                        WINED3DPTFILTERCAPS_LINEARMIPLINEAR  |
4413                                        WINED3DPTFILTERCAPS_LINEARMIPNEAREST |
4414                                        WINED3DPTFILTERCAPS_MIPLINEAR        |
4415                                        WINED3DPTFILTERCAPS_MIPNEAREST       |
4416                                        WINED3DPTFILTERCAPS_NEAREST;
4417
4418         if (gl_info->supported[EXT_TEXTURE_FILTER_ANISOTROPIC])
4419         {
4420             pCaps->CubeTextureFilterCaps |= WINED3DPTFILTERCAPS_MAGFANISOTROPIC |
4421                                             WINED3DPTFILTERCAPS_MINFANISOTROPIC;
4422         }
4423     } else
4424         pCaps->CubeTextureFilterCaps = 0;
4425
4426     if (gl_info->supported[EXT_TEXTURE3D])
4427     {
4428         pCaps->VolumeTextureFilterCaps = WINED3DPTFILTERCAPS_MAGFLINEAR       |
4429                                          WINED3DPTFILTERCAPS_MAGFPOINT        |
4430                                          WINED3DPTFILTERCAPS_MINFLINEAR       |
4431                                          WINED3DPTFILTERCAPS_MINFPOINT        |
4432                                          WINED3DPTFILTERCAPS_MIPFLINEAR       |
4433                                          WINED3DPTFILTERCAPS_MIPFPOINT        |
4434                                          WINED3DPTFILTERCAPS_LINEAR           |
4435                                          WINED3DPTFILTERCAPS_LINEARMIPLINEAR  |
4436                                          WINED3DPTFILTERCAPS_LINEARMIPNEAREST |
4437                                          WINED3DPTFILTERCAPS_MIPLINEAR        |
4438                                          WINED3DPTFILTERCAPS_MIPNEAREST       |
4439                                          WINED3DPTFILTERCAPS_NEAREST;
4440     } else
4441         pCaps->VolumeTextureFilterCaps = 0;
4442
4443     pCaps->TextureAddressCaps =  WINED3DPTADDRESSCAPS_INDEPENDENTUV |
4444                                  WINED3DPTADDRESSCAPS_CLAMP  |
4445                                  WINED3DPTADDRESSCAPS_WRAP;
4446
4447     if (gl_info->supported[ARB_TEXTURE_BORDER_CLAMP])
4448     {
4449         pCaps->TextureAddressCaps |= WINED3DPTADDRESSCAPS_BORDER;
4450     }
4451     if (gl_info->supported[ARB_TEXTURE_MIRRORED_REPEAT])
4452     {
4453         pCaps->TextureAddressCaps |= WINED3DPTADDRESSCAPS_MIRROR;
4454     }
4455     if (gl_info->supported[ATI_TEXTURE_MIRROR_ONCE])
4456     {
4457         pCaps->TextureAddressCaps |= WINED3DPTADDRESSCAPS_MIRRORONCE;
4458     }
4459
4460     if (gl_info->supported[EXT_TEXTURE3D])
4461     {
4462         pCaps->VolumeTextureAddressCaps =  WINED3DPTADDRESSCAPS_INDEPENDENTUV |
4463                                            WINED3DPTADDRESSCAPS_CLAMP  |
4464                                            WINED3DPTADDRESSCAPS_WRAP;
4465         if (gl_info->supported[ARB_TEXTURE_BORDER_CLAMP])
4466         {
4467             pCaps->VolumeTextureAddressCaps |= WINED3DPTADDRESSCAPS_BORDER;
4468         }
4469         if (gl_info->supported[ARB_TEXTURE_MIRRORED_REPEAT])
4470         {
4471             pCaps->VolumeTextureAddressCaps |= WINED3DPTADDRESSCAPS_MIRROR;
4472         }
4473         if (gl_info->supported[ATI_TEXTURE_MIRROR_ONCE])
4474         {
4475             pCaps->VolumeTextureAddressCaps |= WINED3DPTADDRESSCAPS_MIRRORONCE;
4476         }
4477     } else
4478         pCaps->VolumeTextureAddressCaps = 0;
4479
4480     pCaps->LineCaps = WINED3DLINECAPS_TEXTURE       |
4481                       WINED3DLINECAPS_ZTEST         |
4482                       WINED3DLINECAPS_BLEND         |
4483                       WINED3DLINECAPS_ALPHACMP      |
4484                       WINED3DLINECAPS_FOG;
4485     /* WINED3DLINECAPS_ANTIALIAS is not supported on Windows, and dx and gl seem to have a different
4486      * idea how generating the smoothing alpha values works; the result is different
4487      */
4488
4489     pCaps->MaxTextureWidth = gl_info->limits.texture_size;
4490     pCaps->MaxTextureHeight = gl_info->limits.texture_size;
4491
4492     if (gl_info->supported[EXT_TEXTURE3D])
4493         pCaps->MaxVolumeExtent = gl_info->limits.texture3d_size;
4494     else
4495         pCaps->MaxVolumeExtent = 0;
4496
4497     pCaps->MaxTextureRepeat = 32768;
4498     pCaps->MaxTextureAspectRatio = gl_info->limits.texture_size;
4499     pCaps->MaxVertexW = 1.0f;
4500
4501     pCaps->GuardBandLeft = 0.0f;
4502     pCaps->GuardBandTop = 0.0f;
4503     pCaps->GuardBandRight = 0.0f;
4504     pCaps->GuardBandBottom = 0.0f;
4505
4506     pCaps->ExtentsAdjust = 0.0f;
4507
4508     pCaps->StencilCaps =  WINED3DSTENCILCAPS_DECRSAT |
4509                           WINED3DSTENCILCAPS_INCRSAT |
4510                           WINED3DSTENCILCAPS_INVERT  |
4511                           WINED3DSTENCILCAPS_KEEP    |
4512                           WINED3DSTENCILCAPS_REPLACE |
4513                           WINED3DSTENCILCAPS_ZERO;
4514     if (gl_info->supported[EXT_STENCIL_WRAP])
4515     {
4516         pCaps->StencilCaps |= WINED3DSTENCILCAPS_DECR  |
4517                               WINED3DSTENCILCAPS_INCR;
4518     }
4519     if (gl_info->supported[EXT_STENCIL_TWO_SIDE] || gl_info->supported[ATI_SEPARATE_STENCIL])
4520     {
4521         pCaps->StencilCaps |= WINED3DSTENCILCAPS_TWOSIDED;
4522     }
4523
4524     pCaps->FVFCaps = WINED3DFVFCAPS_PSIZE | 0x0008; /* 8 texture coords */
4525
4526     pCaps->MaxUserClipPlanes = gl_info->limits.clipplanes;
4527     pCaps->MaxActiveLights = gl_info->limits.lights;
4528
4529     pCaps->MaxVertexBlendMatrices = gl_info->limits.blends;
4530     pCaps->MaxVertexBlendMatrixIndex   = 0;
4531
4532     pCaps->MaxAnisotropy = gl_info->limits.anisotropy;
4533     pCaps->MaxPointSize = gl_info->limits.pointsize_max;
4534
4535
4536     /* FIXME: Add D3DVTXPCAPS_TWEENING, D3DVTXPCAPS_TEXGEN_SPHEREMAP */
4537     pCaps->VertexProcessingCaps = WINED3DVTXPCAPS_DIRECTIONALLIGHTS |
4538                                   WINED3DVTXPCAPS_MATERIALSOURCE7   |
4539                                   WINED3DVTXPCAPS_POSITIONALLIGHTS  |
4540                                   WINED3DVTXPCAPS_LOCALVIEWER       |
4541                                   WINED3DVTXPCAPS_VERTEXFOG         |
4542                                   WINED3DVTXPCAPS_TEXGEN;
4543
4544     pCaps->MaxPrimitiveCount   = 0xFFFFF; /* For now set 2^20-1 which is used by most >=Geforce3/Radeon8500 cards */
4545     pCaps->MaxVertexIndex      = 0xFFFFF;
4546     pCaps->MaxStreams          = MAX_STREAMS;
4547     pCaps->MaxStreamStride     = 1024;
4548
4549     /* d3d9.dll sets D3DDEVCAPS2_CAN_STRETCHRECT_FROM_TEXTURES here because StretchRects is implemented in d3d9 */
4550     pCaps->DevCaps2                          = WINED3DDEVCAPS2_STREAMOFFSET |
4551                                                WINED3DDEVCAPS2_VERTEXELEMENTSCANSHARESTREAMOFFSET;
4552     pCaps->MaxNpatchTessellationLevel        = 0;
4553     pCaps->MasterAdapterOrdinal              = 0;
4554     pCaps->AdapterOrdinalInGroup             = 0;
4555     pCaps->NumberOfAdaptersInGroup           = 1;
4556
4557     pCaps->NumSimultaneousRTs = gl_info->limits.buffers;
4558
4559     pCaps->StretchRectFilterCaps             = WINED3DPTFILTERCAPS_MINFPOINT  |
4560                                                 WINED3DPTFILTERCAPS_MAGFPOINT  |
4561                                                 WINED3DPTFILTERCAPS_MINFLINEAR |
4562                                                 WINED3DPTFILTERCAPS_MAGFLINEAR;
4563     pCaps->VertexTextureFilterCaps           = 0;
4564
4565     memset(&shader_caps, 0, sizeof(shader_caps));
4566     adapter->shader_backend->shader_get_caps(&adapter->gl_info, &shader_caps);
4567
4568     memset(&fragment_caps, 0, sizeof(fragment_caps));
4569     adapter->fragment_pipe->get_caps(&adapter->gl_info, &fragment_caps);
4570
4571     /* Add shader misc caps. Only some of them belong to the shader parts of the pipeline */
4572     pCaps->PrimitiveMiscCaps |= fragment_caps.PrimitiveMiscCaps;
4573
4574     /* This takes care for disabling vertex shader or pixel shader caps while leaving the other one enabled.
4575      * Ignore shader model capabilities if disabled in config
4576      */
4577     if(vs_selected_mode == SHADER_NONE) {
4578         TRACE_(d3d_caps)("Vertex shader disabled in config, reporting version 0.0\n");
4579         pCaps->VertexShaderVersion          = WINED3DVS_VERSION(0,0);
4580         pCaps->MaxVertexShaderConst         = 0;
4581     } else {
4582         pCaps->VertexShaderVersion          = shader_caps.VertexShaderVersion;
4583         pCaps->MaxVertexShaderConst         = shader_caps.MaxVertexShaderConst;
4584     }
4585
4586     if(ps_selected_mode == SHADER_NONE) {
4587         TRACE_(d3d_caps)("Pixel shader disabled in config, reporting version 0.0\n");
4588         pCaps->PixelShaderVersion           = WINED3DPS_VERSION(0,0);
4589         pCaps->PixelShader1xMaxValue        = 0.0f;
4590     } else {
4591         pCaps->PixelShaderVersion           = shader_caps.PixelShaderVersion;
4592         pCaps->PixelShader1xMaxValue        = shader_caps.PixelShader1xMaxValue;
4593     }
4594
4595     pCaps->TextureOpCaps                    = fragment_caps.TextureOpCaps;
4596     pCaps->MaxTextureBlendStages            = fragment_caps.MaxTextureBlendStages;
4597     pCaps->MaxSimultaneousTextures          = fragment_caps.MaxSimultaneousTextures;
4598
4599     pCaps->VS20Caps                         = shader_caps.VS20Caps;
4600     pCaps->MaxVShaderInstructionsExecuted   = shader_caps.MaxVShaderInstructionsExecuted;
4601     pCaps->MaxVertexShader30InstructionSlots= shader_caps.MaxVertexShader30InstructionSlots;
4602     pCaps->PS20Caps                         = shader_caps.PS20Caps;
4603     pCaps->MaxPShaderInstructionsExecuted   = shader_caps.MaxPShaderInstructionsExecuted;
4604     pCaps->MaxPixelShader30InstructionSlots = shader_caps.MaxPixelShader30InstructionSlots;
4605
4606     /* The following caps are shader specific, but they are things we cannot detect, or which
4607      * are the same among all shader models. So to avoid code duplication set the shader version
4608      * specific, but otherwise constant caps here
4609      */
4610     if(pCaps->VertexShaderVersion == WINED3DVS_VERSION(3,0)) {
4611         /* Where possible set the caps based on OpenGL extensions and if they aren't set (in case of software rendering)
4612         use the VS 3.0 from MSDN or else if there's OpenGL spec use a hardcoded value minimum VS3.0 value. */
4613         pCaps->VS20Caps.Caps                     = WINED3DVS20CAPS_PREDICATION;
4614         pCaps->VS20Caps.DynamicFlowControlDepth  = WINED3DVS20_MAX_DYNAMICFLOWCONTROLDEPTH; /* VS 3.0 requires MAX_DYNAMICFLOWCONTROLDEPTH (24) */
4615         pCaps->VS20Caps.NumTemps = max(32, adapter->gl_info.limits.arb_vs_temps);
4616         pCaps->VS20Caps.StaticFlowControlDepth   = WINED3DVS20_MAX_STATICFLOWCONTROLDEPTH ; /* level of nesting in loops / if-statements; VS 3.0 requires MAX (4) */
4617
4618         pCaps->MaxVShaderInstructionsExecuted    = 65535; /* VS 3.0 needs at least 65535, some cards even use 2^32-1 */
4619         pCaps->MaxVertexShader30InstructionSlots = max(512, adapter->gl_info.limits.arb_vs_instructions);
4620     }
4621     else if (pCaps->VertexShaderVersion == WINED3DVS_VERSION(2,0))
4622     {
4623         pCaps->VS20Caps.Caps                     = 0;
4624         pCaps->VS20Caps.DynamicFlowControlDepth  = WINED3DVS20_MIN_DYNAMICFLOWCONTROLDEPTH;
4625         pCaps->VS20Caps.NumTemps = max(12, adapter->gl_info.limits.arb_vs_temps);
4626         pCaps->VS20Caps.StaticFlowControlDepth   = 1;
4627
4628         pCaps->MaxVShaderInstructionsExecuted    = 65535;
4629         pCaps->MaxVertexShader30InstructionSlots = 0;
4630     } else { /* VS 1.x */
4631         pCaps->VS20Caps.Caps                     = 0;
4632         pCaps->VS20Caps.DynamicFlowControlDepth  = 0;
4633         pCaps->VS20Caps.NumTemps                 = 0;
4634         pCaps->VS20Caps.StaticFlowControlDepth   = 0;
4635
4636         pCaps->MaxVShaderInstructionsExecuted    = 0;
4637         pCaps->MaxVertexShader30InstructionSlots = 0;
4638     }
4639
4640     if(pCaps->PixelShaderVersion == WINED3DPS_VERSION(3,0)) {
4641         /* Where possible set the caps based on OpenGL extensions and if they aren't set (in case of software rendering)
4642         use the PS 3.0 from MSDN or else if there's OpenGL spec use a hardcoded value minimum PS 3.0 value. */
4643
4644         /* 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 */
4645         pCaps->PS20Caps.Caps                     = WINED3DPS20CAPS_ARBITRARYSWIZZLE     |
4646                 WINED3DPS20CAPS_GRADIENTINSTRUCTIONS |
4647                 WINED3DPS20CAPS_PREDICATION          |
4648                 WINED3DPS20CAPS_NODEPENDENTREADLIMIT |
4649                 WINED3DPS20CAPS_NOTEXINSTRUCTIONLIMIT;
4650         pCaps->PS20Caps.DynamicFlowControlDepth  = WINED3DPS20_MAX_DYNAMICFLOWCONTROLDEPTH; /* PS 3.0 requires MAX_DYNAMICFLOWCONTROLDEPTH (24) */
4651         pCaps->PS20Caps.NumTemps = max(32, adapter->gl_info.limits.arb_ps_temps);
4652         pCaps->PS20Caps.StaticFlowControlDepth   = WINED3DPS20_MAX_STATICFLOWCONTROLDEPTH; /* PS 3.0 requires MAX_STATICFLOWCONTROLDEPTH (4) */
4653         pCaps->PS20Caps.NumInstructionSlots      = WINED3DPS20_MAX_NUMINSTRUCTIONSLOTS; /* PS 3.0 requires MAX_NUMINSTRUCTIONSLOTS (512) */
4654
4655         pCaps->MaxPShaderInstructionsExecuted    = 65535;
4656         pCaps->MaxPixelShader30InstructionSlots = max(WINED3DMIN30SHADERINSTRUCTIONS,
4657                 adapter->gl_info.limits.arb_ps_instructions);
4658     }
4659     else if(pCaps->PixelShaderVersion == WINED3DPS_VERSION(2,0))
4660     {
4661         /* Below we assume PS2.0 specs, not extended 2.0a(GeforceFX)/2.0b(Radeon R3xx) ones */
4662         pCaps->PS20Caps.Caps                     = 0;
4663         pCaps->PS20Caps.DynamicFlowControlDepth  = 0; /* WINED3DVS20_MIN_DYNAMICFLOWCONTROLDEPTH = 0 */
4664         pCaps->PS20Caps.NumTemps = max(12, adapter->gl_info.limits.arb_ps_temps);
4665         pCaps->PS20Caps.StaticFlowControlDepth   = WINED3DPS20_MIN_STATICFLOWCONTROLDEPTH; /* Minimum: 1 */
4666         pCaps->PS20Caps.NumInstructionSlots      = WINED3DPS20_MIN_NUMINSTRUCTIONSLOTS; /* Minimum number (64 ALU + 32 Texture), a GeforceFX uses 512 */
4667
4668         pCaps->MaxPShaderInstructionsExecuted    = 512; /* Minimum value, a GeforceFX uses 1024 */
4669         pCaps->MaxPixelShader30InstructionSlots  = 0;
4670     } else { /* PS 1.x */
4671         pCaps->PS20Caps.Caps                     = 0;
4672         pCaps->PS20Caps.DynamicFlowControlDepth  = 0;
4673         pCaps->PS20Caps.NumTemps                 = 0;
4674         pCaps->PS20Caps.StaticFlowControlDepth   = 0;
4675         pCaps->PS20Caps.NumInstructionSlots      = 0;
4676
4677         pCaps->MaxPShaderInstructionsExecuted    = 0;
4678         pCaps->MaxPixelShader30InstructionSlots  = 0;
4679     }
4680
4681     if(pCaps->VertexShaderVersion >= WINED3DVS_VERSION(2,0)) {
4682         /* OpenGL supports all the formats below, perhaps not always
4683          * without conversion, but it supports them.
4684          * Further GLSL doesn't seem to have an official unsigned type so
4685          * don't advertise it yet as I'm not sure how we handle it.
4686          * We might need to add some clamping in the shader engine to
4687          * support it.
4688          * TODO: WINED3DDTCAPS_USHORT2N, WINED3DDTCAPS_USHORT4N, WINED3DDTCAPS_UDEC3, WINED3DDTCAPS_DEC3N */
4689         pCaps->DeclTypes = WINED3DDTCAPS_UBYTE4    |
4690                            WINED3DDTCAPS_UBYTE4N   |
4691                            WINED3DDTCAPS_SHORT2N   |
4692                            WINED3DDTCAPS_SHORT4N;
4693         if (gl_info->supported[ARB_HALF_FLOAT_VERTEX])
4694         {
4695             pCaps->DeclTypes |= WINED3DDTCAPS_FLOAT16_2 |
4696                                 WINED3DDTCAPS_FLOAT16_4;
4697         }
4698     } else
4699         pCaps->DeclTypes                         = 0;
4700
4701     /* Set DirectDraw helper Caps */
4702     ckey_caps =                         WINEDDCKEYCAPS_DESTBLT              |
4703                                         WINEDDCKEYCAPS_SRCBLT;
4704     fx_caps =                           WINEDDFXCAPS_BLTALPHA               |
4705                                         WINEDDFXCAPS_BLTMIRRORLEFTRIGHT     |
4706                                         WINEDDFXCAPS_BLTMIRRORUPDOWN        |
4707                                         WINEDDFXCAPS_BLTROTATION90          |
4708                                         WINEDDFXCAPS_BLTSHRINKX             |
4709                                         WINEDDFXCAPS_BLTSHRINKXN            |
4710                                         WINEDDFXCAPS_BLTSHRINKY             |
4711                                         WINEDDFXCAPS_BLTSHRINKXN            |
4712                                         WINEDDFXCAPS_BLTSTRETCHX            |
4713                                         WINEDDFXCAPS_BLTSTRETCHXN           |
4714                                         WINEDDFXCAPS_BLTSTRETCHY            |
4715                                         WINEDDFXCAPS_BLTSTRETCHYN;
4716     blit_caps =                         WINEDDCAPS_BLT                      |
4717                                         WINEDDCAPS_BLTCOLORFILL             |
4718                                         WINEDDCAPS_BLTDEPTHFILL             |
4719                                         WINEDDCAPS_BLTSTRETCH               |
4720                                         WINEDDCAPS_CANBLTSYSMEM             |
4721                                         WINEDDCAPS_CANCLIP                  |
4722                                         WINEDDCAPS_CANCLIPSTRETCHED         |
4723                                         WINEDDCAPS_COLORKEY                 |
4724                                         WINEDDCAPS_COLORKEYHWASSIST         |
4725                                         WINEDDCAPS_ALIGNBOUNDARYSRC;
4726
4727     /* Fill the ddraw caps structure */
4728     pCaps->DirectDrawCaps.Caps =        WINEDDCAPS_GDI                      |
4729                                         WINEDDCAPS_PALETTE                  |
4730                                         blit_caps;
4731     pCaps->DirectDrawCaps.Caps2 =       WINEDDCAPS2_CERTIFIED                |
4732                                         WINEDDCAPS2_NOPAGELOCKREQUIRED       |
4733                                         WINEDDCAPS2_PRIMARYGAMMA             |
4734                                         WINEDDCAPS2_WIDESURFACES             |
4735                                         WINEDDCAPS2_CANRENDERWINDOWED;
4736     pCaps->DirectDrawCaps.SVBCaps =     blit_caps;
4737     pCaps->DirectDrawCaps.SVBCKeyCaps = ckey_caps;
4738     pCaps->DirectDrawCaps.SVBFXCaps =   fx_caps;
4739     pCaps->DirectDrawCaps.VSBCaps =     blit_caps;
4740     pCaps->DirectDrawCaps.VSBCKeyCaps = ckey_caps;
4741     pCaps->DirectDrawCaps.VSBFXCaps =   fx_caps;
4742     pCaps->DirectDrawCaps.SSBCaps =     blit_caps;
4743     pCaps->DirectDrawCaps.SSBCKeyCaps = ckey_caps;
4744     pCaps->DirectDrawCaps.SSBFXCaps =   fx_caps;
4745
4746     pCaps->DirectDrawCaps.ddsCaps =     WINEDDSCAPS_ALPHA                   |
4747                                         WINEDDSCAPS_BACKBUFFER              |
4748                                         WINEDDSCAPS_FLIP                    |
4749                                         WINEDDSCAPS_FRONTBUFFER             |
4750                                         WINEDDSCAPS_OFFSCREENPLAIN          |
4751                                         WINEDDSCAPS_PALETTE                 |
4752                                         WINEDDSCAPS_PRIMARYSURFACE          |
4753                                         WINEDDSCAPS_SYSTEMMEMORY            |
4754                                         WINEDDSCAPS_VIDEOMEMORY             |
4755                                         WINEDDSCAPS_VISIBLE;
4756     pCaps->DirectDrawCaps.StrideAlign = DDRAW_PITCH_ALIGNMENT;
4757
4758     /* Set D3D caps if OpenGL is available. */
4759     if (adapter->opengl)
4760     {
4761         pCaps->DirectDrawCaps.ddsCaps |=WINEDDSCAPS_3DDEVICE                |
4762                                         WINEDDSCAPS_MIPMAP                  |
4763                                         WINEDDSCAPS_TEXTURE                 |
4764                                         WINEDDSCAPS_ZBUFFER;
4765         pCaps->DirectDrawCaps.Caps |=   WINEDDCAPS_3D;
4766     }
4767
4768     return WINED3D_OK;
4769 }
4770
4771 static HRESULT WINAPI IWineD3DImpl_CreateDevice(IWineD3D *iface, UINT adapter_idx,
4772         WINED3DDEVTYPE device_type, HWND focus_window, DWORD flags, IUnknown *parent,
4773         IWineD3DDeviceParent *device_parent, IWineD3DDevice **device)
4774 {
4775     IWineD3DImpl *This = (IWineD3DImpl *)iface;
4776     IWineD3DDeviceImpl *object;
4777     HRESULT hr;
4778
4779     TRACE("iface %p, adapter_idx %u, device_type %#x, focus_window %p, flags %#x.\n"
4780             "parent %p, device_parent %p, device %p.\n",
4781             iface, adapter_idx, device_type, focus_window, flags,
4782             parent, device_parent, device);
4783
4784     /* Validate the adapter number. If no adapters are available(no GL), ignore the adapter
4785      * number and create a device without a 3D adapter for 2D only operation. */
4786     if (IWineD3D_GetAdapterCount(iface) && adapter_idx >= IWineD3D_GetAdapterCount(iface))
4787     {
4788         return WINED3DERR_INVALIDCALL;
4789     }
4790
4791     object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
4792     if (!object)
4793     {
4794         ERR("Failed to allocate device memory.\n");
4795         return E_OUTOFMEMORY;
4796     }
4797
4798     hr = device_init(object, This, adapter_idx, device_type, focus_window, flags, parent, device_parent);
4799     if (FAILED(hr))
4800     {
4801         WARN("Failed to initialize device, hr %#x.\n", hr);
4802         HeapFree(GetProcessHeap(), 0, object);
4803         return hr;
4804     }
4805
4806     TRACE("Created device %p.\n", object);
4807     *device = (IWineD3DDevice *)object;
4808
4809     IWineD3DDeviceParent_WineD3DDeviceCreated(device_parent, *device);
4810
4811     return WINED3D_OK;
4812 }
4813
4814 static HRESULT WINAPI IWineD3DImpl_GetParent(IWineD3D *iface, IUnknown **pParent) {
4815     IWineD3DImpl *This = (IWineD3DImpl *)iface;
4816     IUnknown_AddRef(This->parent);
4817     *pParent = This->parent;
4818     return WINED3D_OK;
4819 }
4820
4821 static void WINE_GLAPI invalid_func(const void *data)
4822 {
4823     ERR("Invalid vertex attribute function called\n");
4824     DebugBreak();
4825 }
4826
4827 static void WINE_GLAPI invalid_texcoord_func(GLenum unit, const void *data)
4828 {
4829     ERR("Invalid texcoord function called\n");
4830     DebugBreak();
4831 }
4832
4833 /* Helper functions for providing vertex data to opengl. The arrays are initialized based on
4834  * the extension detection and are used in drawStridedSlow
4835  */
4836 static void WINE_GLAPI position_d3dcolor(const void *data)
4837 {
4838     DWORD pos = *((const DWORD *)data);
4839
4840     FIXME("Add a test for fixed function position from d3dcolor type\n");
4841     glVertex4s(D3DCOLOR_B_R(pos),
4842                D3DCOLOR_B_G(pos),
4843                D3DCOLOR_B_B(pos),
4844                D3DCOLOR_B_A(pos));
4845 }
4846
4847 static void WINE_GLAPI position_float4(const void *data)
4848 {
4849     const GLfloat *pos = data;
4850
4851     if (pos[3] != 0.0f && pos[3] != 1.0f)
4852     {
4853         float w = 1.0f / pos[3];
4854
4855         glVertex4f(pos[0] * w, pos[1] * w, pos[2] * w, w);
4856     }
4857     else
4858     {
4859         glVertex3fv(pos);
4860     }
4861 }
4862
4863 static void WINE_GLAPI diffuse_d3dcolor(const void *data)
4864 {
4865     DWORD diffuseColor = *((const DWORD *)data);
4866
4867     glColor4ub(D3DCOLOR_B_R(diffuseColor),
4868                D3DCOLOR_B_G(diffuseColor),
4869                D3DCOLOR_B_B(diffuseColor),
4870                D3DCOLOR_B_A(diffuseColor));
4871 }
4872
4873 static void WINE_GLAPI specular_d3dcolor(const void *data)
4874 {
4875     DWORD specularColor = *((const DWORD *)data);
4876     GLbyte d[] = {D3DCOLOR_B_R(specularColor),
4877             D3DCOLOR_B_G(specularColor),
4878             D3DCOLOR_B_B(specularColor)};
4879
4880     specular_func_3ubv(d);
4881 }
4882
4883 static void WINE_GLAPI warn_no_specular_func(const void *data)
4884 {
4885     WARN("GL_EXT_secondary_color not supported\n");
4886 }
4887
4888 static void fillGLAttribFuncs(const struct wined3d_gl_info *gl_info)
4889 {
4890     position_funcs[WINED3D_FFP_EMIT_FLOAT1]      = invalid_func;
4891     position_funcs[WINED3D_FFP_EMIT_FLOAT2]      = invalid_func;
4892     position_funcs[WINED3D_FFP_EMIT_FLOAT3]      = (glAttribFunc)glVertex3fv;
4893     position_funcs[WINED3D_FFP_EMIT_FLOAT4]      = position_float4;
4894     position_funcs[WINED3D_FFP_EMIT_D3DCOLOR]    = position_d3dcolor;
4895     position_funcs[WINED3D_FFP_EMIT_UBYTE4]      = invalid_func;
4896     position_funcs[WINED3D_FFP_EMIT_SHORT2]      = invalid_func;
4897     position_funcs[WINED3D_FFP_EMIT_SHORT4]      = (glAttribFunc)glVertex2sv;
4898     position_funcs[WINED3D_FFP_EMIT_UBYTE4N]     = invalid_func;
4899     position_funcs[WINED3D_FFP_EMIT_SHORT2N]     = invalid_func;
4900     position_funcs[WINED3D_FFP_EMIT_SHORT4N]     = invalid_func;
4901     position_funcs[WINED3D_FFP_EMIT_USHORT2N]    = invalid_func;
4902     position_funcs[WINED3D_FFP_EMIT_USHORT4N]    = invalid_func;
4903     position_funcs[WINED3D_FFP_EMIT_UDEC3]       = invalid_func;
4904     position_funcs[WINED3D_FFP_EMIT_DEC3N]       = invalid_func;
4905     position_funcs[WINED3D_FFP_EMIT_FLOAT16_2]   = invalid_func;
4906     position_funcs[WINED3D_FFP_EMIT_FLOAT16_4]   = invalid_func;
4907
4908     diffuse_funcs[WINED3D_FFP_EMIT_FLOAT1]       = invalid_func;
4909     diffuse_funcs[WINED3D_FFP_EMIT_FLOAT2]       = invalid_func;
4910     diffuse_funcs[WINED3D_FFP_EMIT_FLOAT3]       = (glAttribFunc)glColor3fv;
4911     diffuse_funcs[WINED3D_FFP_EMIT_FLOAT4]       = (glAttribFunc)glColor4fv;
4912     diffuse_funcs[WINED3D_FFP_EMIT_D3DCOLOR]     = diffuse_d3dcolor;
4913     diffuse_funcs[WINED3D_FFP_EMIT_UBYTE4]       = invalid_func;
4914     diffuse_funcs[WINED3D_FFP_EMIT_SHORT2]       = invalid_func;
4915     diffuse_funcs[WINED3D_FFP_EMIT_SHORT4]       = invalid_func;
4916     diffuse_funcs[WINED3D_FFP_EMIT_UBYTE4N]      = (glAttribFunc)glColor4ubv;
4917     diffuse_funcs[WINED3D_FFP_EMIT_SHORT2N]      = invalid_func;
4918     diffuse_funcs[WINED3D_FFP_EMIT_SHORT4N]      = (glAttribFunc)glColor4sv;
4919     diffuse_funcs[WINED3D_FFP_EMIT_USHORT2N]     = invalid_func;
4920     diffuse_funcs[WINED3D_FFP_EMIT_USHORT4N]     = (glAttribFunc)glColor4usv;
4921     diffuse_funcs[WINED3D_FFP_EMIT_UDEC3]        = invalid_func;
4922     diffuse_funcs[WINED3D_FFP_EMIT_DEC3N]        = invalid_func;
4923     diffuse_funcs[WINED3D_FFP_EMIT_FLOAT16_2]    = invalid_func;
4924     diffuse_funcs[WINED3D_FFP_EMIT_FLOAT16_4]    = invalid_func;
4925
4926     /* No 4 component entry points here */
4927     specular_funcs[WINED3D_FFP_EMIT_FLOAT1]      = invalid_func;
4928     specular_funcs[WINED3D_FFP_EMIT_FLOAT2]      = invalid_func;
4929     if (gl_info->supported[EXT_SECONDARY_COLOR])
4930     {
4931         specular_funcs[WINED3D_FFP_EMIT_FLOAT3]  = (glAttribFunc)GL_EXTCALL(glSecondaryColor3fvEXT);
4932     }
4933     else
4934     {
4935         specular_funcs[WINED3D_FFP_EMIT_FLOAT3]  = warn_no_specular_func;
4936     }
4937     specular_funcs[WINED3D_FFP_EMIT_FLOAT4]      = invalid_func;
4938     if (gl_info->supported[EXT_SECONDARY_COLOR])
4939     {
4940         specular_func_3ubv = (glAttribFunc)GL_EXTCALL(glSecondaryColor3ubvEXT);
4941         specular_funcs[WINED3D_FFP_EMIT_D3DCOLOR] = specular_d3dcolor;
4942     }
4943     else
4944     {
4945         specular_funcs[WINED3D_FFP_EMIT_D3DCOLOR] = warn_no_specular_func;
4946     }
4947     specular_funcs[WINED3D_FFP_EMIT_UBYTE4]      = invalid_func;
4948     specular_funcs[WINED3D_FFP_EMIT_SHORT2]      = invalid_func;
4949     specular_funcs[WINED3D_FFP_EMIT_SHORT4]      = invalid_func;
4950     specular_funcs[WINED3D_FFP_EMIT_UBYTE4N]     = invalid_func;
4951     specular_funcs[WINED3D_FFP_EMIT_SHORT2N]     = invalid_func;
4952     specular_funcs[WINED3D_FFP_EMIT_SHORT4N]     = invalid_func;
4953     specular_funcs[WINED3D_FFP_EMIT_USHORT2N]    = invalid_func;
4954     specular_funcs[WINED3D_FFP_EMIT_USHORT4N]    = invalid_func;
4955     specular_funcs[WINED3D_FFP_EMIT_UDEC3]       = invalid_func;
4956     specular_funcs[WINED3D_FFP_EMIT_DEC3N]       = invalid_func;
4957     specular_funcs[WINED3D_FFP_EMIT_FLOAT16_2]   = invalid_func;
4958     specular_funcs[WINED3D_FFP_EMIT_FLOAT16_4]   = invalid_func;
4959
4960     /* Only 3 component entry points here. Test how others behave. Float4 normals are used
4961      * by one of our tests, trying to pass it to the pixel shader, which fails on Windows.
4962      */
4963     normal_funcs[WINED3D_FFP_EMIT_FLOAT1]         = invalid_func;
4964     normal_funcs[WINED3D_FFP_EMIT_FLOAT2]         = invalid_func;
4965     normal_funcs[WINED3D_FFP_EMIT_FLOAT3]         = (glAttribFunc)glNormal3fv;
4966     normal_funcs[WINED3D_FFP_EMIT_FLOAT4]         = (glAttribFunc)glNormal3fv; /* Just ignore the 4th value */
4967     normal_funcs[WINED3D_FFP_EMIT_D3DCOLOR]       = invalid_func;
4968     normal_funcs[WINED3D_FFP_EMIT_UBYTE4]         = invalid_func;
4969     normal_funcs[WINED3D_FFP_EMIT_SHORT2]         = invalid_func;
4970     normal_funcs[WINED3D_FFP_EMIT_SHORT4]         = invalid_func;
4971     normal_funcs[WINED3D_FFP_EMIT_UBYTE4N]        = invalid_func;
4972     normal_funcs[WINED3D_FFP_EMIT_SHORT2N]        = invalid_func;
4973     normal_funcs[WINED3D_FFP_EMIT_SHORT4N]        = invalid_func;
4974     normal_funcs[WINED3D_FFP_EMIT_USHORT2N]       = invalid_func;
4975     normal_funcs[WINED3D_FFP_EMIT_USHORT4N]       = invalid_func;
4976     normal_funcs[WINED3D_FFP_EMIT_UDEC3]          = invalid_func;
4977     normal_funcs[WINED3D_FFP_EMIT_DEC3N]          = invalid_func;
4978     normal_funcs[WINED3D_FFP_EMIT_FLOAT16_2]      = invalid_func;
4979     normal_funcs[WINED3D_FFP_EMIT_FLOAT16_4]      = invalid_func;
4980
4981     multi_texcoord_funcs[WINED3D_FFP_EMIT_FLOAT1]    = (glMultiTexCoordFunc)GL_EXTCALL(glMultiTexCoord1fvARB);
4982     multi_texcoord_funcs[WINED3D_FFP_EMIT_FLOAT2]    = (glMultiTexCoordFunc)GL_EXTCALL(glMultiTexCoord2fvARB);
4983     multi_texcoord_funcs[WINED3D_FFP_EMIT_FLOAT3]    = (glMultiTexCoordFunc)GL_EXTCALL(glMultiTexCoord3fvARB);
4984     multi_texcoord_funcs[WINED3D_FFP_EMIT_FLOAT4]    = (glMultiTexCoordFunc)GL_EXTCALL(glMultiTexCoord4fvARB);
4985     multi_texcoord_funcs[WINED3D_FFP_EMIT_D3DCOLOR]  = invalid_texcoord_func;
4986     multi_texcoord_funcs[WINED3D_FFP_EMIT_UBYTE4]    = invalid_texcoord_func;
4987     multi_texcoord_funcs[WINED3D_FFP_EMIT_SHORT2]    = (glMultiTexCoordFunc)GL_EXTCALL(glMultiTexCoord2svARB);
4988     multi_texcoord_funcs[WINED3D_FFP_EMIT_SHORT4]    = (glMultiTexCoordFunc)GL_EXTCALL(glMultiTexCoord4svARB);
4989     multi_texcoord_funcs[WINED3D_FFP_EMIT_UBYTE4N]   = invalid_texcoord_func;
4990     multi_texcoord_funcs[WINED3D_FFP_EMIT_SHORT2N]   = invalid_texcoord_func;
4991     multi_texcoord_funcs[WINED3D_FFP_EMIT_SHORT4N]   = invalid_texcoord_func;
4992     multi_texcoord_funcs[WINED3D_FFP_EMIT_USHORT2N]  = invalid_texcoord_func;
4993     multi_texcoord_funcs[WINED3D_FFP_EMIT_USHORT4N]  = invalid_texcoord_func;
4994     multi_texcoord_funcs[WINED3D_FFP_EMIT_UDEC3]     = invalid_texcoord_func;
4995     multi_texcoord_funcs[WINED3D_FFP_EMIT_DEC3N]     = invalid_texcoord_func;
4996     if (gl_info->supported[NV_HALF_FLOAT])
4997     {
4998         /* Not supported by ARB_HALF_FLOAT_VERTEX, so check for NV_HALF_FLOAT */
4999         multi_texcoord_funcs[WINED3D_FFP_EMIT_FLOAT16_2] = (glMultiTexCoordFunc)GL_EXTCALL(glMultiTexCoord2hvNV);
5000         multi_texcoord_funcs[WINED3D_FFP_EMIT_FLOAT16_4] = (glMultiTexCoordFunc)GL_EXTCALL(glMultiTexCoord4hvNV);
5001     } else {
5002         multi_texcoord_funcs[WINED3D_FFP_EMIT_FLOAT16_2] = invalid_texcoord_func;
5003         multi_texcoord_funcs[WINED3D_FFP_EMIT_FLOAT16_4] = invalid_texcoord_func;
5004     }
5005 }
5006
5007 BOOL InitAdapters(IWineD3DImpl *This)
5008 {
5009     static HMODULE mod_gl;
5010     BOOL ret;
5011     int ps_selected_mode, vs_selected_mode;
5012
5013     /* No need to hold any lock. The calling library makes sure only one thread calls
5014      * wined3d simultaneously
5015      */
5016
5017     TRACE("Initializing adapters\n");
5018
5019     if(!mod_gl) {
5020 #ifdef USE_WIN32_OPENGL
5021 #define USE_GL_FUNC(pfn) pfn = (void*)GetProcAddress(mod_gl, #pfn);
5022         mod_gl = LoadLibraryA("opengl32.dll");
5023         if(!mod_gl) {
5024             ERR("Can't load opengl32.dll!\n");
5025             goto nogl_adapter;
5026         }
5027 #else
5028 #define USE_GL_FUNC(pfn) pfn = (void*)pwglGetProcAddress(#pfn);
5029         /* To bypass the opengl32 thunks load wglGetProcAddress from gdi32 (glXGetProcAddress wrapper) instead of opengl32's */
5030         mod_gl = GetModuleHandleA("gdi32.dll");
5031 #endif
5032     }
5033
5034 /* Load WGL core functions from opengl32.dll */
5035 #define USE_WGL_FUNC(pfn) p##pfn = (void*)GetProcAddress(mod_gl, #pfn);
5036     WGL_FUNCS_GEN;
5037 #undef USE_WGL_FUNC
5038
5039     if(!pwglGetProcAddress) {
5040         ERR("Unable to load wglGetProcAddress!\n");
5041         goto nogl_adapter;
5042     }
5043
5044 /* Dynamically load all GL core functions */
5045     GL_FUNCS_GEN;
5046 #undef USE_GL_FUNC
5047
5048     /* Load glFinish and glFlush from opengl32.dll even if we're not using WIN32 opengl
5049      * otherwise because we have to use winex11.drv's override
5050      */
5051 #ifdef USE_WIN32_OPENGL
5052     wglFinish = (void*)GetProcAddress(mod_gl, "glFinish");
5053     wglFlush = (void*)GetProcAddress(mod_gl, "glFlush");
5054 #else
5055     wglFinish = (void*)pwglGetProcAddress("wglFinish");
5056     wglFlush = (void*)pwglGetProcAddress("wglFlush");
5057 #endif
5058
5059     glEnableWINE = glEnable;
5060     glDisableWINE = glDisable;
5061
5062     /* For now only one default adapter */
5063     {
5064         struct wined3d_adapter *adapter = &This->adapters[0];
5065         const struct wined3d_gl_info *gl_info = &adapter->gl_info;
5066         struct wined3d_fake_gl_ctx fake_gl_ctx = {0};
5067         int iPixelFormat;
5068         int res;
5069         int i;
5070         WineD3D_PixelFormat *cfgs;
5071         DISPLAY_DEVICEW DisplayDevice;
5072         HDC hdc;
5073
5074         TRACE("Initializing default adapter\n");
5075         adapter->ordinal = 0;
5076         adapter->monitorPoint.x = -1;
5077         adapter->monitorPoint.y = -1;
5078
5079         if (!AllocateLocallyUniqueId(&adapter->luid))
5080         {
5081             DWORD err = GetLastError();
5082             ERR("Failed to set adapter LUID (%#x).\n", err);
5083             goto nogl_adapter;
5084         }
5085         TRACE("Allocated LUID %08x:%08x for adapter.\n",
5086                 adapter->luid.HighPart, adapter->luid.LowPart);
5087
5088         if (!WineD3D_CreateFakeGLContext(&fake_gl_ctx))
5089         {
5090             ERR("Failed to get a gl context for default adapter\n");
5091             goto nogl_adapter;
5092         }
5093
5094         ret = IWineD3DImpl_FillGLCaps(adapter);
5095         if(!ret) {
5096             ERR("Failed to initialize gl caps for default adapter\n");
5097             WineD3D_ReleaseFakeGLContext(&fake_gl_ctx);
5098             goto nogl_adapter;
5099         }
5100         ret = initPixelFormats(&adapter->gl_info, adapter->driver_info.vendor);
5101         if(!ret) {
5102             ERR("Failed to init gl formats\n");
5103             WineD3D_ReleaseFakeGLContext(&fake_gl_ctx);
5104             goto nogl_adapter;
5105         }
5106
5107         hdc = fake_gl_ctx.dc;
5108
5109         /* Use the VideoRamSize registry setting when set */
5110         if(wined3d_settings.emulated_textureram)
5111             adapter->TextureRam = wined3d_settings.emulated_textureram;
5112         else
5113             adapter->TextureRam = adapter->gl_info.vidmem;
5114         adapter->UsedTextureRam = 0;
5115         TRACE("Emulating %dMB of texture ram\n", adapter->TextureRam/(1024*1024));
5116
5117         /* Initialize the Adapter's DeviceName which is required for ChangeDisplaySettings and friends */
5118         DisplayDevice.cb = sizeof(DisplayDevice);
5119         EnumDisplayDevicesW(NULL, 0 /* Adapter 0 = iDevNum 0 */, &DisplayDevice, 0);
5120         TRACE("DeviceName: %s\n", debugstr_w(DisplayDevice.DeviceName));
5121         strcpyW(adapter->DeviceName, DisplayDevice.DeviceName);
5122
5123         if (gl_info->supported[WGL_ARB_PIXEL_FORMAT])
5124         {
5125             int attribute;
5126             int attribs[11];
5127             int values[11];
5128             int nAttribs = 0;
5129
5130             attribute = WGL_NUMBER_PIXEL_FORMATS_ARB;
5131             GL_EXTCALL(wglGetPixelFormatAttribivARB(hdc, 0, 0, 1, &attribute, &adapter->nCfgs));
5132
5133             adapter->cfgs = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, adapter->nCfgs *sizeof(WineD3D_PixelFormat));
5134             cfgs = adapter->cfgs;
5135             attribs[nAttribs++] = WGL_RED_BITS_ARB;
5136             attribs[nAttribs++] = WGL_GREEN_BITS_ARB;
5137             attribs[nAttribs++] = WGL_BLUE_BITS_ARB;
5138             attribs[nAttribs++] = WGL_ALPHA_BITS_ARB;
5139             attribs[nAttribs++] = WGL_COLOR_BITS_ARB;
5140             attribs[nAttribs++] = WGL_DEPTH_BITS_ARB;
5141             attribs[nAttribs++] = WGL_STENCIL_BITS_ARB;
5142             attribs[nAttribs++] = WGL_DRAW_TO_WINDOW_ARB;
5143             attribs[nAttribs++] = WGL_PIXEL_TYPE_ARB;
5144             attribs[nAttribs++] = WGL_DOUBLE_BUFFER_ARB;
5145             attribs[nAttribs++] = WGL_AUX_BUFFERS_ARB;
5146
5147             for (iPixelFormat=1; iPixelFormat <= adapter->nCfgs; ++iPixelFormat)
5148             {
5149                 res = GL_EXTCALL(wglGetPixelFormatAttribivARB(hdc, iPixelFormat, 0, nAttribs, attribs, values));
5150
5151                 if(!res)
5152                     continue;
5153
5154                 /* Cache the pixel format */
5155                 cfgs->iPixelFormat = iPixelFormat;
5156                 cfgs->redSize = values[0];
5157                 cfgs->greenSize = values[1];
5158                 cfgs->blueSize = values[2];
5159                 cfgs->alphaSize = values[3];
5160                 cfgs->colorSize = values[4];
5161                 cfgs->depthSize = values[5];
5162                 cfgs->stencilSize = values[6];
5163                 cfgs->windowDrawable = values[7];
5164                 cfgs->iPixelType = values[8];
5165                 cfgs->doubleBuffer = values[9];
5166                 cfgs->auxBuffers = values[10];
5167
5168                 cfgs->numSamples = 0;
5169                 /* Check multisample support */
5170                 if (gl_info->supported[ARB_MULTISAMPLE])
5171                 {
5172                     int attrib[2] = {WGL_SAMPLE_BUFFERS_ARB, WGL_SAMPLES_ARB};
5173                     int value[2];
5174                     if(GL_EXTCALL(wglGetPixelFormatAttribivARB(hdc, iPixelFormat, 0, 2, attrib, value))) {
5175                         /* value[0] = WGL_SAMPLE_BUFFERS_ARB which tells whether multisampling is supported.
5176                         * value[1] = number of multi sample buffers*/
5177                         if(value[0])
5178                             cfgs->numSamples = value[1];
5179                     }
5180                 }
5181
5182                 TRACE("iPixelFormat=%d, iPixelType=%#x, doubleBuffer=%d, RGBA=%d/%d/%d/%d, "
5183                         "depth=%d, stencil=%d, samples=%d, windowDrawable=%d\n",
5184                         cfgs->iPixelFormat, cfgs->iPixelType, cfgs->doubleBuffer,
5185                         cfgs->redSize, cfgs->greenSize, cfgs->blueSize, cfgs->alphaSize,
5186                         cfgs->depthSize, cfgs->stencilSize, cfgs->numSamples, cfgs->windowDrawable);
5187                 cfgs++;
5188             }
5189         }
5190         else
5191         {
5192             int nCfgs = DescribePixelFormat(hdc, 0, 0, 0);
5193             adapter->cfgs = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, nCfgs*sizeof(WineD3D_PixelFormat));
5194             adapter->nCfgs = 0; /* We won't accept all formats e.g. software accelerated ones will be skipped */
5195
5196             cfgs = adapter->cfgs;
5197             for(iPixelFormat=1; iPixelFormat<=nCfgs; iPixelFormat++)
5198             {
5199                 PIXELFORMATDESCRIPTOR ppfd;
5200
5201                 res = DescribePixelFormat(hdc, iPixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &ppfd);
5202                 if(!res)
5203                     continue;
5204
5205                 /* We only want HW acceleration using an OpenGL ICD driver.
5206                  * PFD_GENERIC_FORMAT = slow opengl 1.1 gdi software rendering
5207                  * PFD_GENERIC_ACCELERATED = partial hw acceleration using a MCD driver (e.g. 3dfx minigl)
5208                  */
5209                 if(ppfd.dwFlags & (PFD_GENERIC_FORMAT | PFD_GENERIC_ACCELERATED))
5210                 {
5211                     TRACE("Skipping iPixelFormat=%d because it isn't ICD accelerated\n", iPixelFormat);
5212                     continue;
5213                 }
5214
5215                 cfgs->iPixelFormat = iPixelFormat;
5216                 cfgs->redSize = ppfd.cRedBits;
5217                 cfgs->greenSize = ppfd.cGreenBits;
5218                 cfgs->blueSize = ppfd.cBlueBits;
5219                 cfgs->alphaSize = ppfd.cAlphaBits;
5220                 cfgs->colorSize = ppfd.cColorBits;
5221                 cfgs->depthSize = ppfd.cDepthBits;
5222                 cfgs->stencilSize = ppfd.cStencilBits;
5223                 cfgs->windowDrawable = (ppfd.dwFlags & PFD_DRAW_TO_WINDOW) ? 1 : 0;
5224                 cfgs->iPixelType = (ppfd.iPixelType == PFD_TYPE_RGBA) ? WGL_TYPE_RGBA_ARB : WGL_TYPE_COLORINDEX_ARB;
5225                 cfgs->doubleBuffer = (ppfd.dwFlags & PFD_DOUBLEBUFFER) ? 1 : 0;
5226                 cfgs->auxBuffers = ppfd.cAuxBuffers;
5227                 cfgs->numSamples = 0;
5228
5229                 TRACE("iPixelFormat=%d, iPixelType=%#x, doubleBuffer=%d, RGBA=%d/%d/%d/%d, "
5230                         "depth=%d, stencil=%d, windowDrawable=%d\n",
5231                         cfgs->iPixelFormat, cfgs->iPixelType, cfgs->doubleBuffer,
5232                         cfgs->redSize, cfgs->greenSize, cfgs->blueSize, cfgs->alphaSize,
5233                         cfgs->depthSize, cfgs->stencilSize, cfgs->windowDrawable);
5234                 cfgs++;
5235                 adapter->nCfgs++;
5236             }
5237
5238             /* Yikes we haven't found any suitable formats. This should only happen in case of GDI software rendering which we can't use anyway as its 3D functionality is very, very limited */
5239             if(!adapter->nCfgs)
5240             {
5241                 ERR("Disabling Direct3D because no hardware accelerated pixel formats have been found!\n");
5242
5243                 WineD3D_ReleaseFakeGLContext(&fake_gl_ctx);
5244                 HeapFree(GetProcessHeap(), 0, adapter->cfgs);
5245                 goto nogl_adapter;
5246             }
5247         }
5248
5249         /* D16, D24X8 and D24S8 are common depth / depth+stencil formats. All drivers support them though this doesn't
5250          * mean that the format is offered in hardware. For instance Geforce8 cards don't have offer D16 in hardware
5251          * but just fake it using D24(X8?) which is fine. D3D also allows that.
5252          * Some display drivers (i915 on Linux) only report mixed depth+stencil formats like D24S8. MSDN clearly mentions
5253          * that only on lockable formats (e.g. D16_locked) the bit order is guaranteed and that on other formats the
5254          * driver is allowed to consume more bits EXCEPT for stencil bits.
5255          *
5256          * Mark an adapter with this broken stencil behavior.
5257          */
5258         adapter->brokenStencil = TRUE;
5259         for (i = 0, cfgs = adapter->cfgs; i < adapter->nCfgs; ++i)
5260         {
5261             /* Nearly all drivers offer depth formats without stencil, only on i915 this if-statement won't be entered. */
5262             if(cfgs[i].depthSize && !cfgs[i].stencilSize) {
5263                 adapter->brokenStencil = FALSE;
5264                 break;
5265             }
5266         }
5267
5268         WineD3D_ReleaseFakeGLContext(&fake_gl_ctx);
5269
5270         select_shader_mode(&adapter->gl_info, &ps_selected_mode, &vs_selected_mode);
5271         fillGLAttribFuncs(&adapter->gl_info);
5272         adapter->opengl = TRUE;
5273     }
5274     This->adapter_count = 1;
5275     TRACE("%u adapters successfully initialized\n", This->adapter_count);
5276
5277     return TRUE;
5278
5279 nogl_adapter:
5280     /* Initialize an adapter for ddraw-only memory counting */
5281     memset(This->adapters, 0, sizeof(This->adapters));
5282     This->adapters[0].ordinal = 0;
5283     This->adapters[0].opengl = FALSE;
5284     This->adapters[0].monitorPoint.x = -1;
5285     This->adapters[0].monitorPoint.y = -1;
5286
5287     This->adapters[0].driver_info.name = "Display";
5288     This->adapters[0].driver_info.description = "WineD3D DirectDraw Emulation";
5289     if(wined3d_settings.emulated_textureram) {
5290         This->adapters[0].TextureRam = wined3d_settings.emulated_textureram;
5291     } else {
5292         This->adapters[0].TextureRam = 8 * 1024 * 1024; /* This is plenty for a DDraw-only card */
5293     }
5294
5295     initPixelFormatsNoGL(&This->adapters[0].gl_info);
5296
5297     This->adapter_count = 1;
5298     return FALSE;
5299 }
5300
5301 /**********************************************************
5302  * IWineD3D VTbl follows
5303  **********************************************************/
5304
5305 const IWineD3DVtbl IWineD3D_Vtbl =
5306 {
5307     /* IUnknown */
5308     IWineD3DImpl_QueryInterface,
5309     IWineD3DImpl_AddRef,
5310     IWineD3DImpl_Release,
5311     /* IWineD3D */
5312     IWineD3DImpl_GetParent,
5313     IWineD3DImpl_GetAdapterCount,
5314     IWineD3DImpl_RegisterSoftwareDevice,
5315     IWineD3DImpl_GetAdapterMonitor,
5316     IWineD3DImpl_GetAdapterModeCount,
5317     IWineD3DImpl_EnumAdapterModes,
5318     IWineD3DImpl_GetAdapterDisplayMode,
5319     IWineD3DImpl_GetAdapterIdentifier,
5320     IWineD3DImpl_CheckDeviceMultiSampleType,
5321     IWineD3DImpl_CheckDepthStencilMatch,
5322     IWineD3DImpl_CheckDeviceType,
5323     IWineD3DImpl_CheckDeviceFormat,
5324     IWineD3DImpl_CheckDeviceFormatConversion,
5325     IWineD3DImpl_GetDeviceCaps,
5326     IWineD3DImpl_CreateDevice
5327 };
5328
5329 static void STDMETHODCALLTYPE wined3d_null_wined3d_object_destroyed(void *parent) {}
5330
5331 const struct wined3d_parent_ops wined3d_null_parent_ops =
5332 {
5333     wined3d_null_wined3d_object_destroyed,
5334 };