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