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