rsaenh: Fix padding bytes check for 0-byte payload.
[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     memcpy(&pIdentifier->adapter_luid, &adapter->luid, sizeof(pIdentifier->adapter_luid));
2428
2429     return WINED3D_OK;
2430 }
2431
2432 static BOOL IWineD3DImpl_IsPixelFormatCompatibleWithRenderFmt(const struct wined3d_gl_info *gl_info,
2433         const WineD3D_PixelFormat *cfg, const struct GlPixelFormatDesc *format_desc)
2434 {
2435     short redSize, greenSize, blueSize, alphaSize, colorBits;
2436
2437     if(!cfg)
2438         return FALSE;
2439
2440     if(cfg->iPixelType == WGL_TYPE_RGBA_ARB) { /* Integer RGBA formats */
2441         if (!getColorBits(format_desc, &redSize, &greenSize, &blueSize, &alphaSize, &colorBits))
2442         {
2443             ERR("Unable to check compatibility for Format=%s\n", debug_d3dformat(format_desc->format));
2444             return FALSE;
2445         }
2446
2447         if(cfg->redSize < redSize)
2448             return FALSE;
2449
2450         if(cfg->greenSize < greenSize)
2451             return FALSE;
2452
2453         if(cfg->blueSize < blueSize)
2454             return FALSE;
2455
2456         if(cfg->alphaSize < alphaSize)
2457             return FALSE;
2458
2459         return TRUE;
2460     } else if(cfg->iPixelType == WGL_TYPE_RGBA_FLOAT_ARB) { /* Float RGBA formats; TODO: WGL_NV_float_buffer */
2461         if (format_desc->format == WINED3DFMT_R16_FLOAT)
2462             return (cfg->redSize == 16 && cfg->greenSize == 0 && cfg->blueSize == 0 && cfg->alphaSize == 0);
2463         if (format_desc->format == WINED3DFMT_R16G16_FLOAT)
2464             return (cfg->redSize == 16 && cfg->greenSize == 16 && cfg->blueSize == 0 && cfg->alphaSize == 0);
2465         if (format_desc->format == WINED3DFMT_R16G16B16A16_FLOAT)
2466             return (cfg->redSize == 16 && cfg->greenSize == 16 && cfg->blueSize == 16 && cfg->alphaSize == 16);
2467         if (format_desc->format == WINED3DFMT_R32_FLOAT)
2468             return (cfg->redSize == 32 && cfg->greenSize == 0 && cfg->blueSize == 0 && cfg->alphaSize == 0);
2469         if (format_desc->format == WINED3DFMT_R32G32_FLOAT)
2470             return (cfg->redSize == 32 && cfg->greenSize == 32 && cfg->blueSize == 0 && cfg->alphaSize == 0);
2471         if (format_desc->format == WINED3DFMT_R32G32B32A32_FLOAT)
2472             return (cfg->redSize == 32 && cfg->greenSize == 32 && cfg->blueSize == 32 && cfg->alphaSize == 32);
2473     } else {
2474         /* Probably a color index mode */
2475         return FALSE;
2476     }
2477
2478     return FALSE;
2479 }
2480
2481 static BOOL IWineD3DImpl_IsPixelFormatCompatibleWithDepthFmt(const struct wined3d_gl_info *gl_info,
2482         const WineD3D_PixelFormat *cfg, const struct GlPixelFormatDesc *format_desc)
2483 {
2484     short depthSize, stencilSize;
2485     BOOL lockable = FALSE;
2486
2487     if(!cfg)
2488         return FALSE;
2489
2490     if (!getDepthStencilBits(format_desc, &depthSize, &stencilSize))
2491     {
2492         ERR("Unable to check compatibility for Format=%s\n", debug_d3dformat(format_desc->format));
2493         return FALSE;
2494     }
2495
2496     if ((format_desc->format == WINED3DFMT_D16_LOCKABLE) || (format_desc->format == WINED3DFMT_D32_FLOAT))
2497         lockable = TRUE;
2498
2499     /* On some modern cards like the Geforce8/9 GLX doesn't offer some dephthstencil formats which D3D9 reports.
2500      * We can safely report 'compatible' formats (e.g. D24 can be used for D16) as long as we aren't dealing with
2501      * a lockable format. This also helps D3D <= 7 as they expect D16 which isn't offered without this on Geforce8 cards. */
2502     if(!(cfg->depthSize == depthSize || (!lockable && cfg->depthSize > depthSize)))
2503         return FALSE;
2504
2505     /* Some cards like Intel i915 ones only offer D24S8 but lots of games also need a format without stencil, so
2506      * allow more stencil bits than requested. */
2507     if(cfg->stencilSize < stencilSize)
2508         return FALSE;
2509
2510     return TRUE;
2511 }
2512
2513 static HRESULT WINAPI IWineD3DImpl_CheckDepthStencilMatch(IWineD3D *iface, UINT Adapter, WINED3DDEVTYPE DeviceType,
2514                                                    WINED3DFORMAT AdapterFormat,
2515                                                    WINED3DFORMAT RenderTargetFormat,
2516                                                    WINED3DFORMAT DepthStencilFormat) {
2517     IWineD3DImpl *This = (IWineD3DImpl *)iface;
2518     int nCfgs;
2519     const WineD3D_PixelFormat *cfgs;
2520     const struct wined3d_adapter *adapter;
2521     const struct GlPixelFormatDesc *rt_format_desc;
2522     const struct GlPixelFormatDesc *ds_format_desc;
2523     int it;
2524
2525     WARN_(d3d_caps)("(%p)-> (STUB) (Adptr:%d, DevType:(%x,%s), AdptFmt:(%x,%s), RendrTgtFmt:(%x,%s), DepthStencilFmt:(%x,%s))\n",
2526            This, Adapter,
2527            DeviceType, debug_d3ddevicetype(DeviceType),
2528            AdapterFormat, debug_d3dformat(AdapterFormat),
2529            RenderTargetFormat, debug_d3dformat(RenderTargetFormat),
2530            DepthStencilFormat, debug_d3dformat(DepthStencilFormat));
2531
2532     if (Adapter >= IWineD3D_GetAdapterCount(iface)) {
2533         TRACE("(%p) Failed: Atapter (%u) higher than supported adapters (%u) returning WINED3DERR_INVALIDCALL\n", This, Adapter, IWineD3D_GetAdapterCount(iface));
2534         return WINED3DERR_INVALIDCALL;
2535     }
2536
2537     adapter = &This->adapters[Adapter];
2538     rt_format_desc = getFormatDescEntry(RenderTargetFormat, &adapter->gl_info);
2539     ds_format_desc = getFormatDescEntry(DepthStencilFormat, &adapter->gl_info);
2540     cfgs = adapter->cfgs;
2541     nCfgs = adapter->nCfgs;
2542     for (it = 0; it < nCfgs; ++it) {
2543         if (IWineD3DImpl_IsPixelFormatCompatibleWithRenderFmt(&adapter->gl_info, &cfgs[it], rt_format_desc))
2544         {
2545             if (IWineD3DImpl_IsPixelFormatCompatibleWithDepthFmt(&adapter->gl_info, &cfgs[it], ds_format_desc))
2546             {
2547                 TRACE_(d3d_caps)("(%p) : Formats matched\n", This);
2548                 return WINED3D_OK;
2549             }
2550         }
2551     }
2552     WARN_(d3d_caps)("unsupported format pair: %s and %s\n", debug_d3dformat(RenderTargetFormat), debug_d3dformat(DepthStencilFormat));
2553
2554     return WINED3DERR_NOTAVAILABLE;
2555 }
2556
2557 static HRESULT WINAPI IWineD3DImpl_CheckDeviceMultiSampleType(IWineD3D *iface, UINT Adapter, WINED3DDEVTYPE DeviceType,
2558         WINED3DFORMAT SurfaceFormat, BOOL Windowed, WINED3DMULTISAMPLE_TYPE MultiSampleType, DWORD *pQualityLevels)
2559 {
2560     IWineD3DImpl *This = (IWineD3DImpl *)iface;
2561     const struct GlPixelFormatDesc *glDesc;
2562     const struct wined3d_adapter *adapter;
2563
2564     TRACE_(d3d_caps)("(%p)-> (Adptr:%d, DevType:(%x,%s), SurfFmt:(%x,%s), Win?%d, MultiSamp:%x, pQual:%p)\n",
2565           This,
2566           Adapter,
2567           DeviceType, debug_d3ddevicetype(DeviceType),
2568           SurfaceFormat, debug_d3dformat(SurfaceFormat),
2569           Windowed,
2570           MultiSampleType,
2571           pQualityLevels);
2572
2573     if (Adapter >= IWineD3D_GetAdapterCount(iface)) {
2574         return WINED3DERR_INVALIDCALL;
2575     }
2576
2577     /* TODO: handle Windowed, add more quality levels */
2578
2579     if (WINED3DMULTISAMPLE_NONE == MultiSampleType) {
2580         if(pQualityLevels) *pQualityLevels = 1;
2581         return WINED3D_OK;
2582     }
2583
2584     /* By default multisampling is disabled right now as it causes issues
2585      * on some Nvidia driver versions and it doesn't work well in combination
2586      * with FBOs yet. */
2587     if(!wined3d_settings.allow_multisampling)
2588         return WINED3DERR_NOTAVAILABLE;
2589
2590     adapter = &This->adapters[Adapter];
2591     glDesc = getFormatDescEntry(SurfaceFormat, &adapter->gl_info);
2592     if (!glDesc) return WINED3DERR_INVALIDCALL;
2593
2594     if(glDesc->Flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL)) {
2595         int i, nCfgs;
2596         const WineD3D_PixelFormat *cfgs;
2597
2598         cfgs = adapter->cfgs;
2599         nCfgs = adapter->nCfgs;
2600         for(i=0; i<nCfgs; i++) {
2601             if(cfgs[i].numSamples != MultiSampleType)
2602                 continue;
2603
2604             if (!IWineD3DImpl_IsPixelFormatCompatibleWithDepthFmt(&adapter->gl_info, &cfgs[i], glDesc))
2605                 continue;
2606
2607             TRACE("Found iPixelFormat=%d to support MultiSampleType=%d for format %s\n", cfgs[i].iPixelFormat, MultiSampleType, debug_d3dformat(SurfaceFormat));
2608
2609             if(pQualityLevels)
2610                 *pQualityLevels = 1; /* Guess at a value! */
2611             return WINED3D_OK;
2612         }
2613     }
2614     else if(glDesc->Flags & WINED3DFMT_FLAG_RENDERTARGET) {
2615         short redSize, greenSize, blueSize, alphaSize, colorBits;
2616         int i, nCfgs;
2617         const WineD3D_PixelFormat *cfgs;
2618
2619         if (!getColorBits(glDesc, &redSize, &greenSize, &blueSize, &alphaSize, &colorBits))
2620         {
2621             ERR("Unable to color bits for format %#x, can't check multisampling capability!\n", SurfaceFormat);
2622             return WINED3DERR_NOTAVAILABLE;
2623         }
2624
2625         cfgs = adapter->cfgs;
2626         nCfgs = adapter->nCfgs;
2627         for(i=0; i<nCfgs; i++) {
2628             if(cfgs[i].numSamples != MultiSampleType)
2629                 continue;
2630             if(cfgs[i].redSize != redSize)
2631                 continue;
2632             if(cfgs[i].greenSize != greenSize)
2633                 continue;
2634             if(cfgs[i].blueSize != blueSize)
2635                 continue;
2636             if(cfgs[i].alphaSize != alphaSize)
2637                 continue;
2638
2639             TRACE("Found iPixelFormat=%d to support MultiSampleType=%d for format %s\n", cfgs[i].iPixelFormat, MultiSampleType, debug_d3dformat(SurfaceFormat));
2640
2641             if(pQualityLevels)
2642                 *pQualityLevels = 1; /* Guess at a value! */
2643             return WINED3D_OK;
2644         }
2645     }
2646     return WINED3DERR_NOTAVAILABLE;
2647 }
2648
2649 static HRESULT WINAPI IWineD3DImpl_CheckDeviceType(IWineD3D *iface, UINT Adapter, WINED3DDEVTYPE DeviceType,
2650                                             WINED3DFORMAT DisplayFormat, WINED3DFORMAT BackBufferFormat, BOOL Windowed) {
2651
2652     IWineD3DImpl *This = (IWineD3DImpl *)iface;
2653     HRESULT hr = WINED3DERR_NOTAVAILABLE;
2654     UINT nmodes;
2655
2656     TRACE_(d3d_caps)("(%p)-> (STUB) (Adptr:%d, CheckType:(%x,%s), DispFmt:(%x,%s), BackBuf:(%x,%s), Win?%d): stub\n",
2657           This,
2658           Adapter,
2659           DeviceType, debug_d3ddevicetype(DeviceType),
2660           DisplayFormat, debug_d3dformat(DisplayFormat),
2661           BackBufferFormat, debug_d3dformat(BackBufferFormat),
2662           Windowed);
2663
2664     if (Adapter >= IWineD3D_GetAdapterCount(iface)) {
2665         WARN_(d3d_caps)("Adapter >= IWineD3D_GetAdapterCount(iface), returning WINED3DERR_INVALIDCALL\n");
2666         return WINED3DERR_INVALIDCALL;
2667     }
2668
2669     /* The task of this function is to check whether a certain display / backbuffer format
2670      * combination is available on the given adapter. In fullscreen mode microsoft specified
2671      * that the display format shouldn't provide alpha and that ignoring alpha the backbuffer
2672      * and display format should match exactly.
2673      * In windowed mode format conversion can occur and this depends on the driver. When format
2674      * conversion is done, this function should nevertheless fail and applications need to use
2675      * CheckDeviceFormatConversion.
2676      * At the moment we assume that fullscreen and windowed have the same capabilities */
2677
2678     /* There are only 4 display formats */
2679     if (!(DisplayFormat == WINED3DFMT_B5G6R5_UNORM
2680             || DisplayFormat == WINED3DFMT_B5G5R5X1_UNORM
2681             || DisplayFormat == WINED3DFMT_B8G8R8X8_UNORM
2682             || DisplayFormat == WINED3DFMT_B10G10R10A2_UNORM))
2683     {
2684         TRACE_(d3d_caps)("Format %s unsupported as display format\n", debug_d3dformat(DisplayFormat));
2685         return WINED3DERR_NOTAVAILABLE;
2686     }
2687
2688     /* If the requested DisplayFormat is not available, don't continue */
2689     nmodes = IWineD3DImpl_GetAdapterModeCount(iface, Adapter, DisplayFormat);
2690     if(!nmodes) {
2691         TRACE_(d3d_caps)("No available modes for display format %s\n", debug_d3dformat(DisplayFormat));
2692         return WINED3DERR_NOTAVAILABLE;
2693     }
2694
2695     /* Windowed mode allows you to specify WINED3DFMT_UNKNOWN for the backbufferformat, it means 'reuse' the display format for the backbuffer */
2696     if(!Windowed && BackBufferFormat == WINED3DFMT_UNKNOWN) {
2697         TRACE_(d3d_caps)("BackBufferFormat WINED3FMT_UNKNOWN not available in Windowed mode\n");
2698         return WINED3DERR_NOTAVAILABLE;
2699     }
2700
2701     /* In FULLSCREEN mode R5G6B5 can only be mixed with backbuffer format R5G6B5 */
2702     if (DisplayFormat == WINED3DFMT_B5G6R5_UNORM && BackBufferFormat != WINED3DFMT_B5G6R5_UNORM)
2703     {
2704         TRACE_(d3d_caps)("Unsupported display/backbuffer format combination %s/%s\n", debug_d3dformat(DisplayFormat), debug_d3dformat(BackBufferFormat));
2705         return WINED3DERR_NOTAVAILABLE;
2706     }
2707
2708     /* In FULLSCREEN mode X1R5G5B5 can only be mixed with backbuffer format *1R5G5B5 */
2709     if (DisplayFormat == WINED3DFMT_B5G5R5X1_UNORM
2710             && !(BackBufferFormat == WINED3DFMT_B5G5R5X1_UNORM || BackBufferFormat == WINED3DFMT_B5G5R5A1_UNORM))
2711     {
2712         TRACE_(d3d_caps)("Unsupported display/backbuffer format combination %s/%s\n", debug_d3dformat(DisplayFormat), debug_d3dformat(BackBufferFormat));
2713         return WINED3DERR_NOTAVAILABLE;
2714     }
2715
2716     /* In FULLSCREEN mode X8R8G8B8 can only be mixed with backbuffer format *8R8G8B8 */
2717     if (DisplayFormat == WINED3DFMT_B8G8R8X8_UNORM
2718             && !(BackBufferFormat == WINED3DFMT_B8G8R8X8_UNORM || BackBufferFormat == WINED3DFMT_B8G8R8A8_UNORM))
2719     {
2720         TRACE_(d3d_caps)("Unsupported display/backbuffer format combination %s/%s\n", debug_d3dformat(DisplayFormat), debug_d3dformat(BackBufferFormat));
2721         return WINED3DERR_NOTAVAILABLE;
2722     }
2723
2724     /* A2R10G10B10 is only allowed in fullscreen mode and it can only be mixed with backbuffer format A2R10G10B10 */
2725     if (DisplayFormat == WINED3DFMT_B10G10R10A2_UNORM
2726             && (BackBufferFormat != WINED3DFMT_B10G10R10A2_UNORM || Windowed))
2727     {
2728         TRACE_(d3d_caps)("Unsupported display/backbuffer format combination %s/%s\n", debug_d3dformat(DisplayFormat), debug_d3dformat(BackBufferFormat));
2729         return WINED3DERR_NOTAVAILABLE;
2730     }
2731
2732     /* Use CheckDeviceFormat to see if the BackBufferFormat is usable with the given DisplayFormat */
2733     hr = IWineD3DImpl_CheckDeviceFormat(iface, Adapter, DeviceType, DisplayFormat, WINED3DUSAGE_RENDERTARGET, WINED3DRTYPE_SURFACE, BackBufferFormat, SURFACE_OPENGL);
2734     if(FAILED(hr))
2735         TRACE_(d3d_caps)("Unsupported display/backbuffer format combination %s/%s\n", debug_d3dformat(DisplayFormat), debug_d3dformat(BackBufferFormat));
2736
2737     return hr;
2738 }
2739
2740
2741 /* Check if we support bumpmapping for a format */
2742 static BOOL CheckBumpMapCapability(struct wined3d_adapter *adapter,
2743         WINED3DDEVTYPE DeviceType, const struct GlPixelFormatDesc *format_desc)
2744 {
2745     const struct fragment_pipeline *fp;
2746
2747     switch(format_desc->format)
2748     {
2749         case WINED3DFMT_R8G8_SNORM:
2750         case WINED3DFMT_R16G16_SNORM:
2751         case WINED3DFMT_R5G5_SNORM_L6_UNORM:
2752         case WINED3DFMT_R8G8_SNORM_L8X8_UNORM:
2753         case WINED3DFMT_R8G8B8A8_SNORM:
2754             /* Ask the fixed function pipeline implementation if it can deal
2755              * with the conversion. If we've got a GL extension giving native
2756              * support this will be an identity conversion. */
2757             fp = select_fragment_implementation(adapter, DeviceType);
2758             if (fp->color_fixup_supported(format_desc->color_fixup))
2759             {
2760                 TRACE_(d3d_caps)("[OK]\n");
2761                 return TRUE;
2762             }
2763             TRACE_(d3d_caps)("[FAILED]\n");
2764             return FALSE;
2765
2766         default:
2767             TRACE_(d3d_caps)("[FAILED]\n");
2768             return FALSE;
2769     }
2770 }
2771
2772 /* Check if the given DisplayFormat + DepthStencilFormat combination is valid for the Adapter */
2773 static BOOL CheckDepthStencilCapability(struct wined3d_adapter *adapter,
2774         const struct GlPixelFormatDesc *display_format_desc, const struct GlPixelFormatDesc *ds_format_desc)
2775 {
2776     int it=0;
2777
2778     /* Only allow depth/stencil formats */
2779     if (!(ds_format_desc->depth_size || ds_format_desc->stencil_size)) return FALSE;
2780
2781     /* Walk through all WGL pixel formats to find a match */
2782     for (it = 0; it < adapter->nCfgs; ++it)
2783     {
2784         WineD3D_PixelFormat *cfg = &adapter->cfgs[it];
2785         if (IWineD3DImpl_IsPixelFormatCompatibleWithRenderFmt(&adapter->gl_info, cfg, display_format_desc))
2786         {
2787             if (IWineD3DImpl_IsPixelFormatCompatibleWithDepthFmt(&adapter->gl_info, cfg, ds_format_desc))
2788             {
2789                 return TRUE;
2790             }
2791         }
2792     }
2793
2794     return FALSE;
2795 }
2796
2797 static BOOL CheckFilterCapability(struct wined3d_adapter *adapter, const struct GlPixelFormatDesc *format_desc)
2798 {
2799     /* The flags entry of a format contains the filtering capability */
2800     if (format_desc->Flags & WINED3DFMT_FLAG_FILTERING) return TRUE;
2801
2802     return FALSE;
2803 }
2804
2805 /* Check the render target capabilities of a format */
2806 static BOOL CheckRenderTargetCapability(struct wined3d_adapter *adapter,
2807         const struct GlPixelFormatDesc *adapter_format_desc, const struct GlPixelFormatDesc *check_format_desc)
2808 {
2809     /* Filter out non-RT formats */
2810     if (!(check_format_desc->Flags & WINED3DFMT_FLAG_RENDERTARGET)) return FALSE;
2811
2812     if(wined3d_settings.offscreen_rendering_mode == ORM_BACKBUFFER) {
2813         WineD3D_PixelFormat *cfgs = adapter->cfgs;
2814         int it;
2815         short AdapterRed, AdapterGreen, AdapterBlue, AdapterAlpha, AdapterTotalSize;
2816         short CheckRed, CheckGreen, CheckBlue, CheckAlpha, CheckTotalSize;
2817
2818         getColorBits(adapter_format_desc, &AdapterRed, &AdapterGreen, &AdapterBlue, &AdapterAlpha, &AdapterTotalSize);
2819         getColorBits(check_format_desc, &CheckRed, &CheckGreen, &CheckBlue, &CheckAlpha, &CheckTotalSize);
2820
2821         /* In backbuffer mode the front and backbuffer share the same WGL pixelformat.
2822          * The format must match in RGB, alpha is allowed to be different. (Only the backbuffer can have alpha) */
2823         if(!((AdapterRed == CheckRed) && (AdapterGreen == CheckGreen) && (AdapterBlue == CheckBlue))) {
2824             TRACE_(d3d_caps)("[FAILED]\n");
2825             return FALSE;
2826         }
2827
2828         /* Check if there is a WGL pixel format matching the requirements, the format should also be window
2829          * drawable (not offscreen; e.g. Nvidia offers R5G6B5 for pbuffers even when X is running at 24bit) */
2830         for (it = 0; it < adapter->nCfgs; ++it)
2831         {
2832             if (cfgs[it].windowDrawable && IWineD3DImpl_IsPixelFormatCompatibleWithRenderFmt(&adapter->gl_info,
2833                     &cfgs[it], check_format_desc))
2834             {
2835                 TRACE_(d3d_caps)("iPixelFormat=%d is compatible with CheckFormat=%s\n",
2836                         cfgs[it].iPixelFormat, debug_d3dformat(check_format_desc->format));
2837                 return TRUE;
2838             }
2839         }
2840     } else if(wined3d_settings.offscreen_rendering_mode == ORM_PBUFFER) {
2841         /* We can probably use this function in FBO mode too on some drivers to get some basic indication of the capabilities. */
2842         WineD3D_PixelFormat *cfgs = adapter->cfgs;
2843         int it;
2844
2845         /* Check if there is a WGL pixel format matching the requirements, the pixel format should also be usable with pbuffers */
2846         for (it = 0; it < adapter->nCfgs; ++it)
2847         {
2848             if (cfgs[it].pbufferDrawable && IWineD3DImpl_IsPixelFormatCompatibleWithRenderFmt(&adapter->gl_info,
2849                     &cfgs[it], check_format_desc))
2850             {
2851                 TRACE_(d3d_caps)("iPixelFormat=%d is compatible with CheckFormat=%s\n",
2852                         cfgs[it].iPixelFormat, debug_d3dformat(check_format_desc->format));
2853                 return TRUE;
2854             }
2855         }
2856     } else if(wined3d_settings.offscreen_rendering_mode == ORM_FBO){
2857         /* For now return TRUE for FBOs until we have some proper checks.
2858          * Note that this function will only be called when the format is around for texturing. */
2859         return TRUE;
2860     }
2861     return FALSE;
2862 }
2863
2864 static BOOL CheckSrgbReadCapability(struct wined3d_adapter *adapter, const struct GlPixelFormatDesc *format_desc)
2865 {
2866     const struct wined3d_gl_info *gl_info = &adapter->gl_info;
2867
2868     /* Check for supported sRGB formats (Texture loading and framebuffer) */
2869     if (!gl_info->supported[EXT_TEXTURE_SRGB])
2870     {
2871         TRACE_(d3d_caps)("[FAILED] GL_EXT_texture_sRGB not supported\n");
2872         return FALSE;
2873     }
2874
2875     switch (format_desc->format)
2876     {
2877         case WINED3DFMT_B8G8R8A8_UNORM:
2878         case WINED3DFMT_B8G8R8X8_UNORM:
2879         case WINED3DFMT_B4G4R4A4_UNORM:
2880         case WINED3DFMT_L8_UNORM:
2881         case WINED3DFMT_L8A8_UNORM:
2882         case WINED3DFMT_DXT1:
2883         case WINED3DFMT_DXT2:
2884         case WINED3DFMT_DXT3:
2885         case WINED3DFMT_DXT4:
2886         case WINED3DFMT_DXT5:
2887             TRACE_(d3d_caps)("[OK]\n");
2888             return TRUE;
2889
2890         default:
2891             TRACE_(d3d_caps)("[FAILED] Gamma texture format %s not supported.\n", debug_d3dformat(format_desc->format));
2892             return FALSE;
2893     }
2894     return FALSE;
2895 }
2896
2897 static BOOL CheckSrgbWriteCapability(struct wined3d_adapter *adapter,
2898         WINED3DDEVTYPE DeviceType, const struct GlPixelFormatDesc *format_desc)
2899 {
2900     /* Only offer SRGB writing on X8R8G8B8/A8R8G8B8 when we use ARB or GLSL shaders as we are
2901      * doing the color fixup in shaders.
2902      * Note Windows drivers (at least on the Geforce 8800) also offer this on R5G6B5. */
2903     if ((format_desc->format == WINED3DFMT_B8G8R8X8_UNORM) || (format_desc->format == WINED3DFMT_B8G8R8A8_UNORM))
2904     {
2905         int vs_selected_mode;
2906         int ps_selected_mode;
2907         select_shader_mode(&adapter->gl_info, &ps_selected_mode, &vs_selected_mode);
2908
2909         if((ps_selected_mode == SHADER_ARB) || (ps_selected_mode == SHADER_GLSL)) {
2910             TRACE_(d3d_caps)("[OK]\n");
2911             return TRUE;
2912         }
2913     }
2914
2915     TRACE_(d3d_caps)("[FAILED] - no SRGB writing support on format=%s\n", debug_d3dformat(format_desc->format));
2916     return FALSE;
2917 }
2918
2919 /* Check if a format support blending in combination with pixel shaders */
2920 static BOOL CheckPostPixelShaderBlendingCapability(struct wined3d_adapter *adapter,
2921         const struct GlPixelFormatDesc *format_desc)
2922 {
2923     /* The flags entry of a format contains the post pixel shader blending capability */
2924     if (format_desc->Flags & WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING) return TRUE;
2925
2926     return FALSE;
2927 }
2928
2929 static BOOL CheckWrapAndMipCapability(struct wined3d_adapter *adapter, const struct GlPixelFormatDesc *format_desc)
2930 {
2931     /* OpenGL supports mipmapping on all formats basically. Wrapping is unsupported,
2932      * but we have to report mipmapping so we cannot reject this flag. Tests show that
2933      * windows reports WRAPANDMIP on unfilterable surfaces as well, apparently to show
2934      * that wrapping is supported. The lack of filtering will sort out the mipmapping
2935      * capability anyway.
2936      *
2937      * For now lets report this on all formats, but in the future we may want to
2938      * restrict it to some should games need that
2939      */
2940     return TRUE;
2941 }
2942
2943 /* Check if a texture format is supported on the given adapter */
2944 static BOOL CheckTextureCapability(struct wined3d_adapter *adapter,
2945         WINED3DDEVTYPE DeviceType, const struct GlPixelFormatDesc *format_desc)
2946 {
2947     const struct wined3d_gl_info *gl_info = &adapter->gl_info;
2948     const shader_backend_t *shader_backend;
2949     const struct fragment_pipeline *fp;
2950
2951     switch (format_desc->format)
2952     {
2953         /*****
2954          *  supported: RGB(A) formats
2955          */
2956         case WINED3DFMT_B8G8R8_UNORM: /* Enable for dx7, blacklisted for 8 and 9 above */
2957         case WINED3DFMT_B8G8R8A8_UNORM:
2958         case WINED3DFMT_B8G8R8X8_UNORM:
2959         case WINED3DFMT_B5G6R5_UNORM:
2960         case WINED3DFMT_B5G5R5X1_UNORM:
2961         case WINED3DFMT_B5G5R5A1_UNORM:
2962         case WINED3DFMT_B4G4R4A4_UNORM:
2963         case WINED3DFMT_A8_UNORM:
2964         case WINED3DFMT_B4G4R4X4_UNORM:
2965         case WINED3DFMT_R8G8B8A8_UNORM:
2966         case WINED3DFMT_R8G8B8X8_UNORM:
2967         case WINED3DFMT_B10G10R10A2_UNORM:
2968         case WINED3DFMT_R10G10B10A2_UNORM:
2969         case WINED3DFMT_R16G16_UNORM:
2970             TRACE_(d3d_caps)("[OK]\n");
2971             return TRUE;
2972
2973         case WINED3DFMT_B2G3R3_UNORM:
2974             TRACE_(d3d_caps)("[FAILED] - Not supported on Windows\n");
2975             return FALSE;
2976
2977         /*****
2978          *  supported: Palettized
2979          */
2980         case WINED3DFMT_P8_UINT:
2981             TRACE_(d3d_caps)("[OK]\n");
2982             return TRUE;
2983         /* No Windows driver offers WINED3DFMT_P8_UINT_A8_UNORM, so don't offer it either */
2984         case WINED3DFMT_P8_UINT_A8_UNORM:
2985             return FALSE;
2986
2987         /*****
2988          *  Supported: (Alpha)-Luminance
2989          */
2990         case WINED3DFMT_L8_UNORM:
2991         case WINED3DFMT_L8A8_UNORM:
2992         case WINED3DFMT_L16_UNORM:
2993             TRACE_(d3d_caps)("[OK]\n");
2994             return TRUE;
2995
2996         /* Not supported on Windows, thus disabled */
2997         case WINED3DFMT_L4A4_UNORM:
2998             TRACE_(d3d_caps)("[FAILED] - not supported on windows\n");
2999             return FALSE;
3000
3001         /*****
3002          *  Supported: Depth/Stencil formats
3003          */
3004         case WINED3DFMT_D16_LOCKABLE:
3005         case WINED3DFMT_D16_UNORM:
3006         case WINED3DFMT_S1_UINT_D15_UNORM:
3007         case WINED3DFMT_X8D24_UNORM:
3008         case WINED3DFMT_S4X4_UINT_D24_UNORM:
3009         case WINED3DFMT_D24_UNORM_S8_UINT:
3010         case WINED3DFMT_S8_UINT_D24_FLOAT:
3011         case WINED3DFMT_D32_UNORM:
3012         case WINED3DFMT_D32_FLOAT:
3013             return TRUE;
3014
3015         /*****
3016          *  Not supported everywhere(depends on GL_ATI_envmap_bumpmap or
3017          *  GL_NV_texture_shader). Emulated by shaders
3018          */
3019         case WINED3DFMT_R8G8_SNORM:
3020         case WINED3DFMT_R8G8_SNORM_L8X8_UNORM:
3021         case WINED3DFMT_R5G5_SNORM_L6_UNORM:
3022         case WINED3DFMT_R8G8B8A8_SNORM:
3023         case WINED3DFMT_R16G16_SNORM:
3024             /* Ask the shader backend if it can deal with the conversion. If
3025              * we've got a GL extension giving native support this will be an
3026              * identity conversion. */
3027             shader_backend = select_shader_backend(adapter, DeviceType);
3028             if (shader_backend->shader_color_fixup_supported(format_desc->color_fixup))
3029             {
3030                 TRACE_(d3d_caps)("[OK]\n");
3031                 return TRUE;
3032             }
3033             TRACE_(d3d_caps)("[FAILED]\n");
3034             return FALSE;
3035
3036         case WINED3DFMT_DXT1:
3037         case WINED3DFMT_DXT2:
3038         case WINED3DFMT_DXT3:
3039         case WINED3DFMT_DXT4:
3040         case WINED3DFMT_DXT5:
3041             if (gl_info->supported[EXT_TEXTURE_COMPRESSION_S3TC])
3042             {
3043                 TRACE_(d3d_caps)("[OK]\n");
3044                 return TRUE;
3045             }
3046             TRACE_(d3d_caps)("[FAILED]\n");
3047             return FALSE;
3048
3049
3050         /*****
3051          *  Odd formats - not supported
3052          */
3053         case WINED3DFMT_VERTEXDATA:
3054         case WINED3DFMT_R16_UINT:
3055         case WINED3DFMT_R32_UINT:
3056         case WINED3DFMT_R16G16B16A16_SNORM:
3057         case WINED3DFMT_R10G10B10_SNORM_A2_UNORM:
3058         case WINED3DFMT_R10G11B11_SNORM:
3059             TRACE_(d3d_caps)("[FAILED]\n"); /* Enable when implemented */
3060             return FALSE;
3061
3062         /*****
3063          *  WINED3DFMT_R8G8_SNORM_Cx: Not supported right now
3064          */
3065         case WINED3DFMT_R8G8_SNORM_Cx:
3066             TRACE_(d3d_caps)("[FAILED]\n"); /* Enable when implemented */
3067             return FALSE;
3068
3069         /* YUV formats */
3070         case WINED3DFMT_UYVY:
3071         case WINED3DFMT_YUY2:
3072             if (gl_info->supported[APPLE_YCBCR_422])
3073             {
3074                 TRACE_(d3d_caps)("[OK]\n");
3075                 return TRUE;
3076             }
3077             TRACE_(d3d_caps)("[FAILED]\n");
3078             return FALSE;
3079         case WINED3DFMT_YV12:
3080             TRACE_(d3d_caps)("[FAILED]\n");
3081             return FALSE;
3082
3083             /* Not supported */
3084         case WINED3DFMT_R16G16B16A16_UNORM:
3085         case WINED3DFMT_B2G3R3A8_UNORM:
3086             TRACE_(d3d_caps)("[FAILED]\n"); /* Enable when implemented */
3087             return FALSE;
3088
3089             /* Floating point formats */
3090         case WINED3DFMT_R16_FLOAT:
3091         case WINED3DFMT_R16G16_FLOAT:
3092         case WINED3DFMT_R16G16B16A16_FLOAT:
3093             if (gl_info->supported[ARB_TEXTURE_FLOAT] && gl_info->supported[ARB_HALF_FLOAT_PIXEL])
3094             {
3095                 TRACE_(d3d_caps)("[OK]\n");
3096                 return TRUE;
3097             }
3098             TRACE_(d3d_caps)("[FAILED]\n");
3099             return FALSE;
3100
3101         case WINED3DFMT_R32_FLOAT:
3102         case WINED3DFMT_R32G32_FLOAT:
3103         case WINED3DFMT_R32G32B32A32_FLOAT:
3104             if (gl_info->supported[ARB_TEXTURE_FLOAT])
3105             {
3106                 TRACE_(d3d_caps)("[OK]\n");
3107                 return TRUE;
3108             }
3109             TRACE_(d3d_caps)("[FAILED]\n");
3110             return FALSE;
3111
3112         /* ATI instancing hack: Although ATI cards do not support Shader Model 3.0, they support
3113          * instancing. To query if the card supports instancing CheckDeviceFormat with the special format
3114          * MAKEFOURCC('I','N','S','T') is used. Should a (broken) app check for this provide a proper return value.
3115          * We can do instancing with all shader versions, but we need vertex shaders.
3116          *
3117          * Additionally applications have to set the D3DRS_POINTSIZE render state to MAKEFOURCC('I','N','S','T') once
3118          * to enable instancing. WineD3D doesn't need that and just ignores it.
3119          *
3120          * With Shader Model 3.0 capable cards Instancing 'just works' in Windows.
3121          */
3122         case WINEMAKEFOURCC('I','N','S','T'):
3123             TRACE("ATI Instancing check hack\n");
3124             if (gl_info->supported[ARB_VERTEX_PROGRAM] || gl_info->supported[ARB_VERTEX_SHADER])
3125             {
3126                 TRACE_(d3d_caps)("[OK]\n");
3127                 return TRUE;
3128             }
3129             TRACE_(d3d_caps)("[FAILED]\n");
3130             return FALSE;
3131
3132         /* Some weird FOURCC formats */
3133         case WINED3DFMT_R8G8_B8G8:
3134         case WINED3DFMT_G8R8_G8B8:
3135         case WINED3DFMT_MULTI2_ARGB8:
3136             TRACE_(d3d_caps)("[FAILED]\n");
3137             return FALSE;
3138
3139         /* Vendor specific formats */
3140         case WINED3DFMT_ATI2N:
3141             if (gl_info->supported[ATI_TEXTURE_COMPRESSION_3DC]
3142                     || gl_info->supported[EXT_TEXTURE_COMPRESSION_RGTC])
3143             {
3144                 shader_backend = select_shader_backend(adapter, DeviceType);
3145                 fp = select_fragment_implementation(adapter, DeviceType);
3146                 if (shader_backend->shader_color_fixup_supported(format_desc->color_fixup)
3147                         && fp->color_fixup_supported(format_desc->color_fixup))
3148                 {
3149                     TRACE_(d3d_caps)("[OK]\n");
3150                     return TRUE;
3151                 }
3152
3153                 TRACE_(d3d_caps)("[OK]\n");
3154                 return TRUE;
3155             }
3156             TRACE_(d3d_caps)("[FAILED]\n");
3157             return FALSE;
3158
3159         case WINED3DFMT_NVHU:
3160         case WINED3DFMT_NVHS:
3161             /* These formats seem to be similar to the HILO formats in GL_NV_texture_shader. NVHU
3162              * is said to be GL_UNSIGNED_HILO16, NVHS GL_SIGNED_HILO16. Rumours say that d3d computes
3163              * a 3rd channel similarly to D3DFMT_CxV8U8(So NVHS could be called D3DFMT_CxV16U16).
3164              * ATI refused to support formats which can easilly be emulated with pixel shaders, so
3165              * Applications have to deal with not having NVHS and NVHU.
3166              */
3167             TRACE_(d3d_caps)("[FAILED]\n");
3168             return FALSE;
3169
3170         case WINED3DFMT_UNKNOWN:
3171             return FALSE;
3172
3173         default:
3174             ERR("Unhandled format=%s\n", debug_d3dformat(format_desc->format));
3175             break;
3176     }
3177     return FALSE;
3178 }
3179
3180 static BOOL CheckSurfaceCapability(struct wined3d_adapter *adapter, const struct GlPixelFormatDesc *adapter_format_desc,
3181         WINED3DDEVTYPE DeviceType, const struct GlPixelFormatDesc *check_format_desc, WINED3DSURFTYPE SurfaceType)
3182 {
3183     const struct blit_shader *blitter;
3184
3185     if(SurfaceType == SURFACE_GDI) {
3186         switch(check_format_desc->format)
3187         {
3188             case WINED3DFMT_B8G8R8_UNORM:
3189             case WINED3DFMT_B8G8R8A8_UNORM:
3190             case WINED3DFMT_B8G8R8X8_UNORM:
3191             case WINED3DFMT_B5G6R5_UNORM:
3192             case WINED3DFMT_B5G5R5X1_UNORM:
3193             case WINED3DFMT_B5G5R5A1_UNORM:
3194             case WINED3DFMT_B4G4R4A4_UNORM:
3195             case WINED3DFMT_B2G3R3_UNORM:
3196             case WINED3DFMT_A8_UNORM:
3197             case WINED3DFMT_B2G3R3A8_UNORM:
3198             case WINED3DFMT_B4G4R4X4_UNORM:
3199             case WINED3DFMT_R10G10B10A2_UNORM:
3200             case WINED3DFMT_R8G8B8A8_UNORM:
3201             case WINED3DFMT_R8G8B8X8_UNORM:
3202             case WINED3DFMT_R16G16_UNORM:
3203             case WINED3DFMT_B10G10R10A2_UNORM:
3204             case WINED3DFMT_R16G16B16A16_UNORM:
3205             case WINED3DFMT_P8_UINT:
3206                 TRACE_(d3d_caps)("[OK]\n");
3207                 return TRUE;
3208             default:
3209                 TRACE_(d3d_caps)("[FAILED] - not available on GDI surfaces\n");
3210                 return FALSE;
3211         }
3212     }
3213
3214     /* All format that are supported for textures are supported for surfaces as well */
3215     if (CheckTextureCapability(adapter, DeviceType, check_format_desc)) return TRUE;
3216     /* All depth stencil formats are supported on surfaces */
3217     if (CheckDepthStencilCapability(adapter, adapter_format_desc, check_format_desc)) return TRUE;
3218
3219     /* If opengl can't process the format natively, the blitter may be able to convert it */
3220     blitter = select_blit_implementation(adapter, DeviceType);
3221     if (blitter->color_fixup_supported(check_format_desc->color_fixup))
3222     {
3223         TRACE_(d3d_caps)("[OK]\n");
3224         return TRUE;
3225     }
3226
3227     /* Reject other formats */
3228     TRACE_(d3d_caps)("[FAILED]\n");
3229     return FALSE;
3230 }
3231
3232 static BOOL CheckVertexTextureCapability(struct wined3d_adapter *adapter, const struct GlPixelFormatDesc *format_desc)
3233 {
3234     const struct wined3d_gl_info *gl_info = &adapter->gl_info;
3235
3236     if (!gl_info->limits.vertex_samplers)
3237     {
3238         TRACE_(d3d_caps)("[FAILED]\n");
3239         return FALSE;
3240     }
3241
3242     switch (format_desc->format)
3243     {
3244         case WINED3DFMT_R32G32B32A32_FLOAT:
3245             if (!gl_info->supported[ARB_TEXTURE_FLOAT])
3246             {
3247                 TRACE_(d3d_caps)("[FAILED]\n");
3248                 return FALSE;
3249             }
3250             TRACE_(d3d_caps)("[OK]\n");
3251             return TRUE;
3252
3253         default:
3254             TRACE_(d3d_caps)("[FAILED]\n");
3255             return FALSE;
3256     }
3257     return FALSE;
3258 }
3259
3260 static HRESULT WINAPI IWineD3DImpl_CheckDeviceFormat(IWineD3D *iface, UINT Adapter, WINED3DDEVTYPE DeviceType,
3261         WINED3DFORMAT AdapterFormat, DWORD Usage, WINED3DRESOURCETYPE RType, WINED3DFORMAT CheckFormat,
3262         WINED3DSURFTYPE SurfaceType)
3263 {
3264     IWineD3DImpl *This = (IWineD3DImpl *)iface;
3265     struct wined3d_adapter *adapter = &This->adapters[Adapter];
3266     const struct wined3d_gl_info *gl_info = &adapter->gl_info;
3267     const struct GlPixelFormatDesc *format_desc = getFormatDescEntry(CheckFormat, gl_info);
3268     const struct GlPixelFormatDesc *adapter_format_desc = getFormatDescEntry(AdapterFormat, gl_info);
3269     DWORD UsageCaps = 0;
3270
3271     TRACE_(d3d_caps)("(%p)-> (STUB) (Adptr:%d, DevType:(%u,%s), AdptFmt:(%u,%s), Use:(%u,%s,%s), ResTyp:(%x,%s), CheckFmt:(%u,%s))\n",
3272           This,
3273           Adapter,
3274           DeviceType, debug_d3ddevicetype(DeviceType),
3275           AdapterFormat, debug_d3dformat(AdapterFormat),
3276           Usage, debug_d3dusage(Usage), debug_d3dusagequery(Usage),
3277           RType, debug_d3dresourcetype(RType),
3278           CheckFormat, debug_d3dformat(CheckFormat));
3279
3280     if (Adapter >= IWineD3D_GetAdapterCount(iface)) {
3281         return WINED3DERR_INVALIDCALL;
3282     }
3283
3284     if(RType == WINED3DRTYPE_CUBETEXTURE) {
3285
3286         if(SurfaceType != SURFACE_OPENGL) {
3287             TRACE("[FAILED]\n");
3288             return WINED3DERR_NOTAVAILABLE;
3289         }
3290
3291         /* Cubetexture allows:
3292          *                    - D3DUSAGE_AUTOGENMIPMAP
3293          *                    - D3DUSAGE_DEPTHSTENCIL
3294          *                    - D3DUSAGE_DYNAMIC
3295          *                    - D3DUSAGE_NONSECURE (d3d9ex)
3296          *                    - D3DUSAGE_RENDERTARGET
3297          *                    - D3DUSAGE_SOFTWAREPROCESSING
3298          *                    - D3DUSAGE_QUERY_WRAPANDMIP
3299          */
3300         if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
3301         {
3302             /* Check if the texture format is around */
3303             if (CheckTextureCapability(adapter, DeviceType, format_desc))
3304             {
3305                 if(Usage & WINED3DUSAGE_AUTOGENMIPMAP) {
3306                     /* Check for automatic mipmap generation support */
3307                     if (gl_info->supported[SGIS_GENERATE_MIPMAP])
3308                     {
3309                         UsageCaps |= WINED3DUSAGE_AUTOGENMIPMAP;
3310                     } else {
3311                         /* When autogenmipmap isn't around continue and return WINED3DOK_NOAUTOGEN instead of D3D_OK */
3312                         TRACE_(d3d_caps)("[FAILED] - No autogenmipmap support, but continuing\n");
3313                     }
3314                 }
3315
3316                 /* Always report dynamic locking */
3317                 if(Usage & WINED3DUSAGE_DYNAMIC)
3318                     UsageCaps |= WINED3DUSAGE_DYNAMIC;
3319
3320                 if(Usage & WINED3DUSAGE_RENDERTARGET) {
3321                     if(CheckRenderTargetCapability(adapter, adapter_format_desc, format_desc))
3322                     {
3323                         UsageCaps |= WINED3DUSAGE_RENDERTARGET;
3324                     } else {
3325                         TRACE_(d3d_caps)("[FAILED] - No rendertarget support\n");
3326                         return WINED3DERR_NOTAVAILABLE;
3327                     }
3328                 }
3329
3330                 /* Always report software processing */
3331                 if(Usage & WINED3DUSAGE_SOFTWAREPROCESSING)
3332                     UsageCaps |= WINED3DUSAGE_SOFTWAREPROCESSING;
3333
3334                 /* Check QUERY_FILTER support */
3335                 if(Usage & WINED3DUSAGE_QUERY_FILTER) {
3336                     if (CheckFilterCapability(adapter, format_desc))
3337                     {
3338                         UsageCaps |= WINED3DUSAGE_QUERY_FILTER;
3339                     } else {
3340                         TRACE_(d3d_caps)("[FAILED] - No query filter support\n");
3341                         return WINED3DERR_NOTAVAILABLE;
3342                     }
3343                 }
3344
3345                 /* Check QUERY_POSTPIXELSHADER_BLENDING support */
3346                 if(Usage & WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING) {
3347                     if (CheckPostPixelShaderBlendingCapability(adapter, format_desc))
3348                     {
3349                         UsageCaps |= WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING;
3350                     } else {
3351                         TRACE_(d3d_caps)("[FAILED] - No query post pixelshader blending support\n");
3352                         return WINED3DERR_NOTAVAILABLE;
3353                     }
3354                 }
3355
3356                 /* Check QUERY_SRGBREAD support */
3357                 if(Usage & WINED3DUSAGE_QUERY_SRGBREAD) {
3358                     if (CheckSrgbReadCapability(adapter, format_desc))
3359                     {
3360                         UsageCaps |= WINED3DUSAGE_QUERY_SRGBREAD;
3361                     } else {
3362                         TRACE_(d3d_caps)("[FAILED] - No query srgbread support\n");
3363                         return WINED3DERR_NOTAVAILABLE;
3364                     }
3365                 }
3366
3367                 /* Check QUERY_SRGBWRITE support */
3368                 if(Usage & WINED3DUSAGE_QUERY_SRGBWRITE) {
3369                     if (CheckSrgbWriteCapability(adapter, DeviceType, format_desc))
3370                     {
3371                         UsageCaps |= WINED3DUSAGE_QUERY_SRGBWRITE;
3372                     } else {
3373                         TRACE_(d3d_caps)("[FAILED] - No query srgbwrite support\n");
3374                         return WINED3DERR_NOTAVAILABLE;
3375                     }
3376                 }
3377
3378                 /* Check QUERY_VERTEXTEXTURE support */
3379                 if(Usage & WINED3DUSAGE_QUERY_VERTEXTEXTURE) {
3380                     if (CheckVertexTextureCapability(adapter, format_desc))
3381                     {
3382                         UsageCaps |= WINED3DUSAGE_QUERY_VERTEXTEXTURE;
3383                     } else {
3384                         TRACE_(d3d_caps)("[FAILED] - No query vertextexture support\n");
3385                         return WINED3DERR_NOTAVAILABLE;
3386                     }
3387                 }
3388
3389                 /* Check QUERY_WRAPANDMIP support */
3390                 if(Usage & WINED3DUSAGE_QUERY_WRAPANDMIP) {
3391                     if (CheckWrapAndMipCapability(adapter, format_desc))
3392                     {
3393                         UsageCaps |= WINED3DUSAGE_QUERY_WRAPANDMIP;
3394                     } else {
3395                         TRACE_(d3d_caps)("[FAILED] - No wrapping and mipmapping support\n");
3396                         return WINED3DERR_NOTAVAILABLE;
3397                     }
3398                 }
3399             } else {
3400                 TRACE_(d3d_caps)("[FAILED] - Cube texture format not supported\n");
3401                 return WINED3DERR_NOTAVAILABLE;
3402             }
3403         } else {
3404             TRACE_(d3d_caps)("[FAILED] - No cube texture support\n");
3405             return WINED3DERR_NOTAVAILABLE;
3406         }
3407     } else if(RType == WINED3DRTYPE_SURFACE) {
3408         /* Surface allows:
3409          *                - D3DUSAGE_DEPTHSTENCIL
3410          *                - D3DUSAGE_NONSECURE (d3d9ex)
3411          *                - D3DUSAGE_RENDERTARGET
3412          */
3413
3414         if (CheckSurfaceCapability(adapter, adapter_format_desc, DeviceType, format_desc, SurfaceType))
3415         {
3416             if(Usage & WINED3DUSAGE_DEPTHSTENCIL) {
3417                 if (CheckDepthStencilCapability(adapter, adapter_format_desc, format_desc))
3418                 {
3419                     UsageCaps |= WINED3DUSAGE_DEPTHSTENCIL;
3420                 } else {
3421                     TRACE_(d3d_caps)("[FAILED] - No depthstencil support\n");
3422                     return WINED3DERR_NOTAVAILABLE;
3423                 }
3424             }
3425
3426             if(Usage & WINED3DUSAGE_RENDERTARGET) {
3427                 if (CheckRenderTargetCapability(adapter, adapter_format_desc, format_desc))
3428                 {
3429                     UsageCaps |= WINED3DUSAGE_RENDERTARGET;
3430                 } else {
3431                     TRACE_(d3d_caps)("[FAILED] - No rendertarget support\n");
3432                     return WINED3DERR_NOTAVAILABLE;
3433                 }
3434             }
3435
3436             /* Check QUERY_POSTPIXELSHADER_BLENDING support */
3437             if(Usage & WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING) {
3438                 if (CheckPostPixelShaderBlendingCapability(adapter, format_desc))
3439                 {
3440                     UsageCaps |= WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING;
3441                 } else {
3442                     TRACE_(d3d_caps)("[FAILED] - No query post pixelshader blending support\n");
3443                     return WINED3DERR_NOTAVAILABLE;
3444                 }
3445             }
3446         } else {
3447             TRACE_(d3d_caps)("[FAILED] - Not supported for plain surfaces\n");
3448             return WINED3DERR_NOTAVAILABLE;
3449         }
3450
3451     } else if(RType == WINED3DRTYPE_TEXTURE) {
3452         /* Texture allows:
3453          *                - D3DUSAGE_AUTOGENMIPMAP
3454          *                - D3DUSAGE_DEPTHSTENCIL
3455          *                - D3DUSAGE_DMAP
3456          *                - D3DUSAGE_DYNAMIC
3457          *                - D3DUSAGE_NONSECURE (d3d9ex)
3458          *                - D3DUSAGE_RENDERTARGET
3459          *                - D3DUSAGE_SOFTWAREPROCESSING
3460          *                - D3DUSAGE_TEXTAPI (d3d9ex)
3461          *                - D3DUSAGE_QUERY_WRAPANDMIP
3462          */
3463
3464         if(SurfaceType != SURFACE_OPENGL) {
3465             TRACE("[FAILED]\n");
3466             return WINED3DERR_NOTAVAILABLE;
3467         }
3468
3469         /* Check if the texture format is around */
3470         if (CheckTextureCapability(adapter, DeviceType, format_desc))
3471         {
3472             if(Usage & WINED3DUSAGE_AUTOGENMIPMAP) {
3473                 /* Check for automatic mipmap generation support */
3474                 if (gl_info->supported[SGIS_GENERATE_MIPMAP])
3475                 {
3476                     UsageCaps |= WINED3DUSAGE_AUTOGENMIPMAP;
3477                 } else {
3478                     /* When autogenmipmap isn't around continue and return WINED3DOK_NOAUTOGEN instead of D3D_OK */
3479                     TRACE_(d3d_caps)("[FAILED] - No autogenmipmap support, but continuing\n");
3480                 }
3481             }
3482
3483             /* Always report dynamic locking */
3484             if(Usage & WINED3DUSAGE_DYNAMIC)
3485                 UsageCaps |= WINED3DUSAGE_DYNAMIC;
3486
3487             if(Usage & WINED3DUSAGE_RENDERTARGET) {
3488                 if (CheckRenderTargetCapability(adapter, adapter_format_desc, format_desc))
3489                 {
3490                     UsageCaps |= WINED3DUSAGE_RENDERTARGET;
3491                 } else {
3492                     TRACE_(d3d_caps)("[FAILED] - No rendertarget support\n");
3493                      return WINED3DERR_NOTAVAILABLE;
3494                  }
3495             }
3496
3497             /* Always report software processing */
3498             if(Usage & WINED3DUSAGE_SOFTWAREPROCESSING)
3499                 UsageCaps |= WINED3DUSAGE_SOFTWAREPROCESSING;
3500
3501             /* Check QUERY_FILTER support */
3502             if(Usage & WINED3DUSAGE_QUERY_FILTER) {
3503                 if (CheckFilterCapability(adapter, format_desc))
3504                 {
3505                     UsageCaps |= WINED3DUSAGE_QUERY_FILTER;
3506                 } else {
3507                     TRACE_(d3d_caps)("[FAILED] - No query filter support\n");
3508                     return WINED3DERR_NOTAVAILABLE;
3509                 }
3510             }
3511
3512             /* Check QUERY_LEGACYBUMPMAP support */
3513             if(Usage & WINED3DUSAGE_QUERY_LEGACYBUMPMAP) {
3514                 if (CheckBumpMapCapability(adapter, DeviceType, format_desc))
3515                 {
3516                     UsageCaps |= WINED3DUSAGE_QUERY_LEGACYBUMPMAP;
3517                 } else {
3518                     TRACE_(d3d_caps)("[FAILED] - No legacy bumpmap support\n");
3519                     return WINED3DERR_NOTAVAILABLE;
3520                 }
3521             }
3522
3523             /* Check QUERY_POSTPIXELSHADER_BLENDING support */
3524             if(Usage & WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING) {
3525                 if (CheckPostPixelShaderBlendingCapability(adapter, format_desc))
3526                 {
3527                     UsageCaps |= WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING;
3528                 } else {
3529                     TRACE_(d3d_caps)("[FAILED] - No query post pixelshader blending support\n");
3530                     return WINED3DERR_NOTAVAILABLE;
3531                 }
3532             }
3533
3534             /* Check QUERY_SRGBREAD support */
3535             if(Usage & WINED3DUSAGE_QUERY_SRGBREAD) {
3536                 if (CheckSrgbReadCapability(adapter, format_desc))
3537                 {
3538                     UsageCaps |= WINED3DUSAGE_QUERY_SRGBREAD;
3539                 } else {
3540                     TRACE_(d3d_caps)("[FAILED] - No query srgbread support\n");
3541                     return WINED3DERR_NOTAVAILABLE;
3542                 }
3543             }
3544
3545             /* Check QUERY_SRGBWRITE support */
3546             if(Usage & WINED3DUSAGE_QUERY_SRGBWRITE) {
3547                 if (CheckSrgbWriteCapability(adapter, DeviceType, format_desc))
3548                 {
3549                     UsageCaps |= WINED3DUSAGE_QUERY_SRGBWRITE;
3550                 } else {
3551                     TRACE_(d3d_caps)("[FAILED] - No query srgbwrite support\n");
3552                     return WINED3DERR_NOTAVAILABLE;
3553                 }
3554             }
3555
3556             /* Check QUERY_VERTEXTEXTURE support */
3557             if(Usage & WINED3DUSAGE_QUERY_VERTEXTEXTURE) {
3558                 if (CheckVertexTextureCapability(adapter, format_desc))
3559                 {
3560                     UsageCaps |= WINED3DUSAGE_QUERY_VERTEXTEXTURE;
3561                 } else {
3562                     TRACE_(d3d_caps)("[FAILED] - No query vertextexture support\n");
3563                     return WINED3DERR_NOTAVAILABLE;
3564                 }
3565             }
3566
3567             /* Check QUERY_WRAPANDMIP support */
3568             if(Usage & WINED3DUSAGE_QUERY_WRAPANDMIP) {
3569                 if (CheckWrapAndMipCapability(adapter, format_desc))
3570                 {
3571                     UsageCaps |= WINED3DUSAGE_QUERY_WRAPANDMIP;
3572                 } else {
3573                     TRACE_(d3d_caps)("[FAILED] - No wrapping and mipmapping support\n");
3574                     return WINED3DERR_NOTAVAILABLE;
3575                 }
3576             }
3577
3578             if(Usage & WINED3DUSAGE_DEPTHSTENCIL) {
3579                 if (CheckDepthStencilCapability(adapter, adapter_format_desc, format_desc))
3580                 {
3581                     UsageCaps |= WINED3DUSAGE_DEPTHSTENCIL;
3582                 } else {
3583                     TRACE_(d3d_caps)("[FAILED] - No depth stencil support\n");
3584                     return WINED3DERR_NOTAVAILABLE;
3585                 }
3586             }
3587         } else {
3588             TRACE_(d3d_caps)("[FAILED] - Texture format not supported\n");
3589             return WINED3DERR_NOTAVAILABLE;
3590         }
3591     } else if((RType == WINED3DRTYPE_VOLUME) || (RType == WINED3DRTYPE_VOLUMETEXTURE)) {
3592         /* Volume is to VolumeTexture what Surface is to Texture but its usage caps are not documented.
3593          * Most driver seem to offer (nearly) the same on Volume and VolumeTexture, so do that too.
3594          *
3595          * Volumetexture allows:
3596          *                      - D3DUSAGE_DYNAMIC
3597          *                      - D3DUSAGE_NONSECURE (d3d9ex)
3598          *                      - D3DUSAGE_SOFTWAREPROCESSING
3599          *                      - D3DUSAGE_QUERY_WRAPANDMIP
3600          */
3601
3602         if(SurfaceType != SURFACE_OPENGL) {
3603             TRACE("[FAILED]\n");
3604             return WINED3DERR_NOTAVAILABLE;
3605         }
3606
3607         /* Check volume texture and volume usage caps */
3608         if (gl_info->supported[EXT_TEXTURE3D])
3609         {
3610             if (!CheckTextureCapability(adapter, DeviceType, format_desc))
3611             {
3612                 TRACE_(d3d_caps)("[FAILED] - Format not supported\n");
3613                 return WINED3DERR_NOTAVAILABLE;
3614             }
3615
3616             /* Always report dynamic locking */
3617             if(Usage & WINED3DUSAGE_DYNAMIC)
3618                 UsageCaps |= WINED3DUSAGE_DYNAMIC;
3619
3620             /* Always report software processing */
3621             if(Usage & WINED3DUSAGE_SOFTWAREPROCESSING)
3622                 UsageCaps |= WINED3DUSAGE_SOFTWAREPROCESSING;
3623
3624             /* Check QUERY_FILTER support */
3625             if(Usage & WINED3DUSAGE_QUERY_FILTER) {
3626                 if (CheckFilterCapability(adapter, format_desc))
3627                 {
3628                     UsageCaps |= WINED3DUSAGE_QUERY_FILTER;
3629                 } else {
3630                     TRACE_(d3d_caps)("[FAILED] - No query filter support\n");
3631                     return WINED3DERR_NOTAVAILABLE;
3632                 }
3633             }
3634
3635             /* Check QUERY_POSTPIXELSHADER_BLENDING support */
3636             if(Usage & WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING) {
3637                 if (CheckPostPixelShaderBlendingCapability(adapter, format_desc))
3638                 {
3639                     UsageCaps |= WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING;
3640                 } else {
3641                     TRACE_(d3d_caps)("[FAILED] - No query post pixelshader blending support\n");
3642                     return WINED3DERR_NOTAVAILABLE;
3643                 }
3644             }
3645
3646             /* Check QUERY_SRGBREAD support */
3647             if(Usage & WINED3DUSAGE_QUERY_SRGBREAD) {
3648                 if (CheckSrgbReadCapability(adapter, format_desc))
3649                 {
3650                     UsageCaps |= WINED3DUSAGE_QUERY_SRGBREAD;
3651                 } else {
3652                     TRACE_(d3d_caps)("[FAILED] - No query srgbread support\n");
3653                     return WINED3DERR_NOTAVAILABLE;
3654                 }
3655             }
3656
3657             /* Check QUERY_SRGBWRITE support */
3658             if(Usage & WINED3DUSAGE_QUERY_SRGBWRITE) {
3659                 if (CheckSrgbWriteCapability(adapter, DeviceType, format_desc))
3660                 {
3661                     UsageCaps |= WINED3DUSAGE_QUERY_SRGBWRITE;
3662                 } else {
3663                     TRACE_(d3d_caps)("[FAILED] - No query srgbwrite support\n");
3664                     return WINED3DERR_NOTAVAILABLE;
3665                 }
3666             }
3667
3668             /* Check QUERY_VERTEXTEXTURE support */
3669             if(Usage & WINED3DUSAGE_QUERY_VERTEXTEXTURE) {
3670                 if (CheckVertexTextureCapability(adapter, format_desc))
3671                 {
3672                     UsageCaps |= WINED3DUSAGE_QUERY_VERTEXTEXTURE;
3673                 } else {
3674                     TRACE_(d3d_caps)("[FAILED] - No query vertextexture support\n");
3675                     return WINED3DERR_NOTAVAILABLE;
3676                 }
3677             }
3678
3679             /* Check QUERY_WRAPANDMIP support */
3680             if(Usage & WINED3DUSAGE_QUERY_WRAPANDMIP) {
3681                 if (CheckWrapAndMipCapability(adapter, format_desc))
3682                 {
3683                     UsageCaps |= WINED3DUSAGE_QUERY_WRAPANDMIP;
3684                 } else {
3685                     TRACE_(d3d_caps)("[FAILED] - No wrapping and mipmapping support\n");
3686                     return WINED3DERR_NOTAVAILABLE;
3687                 }
3688             }
3689         } else {
3690             TRACE_(d3d_caps)("[FAILED] - No volume texture support\n");
3691             return WINED3DERR_NOTAVAILABLE;
3692         }
3693
3694         /* Filter formats that need conversion; For one part, this conversion is unimplemented,
3695          * and volume textures are huge, so it would be a big performance hit. Unless we hit an
3696          * app needing one of those formats, don't advertize them to avoid leading apps into
3697          * temptation. The windows drivers don't support most of those formats on volumes anyway,
3698          * except of R32F.
3699          */
3700         switch(CheckFormat) {
3701             case WINED3DFMT_P8_UINT:
3702             case WINED3DFMT_L4A4_UNORM:
3703             case WINED3DFMT_R32_FLOAT:
3704             case WINED3DFMT_R16_FLOAT:
3705             case WINED3DFMT_R8G8_SNORM_L8X8_UNORM:
3706             case WINED3DFMT_R5G5_SNORM_L6_UNORM:
3707             case WINED3DFMT_R16G16_UNORM:
3708                 TRACE_(d3d_caps)("[FAILED] - No converted formats on volumes\n");
3709                 return WINED3DERR_NOTAVAILABLE;
3710
3711             case WINED3DFMT_R8G8B8A8_SNORM:
3712             case WINED3DFMT_R16G16_SNORM:
3713             if (!gl_info->supported[NV_TEXTURE_SHADER])
3714             {
3715                 TRACE_(d3d_caps)("[FAILED] - No converted formats on volumes\n");
3716                 return WINED3DERR_NOTAVAILABLE;
3717             }
3718             break;
3719
3720             case WINED3DFMT_R8G8_SNORM:
3721             if (!gl_info->supported[NV_TEXTURE_SHADER])
3722             {
3723                 TRACE_(d3d_caps)("[FAILED] - No converted formats on volumes\n");
3724                 return WINED3DERR_NOTAVAILABLE;
3725             }
3726             break;
3727
3728             case WINED3DFMT_DXT1:
3729             case WINED3DFMT_DXT2:
3730             case WINED3DFMT_DXT3:
3731             case WINED3DFMT_DXT4:
3732             case WINED3DFMT_DXT5:
3733                 /* The GL_EXT_texture_compression_s3tc spec requires that loading an s3tc
3734                  * compressed texture results in an error. While the D3D refrast does
3735                  * support s3tc volumes, at least the nvidia windows driver does not, so
3736                  * we're free not to support this format.
3737                  */
3738                 TRACE_(d3d_caps)("[FAILED] - DXTn does not support 3D textures\n");
3739                 return WINED3DERR_NOTAVAILABLE;
3740
3741             default:
3742                 /* Do nothing, continue with checking the format below */
3743                 break;
3744         }
3745     } else if(RType == WINED3DRTYPE_BUFFER){
3746         /* For instance vertexbuffer/indexbuffer aren't supported yet because no Windows drivers seem to offer it */
3747         TRACE_(d3d_caps)("Unhandled resource type D3DRTYPE_INDEXBUFFER / D3DRTYPE_VERTEXBUFFER\n");
3748         return WINED3DERR_NOTAVAILABLE;
3749     }
3750
3751     /* When the UsageCaps exactly matches Usage return WINED3D_OK except for the situation in which
3752      * WINED3DUSAGE_AUTOGENMIPMAP isn't around, then WINED3DOK_NOAUTOGEN is returned if all the other
3753      * usage flags match. */
3754     if(UsageCaps == Usage) {
3755         return WINED3D_OK;
3756     } else if((UsageCaps == (Usage & ~WINED3DUSAGE_AUTOGENMIPMAP)) && (Usage & WINED3DUSAGE_AUTOGENMIPMAP)){
3757         return WINED3DOK_NOAUTOGEN;
3758     } else {
3759         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);
3760         return WINED3DERR_NOTAVAILABLE;
3761     }
3762 }
3763
3764 static HRESULT  WINAPI IWineD3DImpl_CheckDeviceFormatConversion(IWineD3D *iface, UINT Adapter, WINED3DDEVTYPE DeviceType,
3765                                                           WINED3DFORMAT SourceFormat, WINED3DFORMAT TargetFormat) {
3766     IWineD3DImpl *This = (IWineD3DImpl *)iface;
3767
3768     FIXME_(d3d_caps)("(%p)-> (STUB) (Adptr:%d, DevType:(%u,%s), SrcFmt:(%u,%s), TgtFmt:(%u,%s))\n",
3769           This,
3770           Adapter,
3771           DeviceType, debug_d3ddevicetype(DeviceType),
3772           SourceFormat, debug_d3dformat(SourceFormat),
3773           TargetFormat, debug_d3dformat(TargetFormat));
3774     return WINED3D_OK;
3775 }
3776
3777 /* Note: d3d8 passes in a pointer to a D3DCAPS8 structure, which is a true
3778       subset of a D3DCAPS9 structure. However, it has to come via a void *
3779       as the d3d8 interface cannot import the d3d9 header                  */
3780 static HRESULT WINAPI IWineD3DImpl_GetDeviceCaps(IWineD3D *iface, UINT Adapter, WINED3DDEVTYPE DeviceType, WINED3DCAPS* pCaps) {
3781
3782     IWineD3DImpl    *This = (IWineD3DImpl *)iface;
3783     struct wined3d_adapter *adapter = &This->adapters[Adapter];
3784     const struct wined3d_gl_info *gl_info = &adapter->gl_info;
3785     int vs_selected_mode;
3786     int ps_selected_mode;
3787     struct shader_caps shader_caps;
3788     struct fragment_caps fragment_caps;
3789     const shader_backend_t *shader_backend;
3790     const struct fragment_pipeline *frag_pipeline = NULL;
3791     DWORD ckey_caps, blit_caps, fx_caps;
3792
3793     TRACE_(d3d_caps)("(%p)->(Adptr:%d, DevType: %x, pCaps: %p)\n", This, Adapter, DeviceType, pCaps);
3794
3795     if (Adapter >= IWineD3D_GetAdapterCount(iface)) {
3796         return WINED3DERR_INVALIDCALL;
3797     }
3798
3799     select_shader_mode(&adapter->gl_info, &ps_selected_mode, &vs_selected_mode);
3800
3801     /* ------------------------------------------------
3802        The following fields apply to both d3d8 and d3d9
3803        ------------------------------------------------ */
3804     pCaps->DeviceType              = (DeviceType == WINED3DDEVTYPE_HAL) ? WINED3DDEVTYPE_HAL : WINED3DDEVTYPE_REF;  /* Not quite true, but use h/w supported by opengl I suppose */
3805     pCaps->AdapterOrdinal          = Adapter;
3806
3807     pCaps->Caps                    = 0;
3808     pCaps->Caps2                   = WINED3DCAPS2_CANRENDERWINDOWED |
3809                                      WINED3DCAPS2_FULLSCREENGAMMA |
3810                                      WINED3DCAPS2_DYNAMICTEXTURES;
3811     if (gl_info->supported[SGIS_GENERATE_MIPMAP])
3812     {
3813         pCaps->Caps2 |= WINED3DCAPS2_CANAUTOGENMIPMAP;
3814     }
3815
3816     pCaps->Caps3                   = WINED3DCAPS3_ALPHA_FULLSCREEN_FLIP_OR_DISCARD |
3817                                      WINED3DCAPS3_COPY_TO_VIDMEM                   |
3818                                      WINED3DCAPS3_COPY_TO_SYSTEMMEM;
3819
3820     pCaps->PresentationIntervals   = WINED3DPRESENT_INTERVAL_IMMEDIATE  |
3821                                      WINED3DPRESENT_INTERVAL_ONE;
3822
3823     pCaps->CursorCaps              = WINED3DCURSORCAPS_COLOR            |
3824                                      WINED3DCURSORCAPS_LOWRES;
3825
3826     pCaps->DevCaps                 = WINED3DDEVCAPS_FLOATTLVERTEX       |
3827                                      WINED3DDEVCAPS_EXECUTESYSTEMMEMORY |
3828                                      WINED3DDEVCAPS_TLVERTEXSYSTEMMEMORY|
3829                                      WINED3DDEVCAPS_TLVERTEXVIDEOMEMORY |
3830                                      WINED3DDEVCAPS_DRAWPRIMTLVERTEX    |
3831                                      WINED3DDEVCAPS_HWTRANSFORMANDLIGHT |
3832                                      WINED3DDEVCAPS_EXECUTEVIDEOMEMORY  |
3833                                      WINED3DDEVCAPS_PUREDEVICE          |
3834                                      WINED3DDEVCAPS_HWRASTERIZATION     |
3835                                      WINED3DDEVCAPS_TEXTUREVIDEOMEMORY  |
3836                                      WINED3DDEVCAPS_TEXTURESYSTEMMEMORY |
3837                                      WINED3DDEVCAPS_CANRENDERAFTERFLIP  |
3838                                      WINED3DDEVCAPS_DRAWPRIMITIVES2     |
3839                                      WINED3DDEVCAPS_DRAWPRIMITIVES2EX   |
3840                                      WINED3DDEVCAPS_RTPATCHES;
3841
3842     pCaps->PrimitiveMiscCaps       = WINED3DPMISCCAPS_CULLNONE              |
3843                                      WINED3DPMISCCAPS_CULLCCW               |
3844                                      WINED3DPMISCCAPS_CULLCW                |
3845                                      WINED3DPMISCCAPS_COLORWRITEENABLE      |
3846                                      WINED3DPMISCCAPS_CLIPTLVERTS           |
3847                                      WINED3DPMISCCAPS_CLIPPLANESCALEDPOINTS |
3848                                      WINED3DPMISCCAPS_MASKZ                 |
3849                                      WINED3DPMISCCAPS_BLENDOP               |
3850                                      WINED3DPMISCCAPS_MRTPOSTPIXELSHADERBLENDING;
3851                                     /* TODO:
3852                                         WINED3DPMISCCAPS_NULLREFERENCE
3853                                         WINED3DPMISCCAPS_INDEPENDENTWRITEMASKS
3854                                         WINED3DPMISCCAPS_FOGANDSPECULARALPHA
3855                                         WINED3DPMISCCAPS_MRTINDEPENDENTBITDEPTHS
3856                                         WINED3DPMISCCAPS_FOGVERTEXCLAMPED */
3857
3858     if (gl_info->supported[EXT_BLEND_EQUATION_SEPARATE] && gl_info->supported[EXT_BLEND_FUNC_SEPARATE])
3859         pCaps->PrimitiveMiscCaps |= WINED3DPMISCCAPS_SEPARATEALPHABLEND;
3860
3861     pCaps->RasterCaps              = WINED3DPRASTERCAPS_DITHER    |
3862                                      WINED3DPRASTERCAPS_PAT       |
3863                                      WINED3DPRASTERCAPS_WFOG      |
3864                                      WINED3DPRASTERCAPS_ZFOG      |
3865                                      WINED3DPRASTERCAPS_FOGVERTEX |
3866                                      WINED3DPRASTERCAPS_FOGTABLE  |
3867                                      WINED3DPRASTERCAPS_STIPPLE   |
3868                                      WINED3DPRASTERCAPS_SUBPIXEL  |
3869                                      WINED3DPRASTERCAPS_ZTEST     |
3870                                      WINED3DPRASTERCAPS_SCISSORTEST   |
3871                                      WINED3DPRASTERCAPS_SLOPESCALEDEPTHBIAS |
3872                                      WINED3DPRASTERCAPS_DEPTHBIAS;
3873
3874     if (gl_info->supported[EXT_TEXTURE_FILTER_ANISOTROPIC])
3875     {
3876         pCaps->RasterCaps |= WINED3DPRASTERCAPS_ANISOTROPY    |
3877                              WINED3DPRASTERCAPS_ZBIAS         |
3878                              WINED3DPRASTERCAPS_MIPMAPLODBIAS;
3879     }
3880     if (gl_info->supported[NV_FOG_DISTANCE])
3881     {
3882         pCaps->RasterCaps         |= WINED3DPRASTERCAPS_FOGRANGE;
3883     }
3884                         /* FIXME Add:
3885                            WINED3DPRASTERCAPS_COLORPERSPECTIVE
3886                            WINED3DPRASTERCAPS_STRETCHBLTMULTISAMPLE
3887                            WINED3DPRASTERCAPS_ANTIALIASEDGES
3888                            WINED3DPRASTERCAPS_ZBUFFERLESSHSR
3889                            WINED3DPRASTERCAPS_WBUFFER */
3890
3891     pCaps->ZCmpCaps = WINED3DPCMPCAPS_ALWAYS       |
3892                       WINED3DPCMPCAPS_EQUAL        |
3893                       WINED3DPCMPCAPS_GREATER      |
3894                       WINED3DPCMPCAPS_GREATEREQUAL |
3895                       WINED3DPCMPCAPS_LESS         |
3896                       WINED3DPCMPCAPS_LESSEQUAL    |
3897                       WINED3DPCMPCAPS_NEVER        |
3898                       WINED3DPCMPCAPS_NOTEQUAL;
3899
3900     pCaps->SrcBlendCaps  = WINED3DPBLENDCAPS_BOTHINVSRCALPHA |
3901                            WINED3DPBLENDCAPS_BOTHSRCALPHA    |
3902                            WINED3DPBLENDCAPS_DESTALPHA       |
3903                            WINED3DPBLENDCAPS_DESTCOLOR       |
3904                            WINED3DPBLENDCAPS_INVDESTALPHA    |
3905                            WINED3DPBLENDCAPS_INVDESTCOLOR    |
3906                            WINED3DPBLENDCAPS_INVSRCALPHA     |
3907                            WINED3DPBLENDCAPS_INVSRCCOLOR     |
3908                            WINED3DPBLENDCAPS_ONE             |
3909                            WINED3DPBLENDCAPS_SRCALPHA        |
3910                            WINED3DPBLENDCAPS_SRCALPHASAT     |
3911                            WINED3DPBLENDCAPS_SRCCOLOR        |
3912                            WINED3DPBLENDCAPS_ZERO;
3913
3914     pCaps->DestBlendCaps = WINED3DPBLENDCAPS_DESTALPHA       |
3915                            WINED3DPBLENDCAPS_DESTCOLOR       |
3916                            WINED3DPBLENDCAPS_INVDESTALPHA    |
3917                            WINED3DPBLENDCAPS_INVDESTCOLOR    |
3918                            WINED3DPBLENDCAPS_INVSRCALPHA     |
3919                            WINED3DPBLENDCAPS_INVSRCCOLOR     |
3920                            WINED3DPBLENDCAPS_ONE             |
3921                            WINED3DPBLENDCAPS_SRCALPHA        |
3922                            WINED3DPBLENDCAPS_SRCCOLOR        |
3923                            WINED3DPBLENDCAPS_ZERO;
3924     /* NOTE: WINED3DPBLENDCAPS_SRCALPHASAT is not supported as dest blend factor,
3925      * according to the glBlendFunc manpage
3926      *
3927      * WINED3DPBLENDCAPS_BOTHINVSRCALPHA and WINED3DPBLENDCAPS_BOTHSRCALPHA are
3928      * legacy settings for srcblend only
3929      */
3930
3931     if (gl_info->supported[EXT_BLEND_COLOR])
3932     {
3933         pCaps->SrcBlendCaps |= WINED3DPBLENDCAPS_BLENDFACTOR;
3934         pCaps->DestBlendCaps |= WINED3DPBLENDCAPS_BLENDFACTOR;
3935     }
3936
3937
3938     pCaps->AlphaCmpCaps = WINED3DPCMPCAPS_ALWAYS       |
3939                           WINED3DPCMPCAPS_EQUAL        |
3940                           WINED3DPCMPCAPS_GREATER      |
3941                           WINED3DPCMPCAPS_GREATEREQUAL |
3942                           WINED3DPCMPCAPS_LESS         |
3943                           WINED3DPCMPCAPS_LESSEQUAL    |
3944                           WINED3DPCMPCAPS_NEVER        |
3945                           WINED3DPCMPCAPS_NOTEQUAL;
3946
3947     pCaps->ShadeCaps     = WINED3DPSHADECAPS_SPECULARGOURAUDRGB |
3948                            WINED3DPSHADECAPS_COLORGOURAUDRGB    |
3949                            WINED3DPSHADECAPS_ALPHAFLATBLEND     |
3950                            WINED3DPSHADECAPS_ALPHAGOURAUDBLEND  |
3951                            WINED3DPSHADECAPS_COLORFLATRGB       |
3952                            WINED3DPSHADECAPS_FOGFLAT            |
3953                            WINED3DPSHADECAPS_FOGGOURAUD         |
3954                            WINED3DPSHADECAPS_SPECULARFLATRGB;
3955
3956     pCaps->TextureCaps =  WINED3DPTEXTURECAPS_ALPHA              |
3957                           WINED3DPTEXTURECAPS_ALPHAPALETTE       |
3958                           WINED3DPTEXTURECAPS_TRANSPARENCY       |
3959                           WINED3DPTEXTURECAPS_BORDER             |
3960                           WINED3DPTEXTURECAPS_MIPMAP             |
3961                           WINED3DPTEXTURECAPS_PROJECTED          |
3962                           WINED3DPTEXTURECAPS_PERSPECTIVE;
3963
3964     if (!gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO])
3965     {
3966         pCaps->TextureCaps |= WINED3DPTEXTURECAPS_POW2 |
3967                               WINED3DPTEXTURECAPS_NONPOW2CONDITIONAL;
3968     }
3969
3970     if (gl_info->supported[EXT_TEXTURE3D])
3971     {
3972         pCaps->TextureCaps |=  WINED3DPTEXTURECAPS_VOLUMEMAP      |
3973                                WINED3DPTEXTURECAPS_MIPVOLUMEMAP   |
3974                                WINED3DPTEXTURECAPS_VOLUMEMAP_POW2;
3975     }
3976
3977     if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
3978     {
3979         pCaps->TextureCaps |= WINED3DPTEXTURECAPS_CUBEMAP     |
3980                               WINED3DPTEXTURECAPS_MIPCUBEMAP    |
3981                               WINED3DPTEXTURECAPS_CUBEMAP_POW2;
3982
3983     }
3984
3985     pCaps->TextureFilterCaps = WINED3DPTFILTERCAPS_MAGFLINEAR       |
3986                                WINED3DPTFILTERCAPS_MAGFPOINT        |
3987                                WINED3DPTFILTERCAPS_MINFLINEAR       |
3988                                WINED3DPTFILTERCAPS_MINFPOINT        |
3989                                WINED3DPTFILTERCAPS_MIPFLINEAR       |
3990                                WINED3DPTFILTERCAPS_MIPFPOINT        |
3991                                WINED3DPTFILTERCAPS_LINEAR           |
3992                                WINED3DPTFILTERCAPS_LINEARMIPLINEAR  |
3993                                WINED3DPTFILTERCAPS_LINEARMIPNEAREST |
3994                                WINED3DPTFILTERCAPS_MIPLINEAR        |
3995                                WINED3DPTFILTERCAPS_MIPNEAREST       |
3996                                WINED3DPTFILTERCAPS_NEAREST;
3997
3998     if (gl_info->supported[EXT_TEXTURE_FILTER_ANISOTROPIC])
3999     {
4000         pCaps->TextureFilterCaps |= WINED3DPTFILTERCAPS_MAGFANISOTROPIC |
4001                                     WINED3DPTFILTERCAPS_MINFANISOTROPIC;
4002     }
4003
4004     if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
4005     {
4006         pCaps->CubeTextureFilterCaps = WINED3DPTFILTERCAPS_MAGFLINEAR       |
4007                                        WINED3DPTFILTERCAPS_MAGFPOINT        |
4008                                        WINED3DPTFILTERCAPS_MINFLINEAR       |
4009                                        WINED3DPTFILTERCAPS_MINFPOINT        |
4010                                        WINED3DPTFILTERCAPS_MIPFLINEAR       |
4011                                        WINED3DPTFILTERCAPS_MIPFPOINT        |
4012                                        WINED3DPTFILTERCAPS_LINEAR           |
4013                                        WINED3DPTFILTERCAPS_LINEARMIPLINEAR  |
4014                                        WINED3DPTFILTERCAPS_LINEARMIPNEAREST |
4015                                        WINED3DPTFILTERCAPS_MIPLINEAR        |
4016                                        WINED3DPTFILTERCAPS_MIPNEAREST       |
4017                                        WINED3DPTFILTERCAPS_NEAREST;
4018
4019         if (gl_info->supported[EXT_TEXTURE_FILTER_ANISOTROPIC])
4020         {
4021             pCaps->CubeTextureFilterCaps |= WINED3DPTFILTERCAPS_MAGFANISOTROPIC |
4022                                             WINED3DPTFILTERCAPS_MINFANISOTROPIC;
4023         }
4024     } else
4025         pCaps->CubeTextureFilterCaps = 0;
4026
4027     if (gl_info->supported[EXT_TEXTURE3D])
4028     {
4029         pCaps->VolumeTextureFilterCaps = WINED3DPTFILTERCAPS_MAGFLINEAR       |
4030                                          WINED3DPTFILTERCAPS_MAGFPOINT        |
4031                                          WINED3DPTFILTERCAPS_MINFLINEAR       |
4032                                          WINED3DPTFILTERCAPS_MINFPOINT        |
4033                                          WINED3DPTFILTERCAPS_MIPFLINEAR       |
4034                                          WINED3DPTFILTERCAPS_MIPFPOINT        |
4035                                          WINED3DPTFILTERCAPS_LINEAR           |
4036                                          WINED3DPTFILTERCAPS_LINEARMIPLINEAR  |
4037                                          WINED3DPTFILTERCAPS_LINEARMIPNEAREST |
4038                                          WINED3DPTFILTERCAPS_MIPLINEAR        |
4039                                          WINED3DPTFILTERCAPS_MIPNEAREST       |
4040                                          WINED3DPTFILTERCAPS_NEAREST;
4041     } else
4042         pCaps->VolumeTextureFilterCaps = 0;
4043
4044     pCaps->TextureAddressCaps =  WINED3DPTADDRESSCAPS_INDEPENDENTUV |
4045                                  WINED3DPTADDRESSCAPS_CLAMP  |
4046                                  WINED3DPTADDRESSCAPS_WRAP;
4047
4048     if (gl_info->supported[ARB_TEXTURE_BORDER_CLAMP])
4049     {
4050         pCaps->TextureAddressCaps |= WINED3DPTADDRESSCAPS_BORDER;
4051     }
4052     if (gl_info->supported[ARB_TEXTURE_MIRRORED_REPEAT])
4053     {
4054         pCaps->TextureAddressCaps |= WINED3DPTADDRESSCAPS_MIRROR;
4055     }
4056     if (gl_info->supported[ATI_TEXTURE_MIRROR_ONCE])
4057     {
4058         pCaps->TextureAddressCaps |= WINED3DPTADDRESSCAPS_MIRRORONCE;
4059     }
4060
4061     if (gl_info->supported[EXT_TEXTURE3D])
4062     {
4063         pCaps->VolumeTextureAddressCaps =  WINED3DPTADDRESSCAPS_INDEPENDENTUV |
4064                                            WINED3DPTADDRESSCAPS_CLAMP  |
4065                                            WINED3DPTADDRESSCAPS_WRAP;
4066         if (gl_info->supported[ARB_TEXTURE_BORDER_CLAMP])
4067         {
4068             pCaps->VolumeTextureAddressCaps |= WINED3DPTADDRESSCAPS_BORDER;
4069         }
4070         if (gl_info->supported[ARB_TEXTURE_MIRRORED_REPEAT])
4071         {
4072             pCaps->VolumeTextureAddressCaps |= WINED3DPTADDRESSCAPS_MIRROR;
4073         }
4074         if (gl_info->supported[ATI_TEXTURE_MIRROR_ONCE])
4075         {
4076             pCaps->VolumeTextureAddressCaps |= WINED3DPTADDRESSCAPS_MIRRORONCE;
4077         }
4078     } else
4079         pCaps->VolumeTextureAddressCaps = 0;
4080
4081     pCaps->LineCaps = WINED3DLINECAPS_TEXTURE       |
4082                       WINED3DLINECAPS_ZTEST         |
4083                       WINED3DLINECAPS_BLEND         |
4084                       WINED3DLINECAPS_ALPHACMP      |
4085                       WINED3DLINECAPS_FOG;
4086     /* WINED3DLINECAPS_ANTIALIAS is not supported on Windows, and dx and gl seem to have a different
4087      * idea how generating the smoothing alpha values works; the result is different
4088      */
4089
4090     pCaps->MaxTextureWidth = gl_info->limits.texture_size;
4091     pCaps->MaxTextureHeight = gl_info->limits.texture_size;
4092
4093     if (gl_info->supported[EXT_TEXTURE3D])
4094         pCaps->MaxVolumeExtent = gl_info->limits.texture3d_size;
4095     else
4096         pCaps->MaxVolumeExtent = 0;
4097
4098     pCaps->MaxTextureRepeat = 32768;
4099     pCaps->MaxTextureAspectRatio = gl_info->limits.texture_size;
4100     pCaps->MaxVertexW = 1.0f;
4101
4102     pCaps->GuardBandLeft = 0.0f;
4103     pCaps->GuardBandTop = 0.0f;
4104     pCaps->GuardBandRight = 0.0f;
4105     pCaps->GuardBandBottom = 0.0f;
4106
4107     pCaps->ExtentsAdjust = 0.0f;
4108
4109     pCaps->StencilCaps =  WINED3DSTENCILCAPS_DECRSAT |
4110                           WINED3DSTENCILCAPS_INCRSAT |
4111                           WINED3DSTENCILCAPS_INVERT  |
4112                           WINED3DSTENCILCAPS_KEEP    |
4113                           WINED3DSTENCILCAPS_REPLACE |
4114                           WINED3DSTENCILCAPS_ZERO;
4115     if (gl_info->supported[EXT_STENCIL_WRAP])
4116     {
4117         pCaps->StencilCaps |= WINED3DSTENCILCAPS_DECR  |
4118                               WINED3DSTENCILCAPS_INCR;
4119     }
4120     if (gl_info->supported[EXT_STENCIL_TWO_SIDE] || gl_info->supported[ATI_SEPARATE_STENCIL])
4121     {
4122         pCaps->StencilCaps |= WINED3DSTENCILCAPS_TWOSIDED;
4123     }
4124
4125     pCaps->FVFCaps = WINED3DFVFCAPS_PSIZE | 0x0008; /* 8 texture coords */
4126
4127     pCaps->MaxUserClipPlanes = gl_info->limits.clipplanes;
4128     pCaps->MaxActiveLights = gl_info->limits.lights;
4129
4130     pCaps->MaxVertexBlendMatrices = gl_info->limits.blends;
4131     pCaps->MaxVertexBlendMatrixIndex   = 0;
4132
4133     pCaps->MaxAnisotropy = gl_info->limits.anisotropy;
4134     pCaps->MaxPointSize = gl_info->limits.pointsize_max;
4135
4136
4137     /* FIXME: Add D3DVTXPCAPS_TWEENING, D3DVTXPCAPS_TEXGEN_SPHEREMAP */
4138     pCaps->VertexProcessingCaps = WINED3DVTXPCAPS_DIRECTIONALLIGHTS |
4139                                   WINED3DVTXPCAPS_MATERIALSOURCE7   |
4140                                   WINED3DVTXPCAPS_POSITIONALLIGHTS  |
4141                                   WINED3DVTXPCAPS_LOCALVIEWER       |
4142                                   WINED3DVTXPCAPS_VERTEXFOG         |
4143                                   WINED3DVTXPCAPS_TEXGEN;
4144
4145     pCaps->MaxPrimitiveCount   = 0xFFFFF; /* For now set 2^20-1 which is used by most >=Geforce3/Radeon8500 cards */
4146     pCaps->MaxVertexIndex      = 0xFFFFF;
4147     pCaps->MaxStreams          = MAX_STREAMS;
4148     pCaps->MaxStreamStride     = 1024;
4149
4150     /* d3d9.dll sets D3DDEVCAPS2_CAN_STRETCHRECT_FROM_TEXTURES here because StretchRects is implemented in d3d9 */
4151     pCaps->DevCaps2                          = WINED3DDEVCAPS2_STREAMOFFSET |
4152                                                WINED3DDEVCAPS2_VERTEXELEMENTSCANSHARESTREAMOFFSET;
4153     pCaps->MaxNpatchTessellationLevel        = 0;
4154     pCaps->MasterAdapterOrdinal              = 0;
4155     pCaps->AdapterOrdinalInGroup             = 0;
4156     pCaps->NumberOfAdaptersInGroup           = 1;
4157
4158     pCaps->NumSimultaneousRTs = gl_info->limits.buffers;
4159
4160     pCaps->StretchRectFilterCaps             = WINED3DPTFILTERCAPS_MINFPOINT  |
4161                                                 WINED3DPTFILTERCAPS_MAGFPOINT  |
4162                                                 WINED3DPTFILTERCAPS_MINFLINEAR |
4163                                                 WINED3DPTFILTERCAPS_MAGFLINEAR;
4164     pCaps->VertexTextureFilterCaps           = 0;
4165
4166     memset(&shader_caps, 0, sizeof(shader_caps));
4167     shader_backend = select_shader_backend(adapter, DeviceType);
4168     shader_backend->shader_get_caps(DeviceType, &adapter->gl_info, &shader_caps);
4169
4170     memset(&fragment_caps, 0, sizeof(fragment_caps));
4171     frag_pipeline = select_fragment_implementation(adapter, DeviceType);
4172     frag_pipeline->get_caps(DeviceType, &adapter->gl_info, &fragment_caps);
4173
4174     /* Add shader misc caps. Only some of them belong to the shader parts of the pipeline */
4175     pCaps->PrimitiveMiscCaps |= fragment_caps.PrimitiveMiscCaps;
4176
4177     /* This takes care for disabling vertex shader or pixel shader caps while leaving the other one enabled.
4178      * Ignore shader model capabilities if disabled in config
4179      */
4180     if(vs_selected_mode == SHADER_NONE) {
4181         TRACE_(d3d_caps)("Vertex shader disabled in config, reporting version 0.0\n");
4182         pCaps->VertexShaderVersion          = WINED3DVS_VERSION(0,0);
4183         pCaps->MaxVertexShaderConst         = 0;
4184     } else {
4185         pCaps->VertexShaderVersion          = shader_caps.VertexShaderVersion;
4186         pCaps->MaxVertexShaderConst         = shader_caps.MaxVertexShaderConst;
4187     }
4188
4189     if(ps_selected_mode == SHADER_NONE) {
4190         TRACE_(d3d_caps)("Pixel shader disabled in config, reporting version 0.0\n");
4191         pCaps->PixelShaderVersion           = WINED3DPS_VERSION(0,0);
4192         pCaps->PixelShader1xMaxValue        = 0.0f;
4193     } else {
4194         pCaps->PixelShaderVersion           = shader_caps.PixelShaderVersion;
4195         pCaps->PixelShader1xMaxValue        = shader_caps.PixelShader1xMaxValue;
4196     }
4197
4198     pCaps->TextureOpCaps                    = fragment_caps.TextureOpCaps;
4199     pCaps->MaxTextureBlendStages            = fragment_caps.MaxTextureBlendStages;
4200     pCaps->MaxSimultaneousTextures          = fragment_caps.MaxSimultaneousTextures;
4201
4202     pCaps->VS20Caps                         = shader_caps.VS20Caps;
4203     pCaps->MaxVShaderInstructionsExecuted   = shader_caps.MaxVShaderInstructionsExecuted;
4204     pCaps->MaxVertexShader30InstructionSlots= shader_caps.MaxVertexShader30InstructionSlots;
4205     pCaps->PS20Caps                         = shader_caps.PS20Caps;
4206     pCaps->MaxPShaderInstructionsExecuted   = shader_caps.MaxPShaderInstructionsExecuted;
4207     pCaps->MaxPixelShader30InstructionSlots = shader_caps.MaxPixelShader30InstructionSlots;
4208
4209     /* The following caps are shader specific, but they are things we cannot detect, or which
4210      * are the same among all shader models. So to avoid code duplication set the shader version
4211      * specific, but otherwise constant caps here
4212      */
4213     if(pCaps->VertexShaderVersion == WINED3DVS_VERSION(3,0)) {
4214         /* Where possible set the caps based on OpenGL extensions and if they aren't set (in case of software rendering)
4215         use the VS 3.0 from MSDN or else if there's OpenGL spec use a hardcoded value minimum VS3.0 value. */
4216         pCaps->VS20Caps.Caps                     = WINED3DVS20CAPS_PREDICATION;
4217         pCaps->VS20Caps.DynamicFlowControlDepth  = WINED3DVS20_MAX_DYNAMICFLOWCONTROLDEPTH; /* VS 3.0 requires MAX_DYNAMICFLOWCONTROLDEPTH (24) */
4218         pCaps->VS20Caps.NumTemps = max(32, adapter->gl_info.limits.arb_vs_temps);
4219         pCaps->VS20Caps.StaticFlowControlDepth   = WINED3DVS20_MAX_STATICFLOWCONTROLDEPTH ; /* level of nesting in loops / if-statements; VS 3.0 requires MAX (4) */
4220
4221         pCaps->MaxVShaderInstructionsExecuted    = 65535; /* VS 3.0 needs at least 65535, some cards even use 2^32-1 */
4222         pCaps->MaxVertexShader30InstructionSlots = max(512, adapter->gl_info.limits.arb_vs_instructions);
4223     }
4224     else if (pCaps->VertexShaderVersion == WINED3DVS_VERSION(2,0))
4225     {
4226         pCaps->VS20Caps.Caps                     = 0;
4227         pCaps->VS20Caps.DynamicFlowControlDepth  = WINED3DVS20_MIN_DYNAMICFLOWCONTROLDEPTH;
4228         pCaps->VS20Caps.NumTemps = max(12, adapter->gl_info.limits.arb_vs_temps);
4229         pCaps->VS20Caps.StaticFlowControlDepth   = 1;
4230
4231         pCaps->MaxVShaderInstructionsExecuted    = 65535;
4232         pCaps->MaxVertexShader30InstructionSlots = 0;
4233     } else { /* VS 1.x */
4234         pCaps->VS20Caps.Caps                     = 0;
4235         pCaps->VS20Caps.DynamicFlowControlDepth  = 0;
4236         pCaps->VS20Caps.NumTemps                 = 0;
4237         pCaps->VS20Caps.StaticFlowControlDepth   = 0;
4238
4239         pCaps->MaxVShaderInstructionsExecuted    = 0;
4240         pCaps->MaxVertexShader30InstructionSlots = 0;
4241     }
4242
4243     if(pCaps->PixelShaderVersion == WINED3DPS_VERSION(3,0)) {
4244         /* Where possible set the caps based on OpenGL extensions and if they aren't set (in case of software rendering)
4245         use the PS 3.0 from MSDN or else if there's OpenGL spec use a hardcoded value minimum PS 3.0 value. */
4246
4247         /* 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 */
4248         pCaps->PS20Caps.Caps                     = WINED3DPS20CAPS_ARBITRARYSWIZZLE     |
4249                 WINED3DPS20CAPS_GRADIENTINSTRUCTIONS |
4250                 WINED3DPS20CAPS_PREDICATION          |
4251                 WINED3DPS20CAPS_NODEPENDENTREADLIMIT |
4252                 WINED3DPS20CAPS_NOTEXINSTRUCTIONLIMIT;
4253         pCaps->PS20Caps.DynamicFlowControlDepth  = WINED3DPS20_MAX_DYNAMICFLOWCONTROLDEPTH; /* PS 3.0 requires MAX_DYNAMICFLOWCONTROLDEPTH (24) */
4254         pCaps->PS20Caps.NumTemps = max(32, adapter->gl_info.limits.arb_ps_temps);
4255         pCaps->PS20Caps.StaticFlowControlDepth   = WINED3DPS20_MAX_STATICFLOWCONTROLDEPTH; /* PS 3.0 requires MAX_STATICFLOWCONTROLDEPTH (4) */
4256         pCaps->PS20Caps.NumInstructionSlots      = WINED3DPS20_MAX_NUMINSTRUCTIONSLOTS; /* PS 3.0 requires MAX_NUMINSTRUCTIONSLOTS (512) */
4257
4258         pCaps->MaxPShaderInstructionsExecuted    = 65535;
4259         pCaps->MaxPixelShader30InstructionSlots = max(WINED3DMIN30SHADERINSTRUCTIONS,
4260                 adapter->gl_info.limits.arb_ps_instructions);
4261     }
4262     else if(pCaps->PixelShaderVersion == WINED3DPS_VERSION(2,0))
4263     {
4264         /* Below we assume PS2.0 specs, not extended 2.0a(GeforceFX)/2.0b(Radeon R3xx) ones */
4265         pCaps->PS20Caps.Caps                     = 0;
4266         pCaps->PS20Caps.DynamicFlowControlDepth  = 0; /* WINED3DVS20_MIN_DYNAMICFLOWCONTROLDEPTH = 0 */
4267         pCaps->PS20Caps.NumTemps = max(12, adapter->gl_info.limits.arb_ps_temps);
4268         pCaps->PS20Caps.StaticFlowControlDepth   = WINED3DPS20_MIN_STATICFLOWCONTROLDEPTH; /* Minimum: 1 */
4269         pCaps->PS20Caps.NumInstructionSlots      = WINED3DPS20_MIN_NUMINSTRUCTIONSLOTS; /* Minimum number (64 ALU + 32 Texture), a GeforceFX uses 512 */
4270
4271         pCaps->MaxPShaderInstructionsExecuted    = 512; /* Minimum value, a GeforceFX uses 1024 */
4272         pCaps->MaxPixelShader30InstructionSlots  = 0;
4273     } else { /* PS 1.x */
4274         pCaps->PS20Caps.Caps                     = 0;
4275         pCaps->PS20Caps.DynamicFlowControlDepth  = 0;
4276         pCaps->PS20Caps.NumTemps                 = 0;
4277         pCaps->PS20Caps.StaticFlowControlDepth   = 0;
4278         pCaps->PS20Caps.NumInstructionSlots      = 0;
4279
4280         pCaps->MaxPShaderInstructionsExecuted    = 0;
4281         pCaps->MaxPixelShader30InstructionSlots  = 0;
4282     }
4283
4284     if(pCaps->VertexShaderVersion >= WINED3DVS_VERSION(2,0)) {
4285         /* OpenGL supports all the formats below, perhaps not always
4286          * without conversion, but it supports them.
4287          * Further GLSL doesn't seem to have an official unsigned type so
4288          * don't advertise it yet as I'm not sure how we handle it.
4289          * We might need to add some clamping in the shader engine to
4290          * support it.
4291          * TODO: WINED3DDTCAPS_USHORT2N, WINED3DDTCAPS_USHORT4N, WINED3DDTCAPS_UDEC3, WINED3DDTCAPS_DEC3N */
4292         pCaps->DeclTypes = WINED3DDTCAPS_UBYTE4    |
4293                            WINED3DDTCAPS_UBYTE4N   |
4294                            WINED3DDTCAPS_SHORT2N   |
4295                            WINED3DDTCAPS_SHORT4N;
4296         if (gl_info->supported[ARB_HALF_FLOAT_VERTEX])
4297         {
4298             pCaps->DeclTypes |= WINED3DDTCAPS_FLOAT16_2 |
4299                                 WINED3DDTCAPS_FLOAT16_4;
4300         }
4301     } else
4302         pCaps->DeclTypes                         = 0;
4303
4304     /* Set DirectDraw helper Caps */
4305     ckey_caps =                         WINEDDCKEYCAPS_DESTBLT              |
4306                                         WINEDDCKEYCAPS_SRCBLT;
4307     fx_caps =                           WINEDDFXCAPS_BLTALPHA               |
4308                                         WINEDDFXCAPS_BLTMIRRORLEFTRIGHT     |
4309                                         WINEDDFXCAPS_BLTMIRRORUPDOWN        |
4310                                         WINEDDFXCAPS_BLTROTATION90          |
4311                                         WINEDDFXCAPS_BLTSHRINKX             |
4312                                         WINEDDFXCAPS_BLTSHRINKXN            |
4313                                         WINEDDFXCAPS_BLTSHRINKY             |
4314                                         WINEDDFXCAPS_BLTSHRINKXN            |
4315                                         WINEDDFXCAPS_BLTSTRETCHX            |
4316                                         WINEDDFXCAPS_BLTSTRETCHXN           |
4317                                         WINEDDFXCAPS_BLTSTRETCHY            |
4318                                         WINEDDFXCAPS_BLTSTRETCHYN;
4319     blit_caps =                         WINEDDCAPS_BLT                      |
4320                                         WINEDDCAPS_BLTCOLORFILL             |
4321                                         WINEDDCAPS_BLTDEPTHFILL             |
4322                                         WINEDDCAPS_BLTSTRETCH               |
4323                                         WINEDDCAPS_CANBLTSYSMEM             |
4324                                         WINEDDCAPS_CANCLIP                  |
4325                                         WINEDDCAPS_CANCLIPSTRETCHED         |
4326                                         WINEDDCAPS_COLORKEY                 |
4327                                         WINEDDCAPS_COLORKEYHWASSIST         |
4328                                         WINEDDCAPS_ALIGNBOUNDARYSRC;
4329
4330     /* Fill the ddraw caps structure */
4331     pCaps->DirectDrawCaps.Caps =        WINEDDCAPS_GDI                      |
4332                                         WINEDDCAPS_PALETTE                  |
4333                                         blit_caps;
4334     pCaps->DirectDrawCaps.Caps2 =       WINEDDCAPS2_CERTIFIED                |
4335                                         WINEDDCAPS2_NOPAGELOCKREQUIRED       |
4336                                         WINEDDCAPS2_PRIMARYGAMMA             |
4337                                         WINEDDCAPS2_WIDESURFACES             |
4338                                         WINEDDCAPS2_CANRENDERWINDOWED;
4339     pCaps->DirectDrawCaps.SVBCaps =     blit_caps;
4340     pCaps->DirectDrawCaps.SVBCKeyCaps = ckey_caps;
4341     pCaps->DirectDrawCaps.SVBFXCaps =   fx_caps;
4342     pCaps->DirectDrawCaps.VSBCaps =     blit_caps;
4343     pCaps->DirectDrawCaps.VSBCKeyCaps = ckey_caps;
4344     pCaps->DirectDrawCaps.VSBFXCaps =   fx_caps;
4345     pCaps->DirectDrawCaps.SSBCaps =     blit_caps;
4346     pCaps->DirectDrawCaps.SSBCKeyCaps = ckey_caps;
4347     pCaps->DirectDrawCaps.SSBFXCaps =   fx_caps;
4348
4349     pCaps->DirectDrawCaps.ddsCaps =     WINEDDSCAPS_ALPHA                   |
4350                                         WINEDDSCAPS_BACKBUFFER              |
4351                                         WINEDDSCAPS_FLIP                    |
4352                                         WINEDDSCAPS_FRONTBUFFER             |
4353                                         WINEDDSCAPS_OFFSCREENPLAIN          |
4354                                         WINEDDSCAPS_PALETTE                 |
4355                                         WINEDDSCAPS_PRIMARYSURFACE          |
4356                                         WINEDDSCAPS_SYSTEMMEMORY            |
4357                                         WINEDDSCAPS_VIDEOMEMORY             |
4358                                         WINEDDSCAPS_VISIBLE;
4359     pCaps->DirectDrawCaps.StrideAlign = DDRAW_PITCH_ALIGNMENT;
4360
4361     /* Set D3D caps if OpenGL is available. */
4362     if (adapter->opengl)
4363     {
4364         pCaps->DirectDrawCaps.ddsCaps |=WINEDDSCAPS_3DDEVICE                |
4365                                         WINEDDSCAPS_MIPMAP                  |
4366                                         WINEDDSCAPS_TEXTURE                 |
4367                                         WINEDDSCAPS_ZBUFFER;
4368         pCaps->DirectDrawCaps.Caps |=   WINEDDCAPS_3D;
4369     }
4370
4371     return WINED3D_OK;
4372 }
4373
4374 static HRESULT WINAPI IWineD3DImpl_CreateDevice(IWineD3D *iface, UINT adapter_idx,
4375         WINED3DDEVTYPE device_type, HWND focus_window, DWORD flags, IUnknown *parent,
4376         IWineD3DDeviceParent *device_parent, IWineD3DDevice **device)
4377 {
4378     IWineD3DImpl *This = (IWineD3DImpl *)iface;
4379     IWineD3DDeviceImpl *object;
4380     HRESULT hr;
4381
4382     TRACE("iface %p, adapter_idx %u, device_type %#x, focus_window %p, flags %#x.\n"
4383             "parent %p, device_parent %p, device %p.\n",
4384             iface, adapter_idx, device_type, focus_window, flags,
4385             parent, device_parent, device);
4386
4387     /* Validate the adapter number. If no adapters are available(no GL), ignore the adapter
4388      * number and create a device without a 3D adapter for 2D only operation. */
4389     if (IWineD3D_GetAdapterCount(iface) && adapter_idx >= IWineD3D_GetAdapterCount(iface))
4390     {
4391         return WINED3DERR_INVALIDCALL;
4392     }
4393
4394     object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
4395     if (!object)
4396     {
4397         ERR("Failed to allocate device memory.\n");
4398         return E_OUTOFMEMORY;
4399     }
4400
4401     hr = device_init(object, This, adapter_idx, device_type, focus_window, flags, parent, device_parent);
4402     if (FAILED(hr))
4403     {
4404         WARN("Failed to initialize device, hr %#x.\n", hr);
4405         HeapFree(GetProcessHeap(), 0, object);
4406         return hr;
4407     }
4408
4409     TRACE("Created device %p.\n", object);
4410     *device = (IWineD3DDevice *)object;
4411
4412     IWineD3DDeviceParent_WineD3DDeviceCreated(device_parent, *device);
4413
4414     return WINED3D_OK;
4415 }
4416
4417 static HRESULT WINAPI IWineD3DImpl_GetParent(IWineD3D *iface, IUnknown **pParent) {
4418     IWineD3DImpl *This = (IWineD3DImpl *)iface;
4419     IUnknown_AddRef(This->parent);
4420     *pParent = This->parent;
4421     return WINED3D_OK;
4422 }
4423
4424 static void WINE_GLAPI invalid_func(const void *data)
4425 {
4426     ERR("Invalid vertex attribute function called\n");
4427     DebugBreak();
4428 }
4429
4430 static void WINE_GLAPI invalid_texcoord_func(GLenum unit, const void *data)
4431 {
4432     ERR("Invalid texcoord function called\n");
4433     DebugBreak();
4434 }
4435
4436 /* Helper functions for providing vertex data to opengl. The arrays are initialized based on
4437  * the extension detection and are used in drawStridedSlow
4438  */
4439 static void WINE_GLAPI position_d3dcolor(const void *data)
4440 {
4441     DWORD pos = *((const DWORD *)data);
4442
4443     FIXME("Add a test for fixed function position from d3dcolor type\n");
4444     glVertex4s(D3DCOLOR_B_R(pos),
4445                D3DCOLOR_B_G(pos),
4446                D3DCOLOR_B_B(pos),
4447                D3DCOLOR_B_A(pos));
4448 }
4449
4450 static void WINE_GLAPI position_float4(const void *data)
4451 {
4452     const GLfloat *pos = data;
4453
4454     if (pos[3] != 0.0f && pos[3] != 1.0f)
4455     {
4456         float w = 1.0f / pos[3];
4457
4458         glVertex4f(pos[0] * w, pos[1] * w, pos[2] * w, w);
4459     }
4460     else
4461     {
4462         glVertex3fv(pos);
4463     }
4464 }
4465
4466 static void WINE_GLAPI diffuse_d3dcolor(const void *data)
4467 {
4468     DWORD diffuseColor = *((const DWORD *)data);
4469
4470     glColor4ub(D3DCOLOR_B_R(diffuseColor),
4471                D3DCOLOR_B_G(diffuseColor),
4472                D3DCOLOR_B_B(diffuseColor),
4473                D3DCOLOR_B_A(diffuseColor));
4474 }
4475
4476 static void WINE_GLAPI specular_d3dcolor(const void *data)
4477 {
4478     DWORD specularColor = *((const DWORD *)data);
4479     GLbyte d[] = {D3DCOLOR_B_R(specularColor),
4480             D3DCOLOR_B_G(specularColor),
4481             D3DCOLOR_B_B(specularColor)};
4482
4483     specular_func_3ubv(d);
4484 }
4485
4486 static void WINE_GLAPI warn_no_specular_func(const void *data)
4487 {
4488     WARN("GL_EXT_secondary_color not supported\n");
4489 }
4490
4491 static void fillGLAttribFuncs(const struct wined3d_gl_info *gl_info)
4492 {
4493     position_funcs[WINED3D_FFP_EMIT_FLOAT1]      = invalid_func;
4494     position_funcs[WINED3D_FFP_EMIT_FLOAT2]      = invalid_func;
4495     position_funcs[WINED3D_FFP_EMIT_FLOAT3]      = (glAttribFunc)glVertex3fv;
4496     position_funcs[WINED3D_FFP_EMIT_FLOAT4]      = position_float4;
4497     position_funcs[WINED3D_FFP_EMIT_D3DCOLOR]    = position_d3dcolor;
4498     position_funcs[WINED3D_FFP_EMIT_UBYTE4]      = invalid_func;
4499     position_funcs[WINED3D_FFP_EMIT_SHORT2]      = invalid_func;
4500     position_funcs[WINED3D_FFP_EMIT_SHORT4]      = (glAttribFunc)glVertex2sv;
4501     position_funcs[WINED3D_FFP_EMIT_UBYTE4N]     = invalid_func;
4502     position_funcs[WINED3D_FFP_EMIT_SHORT2N]     = invalid_func;
4503     position_funcs[WINED3D_FFP_EMIT_SHORT4N]     = invalid_func;
4504     position_funcs[WINED3D_FFP_EMIT_USHORT2N]    = invalid_func;
4505     position_funcs[WINED3D_FFP_EMIT_USHORT4N]    = invalid_func;
4506     position_funcs[WINED3D_FFP_EMIT_UDEC3]       = invalid_func;
4507     position_funcs[WINED3D_FFP_EMIT_DEC3N]       = invalid_func;
4508     position_funcs[WINED3D_FFP_EMIT_FLOAT16_2]   = invalid_func;
4509     position_funcs[WINED3D_FFP_EMIT_FLOAT16_4]   = invalid_func;
4510
4511     diffuse_funcs[WINED3D_FFP_EMIT_FLOAT1]       = invalid_func;
4512     diffuse_funcs[WINED3D_FFP_EMIT_FLOAT2]       = invalid_func;
4513     diffuse_funcs[WINED3D_FFP_EMIT_FLOAT3]       = (glAttribFunc)glColor3fv;
4514     diffuse_funcs[WINED3D_FFP_EMIT_FLOAT4]       = (glAttribFunc)glColor4fv;
4515     diffuse_funcs[WINED3D_FFP_EMIT_D3DCOLOR]     = diffuse_d3dcolor;
4516     diffuse_funcs[WINED3D_FFP_EMIT_UBYTE4]       = invalid_func;
4517     diffuse_funcs[WINED3D_FFP_EMIT_SHORT2]       = invalid_func;
4518     diffuse_funcs[WINED3D_FFP_EMIT_SHORT4]       = invalid_func;
4519     diffuse_funcs[WINED3D_FFP_EMIT_UBYTE4N]      = (glAttribFunc)glColor4ubv;
4520     diffuse_funcs[WINED3D_FFP_EMIT_SHORT2N]      = invalid_func;
4521     diffuse_funcs[WINED3D_FFP_EMIT_SHORT4N]      = (glAttribFunc)glColor4sv;
4522     diffuse_funcs[WINED3D_FFP_EMIT_USHORT2N]     = invalid_func;
4523     diffuse_funcs[WINED3D_FFP_EMIT_USHORT4N]     = (glAttribFunc)glColor4usv;
4524     diffuse_funcs[WINED3D_FFP_EMIT_UDEC3]        = invalid_func;
4525     diffuse_funcs[WINED3D_FFP_EMIT_DEC3N]        = invalid_func;
4526     diffuse_funcs[WINED3D_FFP_EMIT_FLOAT16_2]    = invalid_func;
4527     diffuse_funcs[WINED3D_FFP_EMIT_FLOAT16_4]    = invalid_func;
4528
4529     /* No 4 component entry points here */
4530     specular_funcs[WINED3D_FFP_EMIT_FLOAT1]      = invalid_func;
4531     specular_funcs[WINED3D_FFP_EMIT_FLOAT2]      = invalid_func;
4532     if (gl_info->supported[EXT_SECONDARY_COLOR])
4533     {
4534         specular_funcs[WINED3D_FFP_EMIT_FLOAT3]  = (glAttribFunc)GL_EXTCALL(glSecondaryColor3fvEXT);
4535     }
4536     else
4537     {
4538         specular_funcs[WINED3D_FFP_EMIT_FLOAT3]  = warn_no_specular_func;
4539     }
4540     specular_funcs[WINED3D_FFP_EMIT_FLOAT4]      = invalid_func;
4541     if (gl_info->supported[EXT_SECONDARY_COLOR])
4542     {
4543         specular_func_3ubv = (glAttribFunc)GL_EXTCALL(glSecondaryColor3ubvEXT);
4544         specular_funcs[WINED3D_FFP_EMIT_D3DCOLOR] = specular_d3dcolor;
4545     }
4546     else
4547     {
4548         specular_funcs[WINED3D_FFP_EMIT_D3DCOLOR] = warn_no_specular_func;
4549     }
4550     specular_funcs[WINED3D_FFP_EMIT_UBYTE4]      = invalid_func;
4551     specular_funcs[WINED3D_FFP_EMIT_SHORT2]      = invalid_func;
4552     specular_funcs[WINED3D_FFP_EMIT_SHORT4]      = invalid_func;
4553     specular_funcs[WINED3D_FFP_EMIT_UBYTE4N]     = invalid_func;
4554     specular_funcs[WINED3D_FFP_EMIT_SHORT2N]     = invalid_func;
4555     specular_funcs[WINED3D_FFP_EMIT_SHORT4N]     = invalid_func;
4556     specular_funcs[WINED3D_FFP_EMIT_USHORT2N]    = invalid_func;
4557     specular_funcs[WINED3D_FFP_EMIT_USHORT4N]    = invalid_func;
4558     specular_funcs[WINED3D_FFP_EMIT_UDEC3]       = invalid_func;
4559     specular_funcs[WINED3D_FFP_EMIT_DEC3N]       = invalid_func;
4560     specular_funcs[WINED3D_FFP_EMIT_FLOAT16_2]   = invalid_func;
4561     specular_funcs[WINED3D_FFP_EMIT_FLOAT16_4]   = invalid_func;
4562
4563     /* Only 3 component entry points here. Test how others behave. Float4 normals are used
4564      * by one of our tests, trying to pass it to the pixel shader, which fails on Windows.
4565      */
4566     normal_funcs[WINED3D_FFP_EMIT_FLOAT1]         = invalid_func;
4567     normal_funcs[WINED3D_FFP_EMIT_FLOAT2]         = invalid_func;
4568     normal_funcs[WINED3D_FFP_EMIT_FLOAT3]         = (glAttribFunc)glNormal3fv;
4569     normal_funcs[WINED3D_FFP_EMIT_FLOAT4]         = (glAttribFunc)glNormal3fv; /* Just ignore the 4th value */
4570     normal_funcs[WINED3D_FFP_EMIT_D3DCOLOR]       = invalid_func;
4571     normal_funcs[WINED3D_FFP_EMIT_UBYTE4]         = invalid_func;
4572     normal_funcs[WINED3D_FFP_EMIT_SHORT2]         = invalid_func;
4573     normal_funcs[WINED3D_FFP_EMIT_SHORT4]         = invalid_func;
4574     normal_funcs[WINED3D_FFP_EMIT_UBYTE4N]        = invalid_func;
4575     normal_funcs[WINED3D_FFP_EMIT_SHORT2N]        = invalid_func;
4576     normal_funcs[WINED3D_FFP_EMIT_SHORT4N]        = invalid_func;
4577     normal_funcs[WINED3D_FFP_EMIT_USHORT2N]       = invalid_func;
4578     normal_funcs[WINED3D_FFP_EMIT_USHORT4N]       = invalid_func;
4579     normal_funcs[WINED3D_FFP_EMIT_UDEC3]          = invalid_func;
4580     normal_funcs[WINED3D_FFP_EMIT_DEC3N]          = invalid_func;
4581     normal_funcs[WINED3D_FFP_EMIT_FLOAT16_2]      = invalid_func;
4582     normal_funcs[WINED3D_FFP_EMIT_FLOAT16_4]      = invalid_func;
4583
4584     multi_texcoord_funcs[WINED3D_FFP_EMIT_FLOAT1]    = (glMultiTexCoordFunc)GL_EXTCALL(glMultiTexCoord1fvARB);
4585     multi_texcoord_funcs[WINED3D_FFP_EMIT_FLOAT2]    = (glMultiTexCoordFunc)GL_EXTCALL(glMultiTexCoord2fvARB);
4586     multi_texcoord_funcs[WINED3D_FFP_EMIT_FLOAT3]    = (glMultiTexCoordFunc)GL_EXTCALL(glMultiTexCoord3fvARB);
4587     multi_texcoord_funcs[WINED3D_FFP_EMIT_FLOAT4]    = (glMultiTexCoordFunc)GL_EXTCALL(glMultiTexCoord4fvARB);
4588     multi_texcoord_funcs[WINED3D_FFP_EMIT_D3DCOLOR]  = invalid_texcoord_func;
4589     multi_texcoord_funcs[WINED3D_FFP_EMIT_UBYTE4]    = invalid_texcoord_func;
4590     multi_texcoord_funcs[WINED3D_FFP_EMIT_SHORT2]    = (glMultiTexCoordFunc)GL_EXTCALL(glMultiTexCoord2svARB);
4591     multi_texcoord_funcs[WINED3D_FFP_EMIT_SHORT4]    = (glMultiTexCoordFunc)GL_EXTCALL(glMultiTexCoord4svARB);
4592     multi_texcoord_funcs[WINED3D_FFP_EMIT_UBYTE4N]   = invalid_texcoord_func;
4593     multi_texcoord_funcs[WINED3D_FFP_EMIT_SHORT2N]   = invalid_texcoord_func;
4594     multi_texcoord_funcs[WINED3D_FFP_EMIT_SHORT4N]   = invalid_texcoord_func;
4595     multi_texcoord_funcs[WINED3D_FFP_EMIT_USHORT2N]  = invalid_texcoord_func;
4596     multi_texcoord_funcs[WINED3D_FFP_EMIT_USHORT4N]  = invalid_texcoord_func;
4597     multi_texcoord_funcs[WINED3D_FFP_EMIT_UDEC3]     = invalid_texcoord_func;
4598     multi_texcoord_funcs[WINED3D_FFP_EMIT_DEC3N]     = invalid_texcoord_func;
4599     if (gl_info->supported[NV_HALF_FLOAT])
4600     {
4601         /* Not supported by ARB_HALF_FLOAT_VERTEX, so check for NV_HALF_FLOAT */
4602         multi_texcoord_funcs[WINED3D_FFP_EMIT_FLOAT16_2] = (glMultiTexCoordFunc)GL_EXTCALL(glMultiTexCoord2hvNV);
4603         multi_texcoord_funcs[WINED3D_FFP_EMIT_FLOAT16_4] = (glMultiTexCoordFunc)GL_EXTCALL(glMultiTexCoord4hvNV);
4604     } else {
4605         multi_texcoord_funcs[WINED3D_FFP_EMIT_FLOAT16_2] = invalid_texcoord_func;
4606         multi_texcoord_funcs[WINED3D_FFP_EMIT_FLOAT16_4] = invalid_texcoord_func;
4607     }
4608 }
4609
4610 BOOL InitAdapters(IWineD3DImpl *This)
4611 {
4612     static HMODULE mod_gl;
4613     BOOL ret;
4614     int ps_selected_mode, vs_selected_mode;
4615
4616     /* No need to hold any lock. The calling library makes sure only one thread calls
4617      * wined3d simultaneously
4618      */
4619
4620     TRACE("Initializing adapters\n");
4621
4622     if(!mod_gl) {
4623 #ifdef USE_WIN32_OPENGL
4624 #define USE_GL_FUNC(pfn) pfn = (void*)GetProcAddress(mod_gl, #pfn);
4625         mod_gl = LoadLibraryA("opengl32.dll");
4626         if(!mod_gl) {
4627             ERR("Can't load opengl32.dll!\n");
4628             goto nogl_adapter;
4629         }
4630 #else
4631 #define USE_GL_FUNC(pfn) pfn = (void*)pwglGetProcAddress(#pfn);
4632         /* To bypass the opengl32 thunks load wglGetProcAddress from gdi32 (glXGetProcAddress wrapper) instead of opengl32's */
4633         mod_gl = GetModuleHandleA("gdi32.dll");
4634 #endif
4635     }
4636
4637 /* Load WGL core functions from opengl32.dll */
4638 #define USE_WGL_FUNC(pfn) p##pfn = (void*)GetProcAddress(mod_gl, #pfn);
4639     WGL_FUNCS_GEN;
4640 #undef USE_WGL_FUNC
4641
4642     if(!pwglGetProcAddress) {
4643         ERR("Unable to load wglGetProcAddress!\n");
4644         goto nogl_adapter;
4645     }
4646
4647 /* Dynamically load all GL core functions */
4648     GL_FUNCS_GEN;
4649 #undef USE_GL_FUNC
4650
4651     /* Load glFinish and glFlush from opengl32.dll even if we're not using WIN32 opengl
4652      * otherwise because we have to use winex11.drv's override
4653      */
4654 #ifdef USE_WIN32_OPENGL
4655     wglFinish = (void*)GetProcAddress(mod_gl, "glFinish");
4656     wglFlush = (void*)GetProcAddress(mod_gl, "glFlush");
4657 #else
4658     wglFinish = (void*)pwglGetProcAddress("wglFinish");
4659     wglFlush = (void*)pwglGetProcAddress("wglFlush");
4660 #endif
4661
4662     glEnableWINE = glEnable;
4663     glDisableWINE = glDisable;
4664
4665     /* For now only one default adapter */
4666     {
4667         struct wined3d_adapter *adapter = &This->adapters[0];
4668         const struct wined3d_gl_info *gl_info = &adapter->gl_info;
4669         struct wined3d_fake_gl_ctx fake_gl_ctx = {0};
4670         int iPixelFormat;
4671         int res;
4672         int i;
4673         WineD3D_PixelFormat *cfgs;
4674         DISPLAY_DEVICEW DisplayDevice;
4675         HDC hdc;
4676
4677         TRACE("Initializing default adapter\n");
4678         adapter->num = 0;
4679         adapter->monitorPoint.x = -1;
4680         adapter->monitorPoint.y = -1;
4681
4682         if (!AllocateLocallyUniqueId(&adapter->luid))
4683         {
4684             DWORD err = GetLastError();
4685             ERR("Failed to set adapter LUID (%#x).\n", err);
4686             goto nogl_adapter;
4687         }
4688         TRACE("Allocated LUID %08x:%08x for adapter.\n",
4689                 adapter->luid.HighPart, adapter->luid.LowPart);
4690
4691         if (!WineD3D_CreateFakeGLContext(&fake_gl_ctx))
4692         {
4693             ERR("Failed to get a gl context for default adapter\n");
4694             goto nogl_adapter;
4695         }
4696
4697         ret = IWineD3DImpl_FillGLCaps(&adapter->driver_info, &adapter->gl_info);
4698         if(!ret) {
4699             ERR("Failed to initialize gl caps for default adapter\n");
4700             WineD3D_ReleaseFakeGLContext(&fake_gl_ctx);
4701             goto nogl_adapter;
4702         }
4703         ret = initPixelFormats(&adapter->gl_info, adapter->driver_info.vendor);
4704         if(!ret) {
4705             ERR("Failed to init gl formats\n");
4706             WineD3D_ReleaseFakeGLContext(&fake_gl_ctx);
4707             goto nogl_adapter;
4708         }
4709
4710         hdc = fake_gl_ctx.dc;
4711
4712         /* Use the VideoRamSize registry setting when set */
4713         if(wined3d_settings.emulated_textureram)
4714             adapter->TextureRam = wined3d_settings.emulated_textureram;
4715         else
4716             adapter->TextureRam = adapter->gl_info.vidmem;
4717         adapter->UsedTextureRam = 0;
4718         TRACE("Emulating %dMB of texture ram\n", adapter->TextureRam/(1024*1024));
4719
4720         /* Initialize the Adapter's DeviceName which is required for ChangeDisplaySettings and friends */
4721         DisplayDevice.cb = sizeof(DisplayDevice);
4722         EnumDisplayDevicesW(NULL, 0 /* Adapter 0 = iDevNum 0 */, &DisplayDevice, 0);
4723         TRACE("DeviceName: %s\n", debugstr_w(DisplayDevice.DeviceName));
4724         strcpyW(adapter->DeviceName, DisplayDevice.DeviceName);
4725
4726         if (gl_info->supported[WGL_ARB_PIXEL_FORMAT])
4727         {
4728             int attribute;
4729             int attribs[10];
4730             int values[10];
4731             int nAttribs = 0;
4732
4733             attribute = WGL_NUMBER_PIXEL_FORMATS_ARB;
4734             GL_EXTCALL(wglGetPixelFormatAttribivARB(hdc, 0, 0, 1, &attribute, &adapter->nCfgs));
4735
4736             adapter->cfgs = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, adapter->nCfgs *sizeof(WineD3D_PixelFormat));
4737             cfgs = adapter->cfgs;
4738             attribs[nAttribs++] = WGL_RED_BITS_ARB;
4739             attribs[nAttribs++] = WGL_GREEN_BITS_ARB;
4740             attribs[nAttribs++] = WGL_BLUE_BITS_ARB;
4741             attribs[nAttribs++] = WGL_ALPHA_BITS_ARB;
4742             attribs[nAttribs++] = WGL_DEPTH_BITS_ARB;
4743             attribs[nAttribs++] = WGL_STENCIL_BITS_ARB;
4744             attribs[nAttribs++] = WGL_DRAW_TO_WINDOW_ARB;
4745             attribs[nAttribs++] = WGL_PIXEL_TYPE_ARB;
4746             attribs[nAttribs++] = WGL_DOUBLE_BUFFER_ARB;
4747             attribs[nAttribs++] = WGL_AUX_BUFFERS_ARB;
4748
4749             for (iPixelFormat=1; iPixelFormat <= adapter->nCfgs; ++iPixelFormat)
4750             {
4751                 res = GL_EXTCALL(wglGetPixelFormatAttribivARB(hdc, iPixelFormat, 0, nAttribs, attribs, values));
4752
4753                 if(!res)
4754                     continue;
4755
4756                 /* Cache the pixel format */
4757                 cfgs->iPixelFormat = iPixelFormat;
4758                 cfgs->redSize = values[0];
4759                 cfgs->greenSize = values[1];
4760                 cfgs->blueSize = values[2];
4761                 cfgs->alphaSize = values[3];
4762                 cfgs->depthSize = values[4];
4763                 cfgs->stencilSize = values[5];
4764                 cfgs->windowDrawable = values[6];
4765                 cfgs->iPixelType = values[7];
4766                 cfgs->doubleBuffer = values[8];
4767                 cfgs->auxBuffers = values[9];
4768
4769                 cfgs->pbufferDrawable = FALSE;
4770                 /* Check for pbuffer support when it is around as
4771                  * wglGetPixelFormatAttribiv fails for unknown attributes. */
4772                 if (gl_info->supported[WGL_ARB_PBUFFER])
4773                 {
4774                     int attrib = WGL_DRAW_TO_PBUFFER_ARB;
4775                     int value;
4776                     if(GL_EXTCALL(wglGetPixelFormatAttribivARB(hdc, iPixelFormat, 0, 1, &attrib, &value)))
4777                         cfgs->pbufferDrawable = value;
4778                 }
4779
4780                 cfgs->numSamples = 0;
4781                 /* Check multisample support */
4782                 if (gl_info->supported[ARB_MULTISAMPLE])
4783                 {
4784                     int attrib[2] = {WGL_SAMPLE_BUFFERS_ARB, WGL_SAMPLES_ARB};
4785                     int value[2];
4786                     if(GL_EXTCALL(wglGetPixelFormatAttribivARB(hdc, iPixelFormat, 0, 2, attrib, value))) {
4787                         /* value[0] = WGL_SAMPLE_BUFFERS_ARB which tells whether multisampling is supported.
4788                         * value[1] = number of multi sample buffers*/
4789                         if(value[0])
4790                             cfgs->numSamples = value[1];
4791                     }
4792                 }
4793
4794                 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);
4795                 cfgs++;
4796             }
4797         }
4798         else
4799         {
4800             int nCfgs = DescribePixelFormat(hdc, 0, 0, 0);
4801             adapter->cfgs = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, nCfgs*sizeof(WineD3D_PixelFormat));
4802             adapter->nCfgs = 0; /* We won't accept all formats e.g. software accelerated ones will be skipped */
4803
4804             cfgs = adapter->cfgs;
4805             for(iPixelFormat=1; iPixelFormat<=nCfgs; iPixelFormat++)
4806             {
4807                 PIXELFORMATDESCRIPTOR ppfd;
4808
4809                 res = DescribePixelFormat(hdc, iPixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &ppfd);
4810                 if(!res)
4811                     continue;
4812
4813                 /* We only want HW acceleration using an OpenGL ICD driver.
4814                  * PFD_GENERIC_FORMAT = slow opengl 1.1 gdi software rendering
4815                  * PFD_GENERIC_ACCELERATED = partial hw acceleration using a MCD driver (e.g. 3dfx minigl)
4816                  */
4817                 if(ppfd.dwFlags & (PFD_GENERIC_FORMAT | PFD_GENERIC_ACCELERATED))
4818                 {
4819                     TRACE("Skipping iPixelFormat=%d because it isn't ICD accelerated\n", iPixelFormat);
4820                     continue;
4821                 }
4822
4823                 cfgs->iPixelFormat = iPixelFormat;
4824                 cfgs->redSize = ppfd.cRedBits;
4825                 cfgs->greenSize = ppfd.cGreenBits;
4826                 cfgs->blueSize = ppfd.cBlueBits;
4827                 cfgs->alphaSize = ppfd.cAlphaBits;
4828                 cfgs->depthSize = ppfd.cDepthBits;
4829                 cfgs->stencilSize = ppfd.cStencilBits;
4830                 cfgs->pbufferDrawable = 0;
4831                 cfgs->windowDrawable = (ppfd.dwFlags & PFD_DRAW_TO_WINDOW) ? 1 : 0;
4832                 cfgs->iPixelType = (ppfd.iPixelType == PFD_TYPE_RGBA) ? WGL_TYPE_RGBA_ARB : WGL_TYPE_COLORINDEX_ARB;
4833                 cfgs->doubleBuffer = (ppfd.dwFlags & PFD_DOUBLEBUFFER) ? 1 : 0;
4834                 cfgs->auxBuffers = ppfd.cAuxBuffers;
4835                 cfgs->numSamples = 0;
4836
4837                 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);
4838                 cfgs++;
4839                 adapter->nCfgs++;
4840             }
4841
4842             /* 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 */
4843             if(!adapter->nCfgs)
4844             {
4845                 ERR("Disabling Direct3D because no hardware accelerated pixel formats have been found!\n");
4846
4847                 WineD3D_ReleaseFakeGLContext(&fake_gl_ctx);
4848                 HeapFree(GetProcessHeap(), 0, adapter->cfgs);
4849                 goto nogl_adapter;
4850             }
4851         }
4852
4853         /* D16, D24X8 and D24S8 are common depth / depth+stencil formats. All drivers support them though this doesn't
4854          * mean that the format is offered in hardware. For instance Geforce8 cards don't have offer D16 in hardware
4855          * but just fake it using D24(X8?) which is fine. D3D also allows that.
4856          * Some display drivers (i915 on Linux) only report mixed depth+stencil formats like D24S8. MSDN clearly mentions
4857          * that only on lockable formats (e.g. D16_locked) the bit order is guaranteed and that on other formats the
4858          * driver is allowed to consume more bits EXCEPT for stencil bits.
4859          *
4860          * Mark an adapter with this broken stencil behavior.
4861          */
4862         adapter->brokenStencil = TRUE;
4863         for (i = 0, cfgs = adapter->cfgs; i < adapter->nCfgs; ++i)
4864         {
4865             /* Nearly all drivers offer depth formats without stencil, only on i915 this if-statement won't be entered. */
4866             if(cfgs[i].depthSize && !cfgs[i].stencilSize) {
4867                 adapter->brokenStencil = FALSE;
4868                 break;
4869             }
4870         }
4871
4872         WineD3D_ReleaseFakeGLContext(&fake_gl_ctx);
4873
4874         select_shader_mode(&adapter->gl_info, &ps_selected_mode, &vs_selected_mode);
4875         fillGLAttribFuncs(&adapter->gl_info);
4876         adapter->opengl = TRUE;
4877     }
4878     This->adapter_count = 1;
4879     TRACE("%u adapters successfully initialized\n", This->adapter_count);
4880
4881     return TRUE;
4882
4883 nogl_adapter:
4884     /* Initialize an adapter for ddraw-only memory counting */
4885     memset(This->adapters, 0, sizeof(This->adapters));
4886     This->adapters[0].num = 0;
4887     This->adapters[0].opengl = FALSE;
4888     This->adapters[0].monitorPoint.x = -1;
4889     This->adapters[0].monitorPoint.y = -1;
4890
4891     This->adapters[0].driver_info.name = "Display";
4892     This->adapters[0].driver_info.description = "WineD3D DirectDraw Emulation";
4893     if(wined3d_settings.emulated_textureram) {
4894         This->adapters[0].TextureRam = wined3d_settings.emulated_textureram;
4895     } else {
4896         This->adapters[0].TextureRam = 8 * 1024 * 1024; /* This is plenty for a DDraw-only card */
4897     }
4898
4899     initPixelFormatsNoGL(&This->adapters[0].gl_info);
4900
4901     This->adapter_count = 1;
4902     return FALSE;
4903 }
4904
4905 /**********************************************************
4906  * IWineD3D VTbl follows
4907  **********************************************************/
4908
4909 const IWineD3DVtbl IWineD3D_Vtbl =
4910 {
4911     /* IUnknown */
4912     IWineD3DImpl_QueryInterface,
4913     IWineD3DImpl_AddRef,
4914     IWineD3DImpl_Release,
4915     /* IWineD3D */
4916     IWineD3DImpl_GetParent,
4917     IWineD3DImpl_GetAdapterCount,
4918     IWineD3DImpl_RegisterSoftwareDevice,
4919     IWineD3DImpl_GetAdapterMonitor,
4920     IWineD3DImpl_GetAdapterModeCount,
4921     IWineD3DImpl_EnumAdapterModes,
4922     IWineD3DImpl_GetAdapterDisplayMode,
4923     IWineD3DImpl_GetAdapterIdentifier,
4924     IWineD3DImpl_CheckDeviceMultiSampleType,
4925     IWineD3DImpl_CheckDepthStencilMatch,
4926     IWineD3DImpl_CheckDeviceType,
4927     IWineD3DImpl_CheckDeviceFormat,
4928     IWineD3DImpl_CheckDeviceFormatConversion,
4929     IWineD3DImpl_GetDeviceCaps,
4930     IWineD3DImpl_CreateDevice
4931 };
4932
4933 static void STDMETHODCALLTYPE wined3d_null_wined3d_object_destroyed(void *parent) {}
4934
4935 const struct wined3d_parent_ops wined3d_null_parent_ops =
4936 {
4937     wined3d_null_wined3d_object_destroyed,
4938 };