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