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