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