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