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