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