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