wined3d: When volume textures aren't around (GL_EXT_texture3D not supported) return...
[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 /* Check if a texture format is supported on the given adapter */
2008 static BOOL CheckTextureCapability(UINT Adapter, WINED3DFORMAT CheckFormat)
2009 {
2010     switch (CheckFormat) {
2011
2012         /*****
2013          *  supported: RGB(A) formats
2014          */
2015         case WINED3DFMT_R8G8B8: /* Enable for dx7, blacklisted for 8 and 9 above */
2016         case WINED3DFMT_A8R8G8B8:
2017         case WINED3DFMT_X8R8G8B8:
2018         case WINED3DFMT_R5G6B5:
2019         case WINED3DFMT_X1R5G5B5:
2020         case WINED3DFMT_A1R5G5B5:
2021         case WINED3DFMT_A4R4G4B4:
2022         case WINED3DFMT_R3G3B2:
2023         case WINED3DFMT_A8:
2024         case WINED3DFMT_X4R4G4B4:
2025         case WINED3DFMT_A8B8G8R8:
2026         case WINED3DFMT_X8B8G8R8:
2027         case WINED3DFMT_A2R10G10B10:
2028         case WINED3DFMT_A2B10G10R10:
2029         case WINED3DFMT_G16R16:
2030             TRACE_(d3d_caps)("[OK]\n");
2031             return TRUE;
2032
2033         /*****
2034          *  supported: Palettized
2035          */
2036         case WINED3DFMT_P8:
2037             TRACE_(d3d_caps)("[OK]\n");
2038             return TRUE;
2039         /* No Windows driver offers A8P8, so don't offer it either */
2040         case WINED3DFMT_A8P8:
2041             return FALSE;
2042
2043         /*****
2044          *  Supported: (Alpha)-Luminance
2045          */
2046         case WINED3DFMT_L8:
2047         case WINED3DFMT_A8L8:
2048         case WINED3DFMT_A4L4:
2049         case WINED3DFMT_L16:
2050             TRACE_(d3d_caps)("[OK]\n");
2051             return TRUE;
2052
2053         /* Depth/stencil is handled using checkDepthStencilCapability, return FALSE here */
2054         case WINED3DFMT_D16_LOCKABLE:
2055         case WINED3DFMT_D16:
2056         case WINED3DFMT_D15S1:
2057         case WINED3DFMT_D24X8:
2058         case WINED3DFMT_D24X4S4:
2059         case WINED3DFMT_D24S8:
2060         case WINED3DFMT_D24FS8:
2061         case WINED3DFMT_D32:
2062         case WINED3DFMT_D32F_LOCKABLE:
2063             return FALSE;
2064
2065         /*****
2066          *  Not supported everywhere(depends on GL_ATI_envmap_bumpmap or
2067          *  GL_NV_texture_shader), but advertized to make apps happy.
2068          *  Enable some because games often fail when they are not available
2069          *  and are still playable even without bump mapping
2070          */
2071         case WINED3DFMT_V8U8:
2072             if(GL_SUPPORT(NV_TEXTURE_SHADER) || GL_SUPPORT(ATI_ENVMAP_BUMPMAP)) {
2073                 return WINED3D_OK;
2074             }
2075             TRACE_(d3d_caps)("[FAILED] - No converted formats on volumes\n");
2076             return FALSE;
2077
2078         case WINED3DFMT_X8L8V8U8:
2079         case WINED3DFMT_L6V5U5:
2080             WARN_(d3d_caps)("[FAILED]\n");
2081             return FALSE;
2082
2083         case WINED3DFMT_Q8W8V8U8:
2084         case WINED3DFMT_V16U16:
2085             if(GL_SUPPORT(NV_TEXTURE_SHADER)) {
2086                 WARN_(d3d_caps)("[Not supported, but pretended to do]\n");
2087                 return TRUE;
2088             }
2089             TRACE_(d3d_caps)("[FAILED] - No converted formats on volumes\n");
2090             return FALSE;
2091
2092         /* Those are not advertized by the nvidia windows driver, and not
2093          * supported natively by GL_NV_texture_shader or GL_ATI_envmap_bumpmap.
2094          * WINED3DFMT_A2W10V10U10 could be loaded into shaders using the unsigned
2095          * ARGB format if needed
2096          */
2097         case WINED3DFMT_W11V11U10:
2098         case WINED3DFMT_A2W10V10U10:
2099             WARN_(d3d_caps)("[FAILED]\n");
2100             return FALSE;
2101
2102         case WINED3DFMT_DXT1:
2103         case WINED3DFMT_DXT2:
2104         case WINED3DFMT_DXT3:
2105         case WINED3DFMT_DXT4:
2106         case WINED3DFMT_DXT5:
2107             if (GL_SUPPORT(EXT_TEXTURE_COMPRESSION_S3TC)) {
2108                 TRACE_(d3d_caps)("[OK]\n");
2109                 return TRUE;
2110             }
2111             TRACE_(d3d_caps)("[FAILED]\n");
2112             return FALSE;
2113
2114
2115         /*****
2116          *  Odd formats - not supported
2117          */
2118         case WINED3DFMT_VERTEXDATA:
2119         case WINED3DFMT_INDEX16:
2120         case WINED3DFMT_INDEX32:
2121         case WINED3DFMT_Q16W16V16U16:
2122             TRACE_(d3d_caps)("[FAILED]\n"); /* Enable when implemented */
2123             return FALSE;
2124
2125         /*****
2126          *  WINED3DFMT_CxV8U8: Not supported right now
2127          */
2128         case WINED3DFMT_CxV8U8:
2129             TRACE_(d3d_caps)("[FAILED]\n"); /* Enable when implemented */
2130             return FALSE;
2131
2132         /* YUV formats, not supported for now */
2133         case WINED3DFMT_UYVY:
2134         case WINED3DFMT_YUY2:
2135             TRACE_(d3d_caps)("[FAILED]\n"); /* Enable when implemented */
2136             return FALSE;
2137
2138             /* Not supported */
2139         case WINED3DFMT_A16B16G16R16:
2140         case WINED3DFMT_A8R3G3B2:
2141             TRACE_(d3d_caps)("[FAILED]\n"); /* Enable when implemented */
2142             return FALSE;
2143
2144             /* Floating point formats */
2145         case WINED3DFMT_R16F:
2146         case WINED3DFMT_A16B16G16R16F:
2147             if(GL_SUPPORT(ARB_HALF_FLOAT_PIXEL)) {
2148                 TRACE_(d3d_caps)("[OK]\n");
2149                 return TRUE;
2150             }
2151             TRACE_(d3d_caps)("[FAILED]\n");
2152             return FALSE;
2153
2154         case WINED3DFMT_R32F:
2155         case WINED3DFMT_A32B32G32R32F:
2156             if (GL_SUPPORT(ARB_TEXTURE_FLOAT)) {
2157                 TRACE_(d3d_caps)("[OK]\n");
2158                 return TRUE;
2159             }
2160             TRACE_(d3d_caps)("[FAILED]\n");
2161             return FALSE;
2162
2163         case WINED3DFMT_G16R16F:
2164         case WINED3DFMT_G32R32F:
2165             TRACE_(d3d_caps)("[FAILED]\n");
2166             return FALSE;
2167
2168         /* ATI instancing hack: Although ATI cards do not support Shader Model 3.0, they support
2169          * instancing. To query if the card supports instancing CheckDeviceFormat with the special format
2170          * MAKEFOURCC('I','N','S','T') is used. Should a (broken) app check for this provide a proper return value.
2171          * We can do instancing with all shader versions, but we need vertex shaders.
2172          *
2173          * Additionally applications have to set the D3DRS_POINTSIZE render state to
2174 MAKEFOURCC('I','N','S','T') once
2175          * to enable instancing. WineD3D doesn't need that and just ignores it.
2176          *
2177          * With Shader Model 3.0 capable cards Instancing 'just works' in Windows.
2178          */
2179         case WINEMAKEFOURCC('I','N','S','T'):
2180             TRACE("ATI Instancing check hack\n");
2181             if(GL_SUPPORT(ARB_VERTEX_PROGRAM) || GL_SUPPORT(ARB_VERTEX_SHADER)) {
2182                 TRACE_(d3d_caps)("[OK]\n");
2183                 return TRUE;
2184             }
2185             TRACE_(d3d_caps)("[FAILED]\n");
2186             return FALSE;
2187
2188         /* Some weird FOURCC formats */
2189         case WINED3DFMT_R8G8_B8G8:
2190         case WINED3DFMT_G8R8_G8B8:
2191         case WINED3DFMT_MULTI2_ARGB8:
2192             TRACE_(d3d_caps)("[FAILED]\n");
2193             return FALSE;
2194
2195         case WINED3DFMT_UNKNOWN:
2196             return FALSE;
2197
2198         default:
2199             ERR("Unhandled format=%s\n", debug_d3dformat(CheckFormat));
2200             break;
2201     }
2202     return FALSE;
2203 }
2204
2205 static BOOL CheckVertexTextureCapability(UINT Adapter, WINED3DFORMAT CheckFormat)
2206 {
2207     if (!GL_LIMITS(vertex_samplers)) {
2208         TRACE_(d3d_caps)("[FAILED]\n");
2209         return FALSE;
2210     }
2211
2212     switch (CheckFormat) {
2213         case WINED3DFMT_A32B32G32R32F:
2214             if (!GL_SUPPORT(ARB_TEXTURE_FLOAT)) {
2215                 TRACE_(d3d_caps)("[FAILED]\n");
2216                 return FALSE;
2217             }
2218             TRACE_(d3d_caps)("[OK]\n");
2219             return TRUE;
2220
2221         default:
2222             TRACE_(d3d_caps)("[FAILED]\n");
2223             return FALSE;
2224     }
2225     return FALSE;
2226 }
2227
2228 static HRESULT WINAPI IWineD3DImpl_CheckDeviceFormat(IWineD3D *iface, UINT Adapter, WINED3DDEVTYPE DeviceType, 
2229                                               WINED3DFORMAT AdapterFormat, DWORD Usage, WINED3DRESOURCETYPE RType, WINED3DFORMAT CheckFormat) {
2230     IWineD3DImpl *This = (IWineD3DImpl *)iface;
2231     DWORD UsageCaps = 0;
2232
2233     TRACE_(d3d_caps)("(%p)-> (STUB) (Adptr:%d, DevType:(%u,%s), AdptFmt:(%u,%s), Use:(%u,%s,%s), ResTyp:(%x,%s), CheckFmt:(%u,%s))\n",
2234           This,
2235           Adapter,
2236           DeviceType, debug_d3ddevicetype(DeviceType),
2237           AdapterFormat, debug_d3dformat(AdapterFormat),
2238           Usage, debug_d3dusage(Usage), debug_d3dusagequery(Usage),
2239           RType, debug_d3dresourcetype(RType),
2240           CheckFormat, debug_d3dformat(CheckFormat));
2241
2242     if (Adapter >= IWineD3D_GetAdapterCount(iface)) {
2243         return WINED3DERR_INVALIDCALL;
2244     }
2245
2246     if(RType == WINED3DRTYPE_CUBETEXTURE) {
2247         /* Cubetexture allows:
2248          *                    - D3DUSAGE_AUTOGENMIPMAP
2249          *                    - D3DUSAGE_DEPTHSTENCIL
2250          *                    - D3DUSAGE_DYNAMIC
2251          *                    - D3DUSAGE_NONSECURE (d3d9ex)
2252          *                    - D3DUSAGE_RENDERTARGET
2253          *                    - D3DUSAGE_SOFTWAREPROCESSING
2254          */
2255         if(GL_SUPPORT(ARB_TEXTURE_CUBE_MAP)) {
2256             /* Check if the texture format is around */
2257             if(CheckTextureCapability(Adapter, CheckFormat)) {
2258                 if(Usage & WINED3DUSAGE_AUTOGENMIPMAP) {
2259                     /* Check for automatic mipmap generation support */
2260                     if(GL_SUPPORT(SGIS_GENERATE_MIPMAP)) {
2261                         UsageCaps |= WINED3DUSAGE_AUTOGENMIPMAP;
2262                     } else {
2263                         /* When autogenmipmap isn't around continue and return WINED3DOK_NOAUOTGEN instead of D3D_OK */
2264                         TRACE_(d3d_caps)("[FAILED] - No autogenmipmap support, but continuing\n");
2265                     }
2266                 }
2267
2268                 /* Always report dynamic locking */
2269                 if(Usage & WINED3DUSAGE_DYNAMIC)
2270                     UsageCaps |= WINED3DUSAGE_DYNAMIC;
2271
2272                 if(Usage & WINED3DUSAGE_RENDERTARGET) {
2273                     if(CheckRenderTargetCapability(AdapterFormat, CheckFormat)) {
2274                         UsageCaps |= WINED3DUSAGE_RENDERTARGET;
2275                     } else {
2276                         TRACE_(d3d_caps)("[FAILED] - No rendertarget support\n");
2277                         return WINED3DERR_NOTAVAILABLE;
2278                     }
2279                 }
2280
2281                 /* Always report software processing */
2282                 if(Usage & WINED3DUSAGE_SOFTWAREPROCESSING)
2283                     UsageCaps |= WINED3DUSAGE_SOFTWAREPROCESSING;
2284
2285                 /* Check QUERY_FILTER support */
2286                 if(Usage & WINED3DUSAGE_QUERY_FILTER) {
2287                     if(CheckFilterCapability(CheckFormat)) {
2288                         UsageCaps |= WINED3DUSAGE_QUERY_FILTER;
2289                     } else {
2290                         TRACE_(d3d_caps)("[FAILED] - No query filter support\n");
2291                         return WINED3DERR_NOTAVAILABLE;
2292                     }
2293                 }
2294
2295                 /* Check QUERY_SRGBREAD support */
2296                 if(Usage & WINED3DUSAGE_QUERY_SRGBREAD) {
2297                     if(CheckSrgbReadCapability(Adapter, CheckFormat)) {
2298                         UsageCaps |= WINED3DUSAGE_QUERY_SRGBREAD;
2299                     } else {
2300                         TRACE_(d3d_caps)("[FAILED] - No query srgbread support\n");
2301                         return WINED3DERR_NOTAVAILABLE;
2302                     }
2303                 }
2304
2305                 /* Check QUERY_VERTEXTEXTURE support */
2306                 if(Usage & WINED3DUSAGE_QUERY_VERTEXTEXTURE) {
2307                     if(CheckVertexTextureCapability(Adapter, CheckFormat)) {
2308                         UsageCaps |= WINED3DUSAGE_QUERY_VERTEXTEXTURE;
2309                     } else {
2310                         TRACE_(d3d_caps)("[FAILED] - No query vertextexture support\n");
2311                         return WINED3DERR_NOTAVAILABLE;
2312                     }
2313                 }
2314             }
2315         }
2316     } else if(RType == WINED3DRTYPE_SURFACE) {
2317         /* Surface allows:
2318          *                - D3DUSAGE_DEPTHSTENCIL
2319          *                - D3DUSAGE_NONSECURE (d3d9ex)
2320          *                - D3DUSAGE_RENDERTARGET
2321          */
2322
2323         if(Usage & WINED3DUSAGE_DEPTHSTENCIL) {
2324             if(CheckDepthStencilCapability(Adapter, AdapterFormat, CheckFormat)) {
2325                 UsageCaps |= WINED3DUSAGE_DEPTHSTENCIL;
2326             } else {
2327                 TRACE_(d3d_caps)("[FAILED] - No depthstencil support\n");
2328                 return WINED3DERR_NOTAVAILABLE;
2329             }
2330         }
2331
2332         if(Usage & WINED3DUSAGE_RENDERTARGET) {
2333             if(CheckRenderTargetCapability(AdapterFormat, CheckFormat)) {
2334                 UsageCaps |= WINED3DUSAGE_RENDERTARGET;
2335             } else {
2336                 TRACE_(d3d_caps)("[FAILED] - No rendertarget support\n");
2337                  return WINED3DERR_NOTAVAILABLE;
2338             }
2339         }
2340     } else if(RType == WINED3DRTYPE_TEXTURE) {
2341         /* Texture allows:
2342          *                - D3DUSAGE_AUTOGENMIPMAP
2343          *                - D3DUSAGE_DEPTHSTENCIL
2344          *                - D3DUSAGE_DMAP
2345          *                - D3DUSAGE_DYNAMIC
2346          *                - D3DUSAGE_NONSECURE (d3d9ex)
2347          *                - D3DUSAGE_RENDERTARGET
2348          *                - D3DUSAGE_SOFTWAREPROCESSING
2349          *                - D3DUSAGE_TEXTAPI (d3d9ex)
2350          */
2351
2352         /* Check if the texture format is around */
2353         if(CheckTextureCapability(Adapter, CheckFormat)) {
2354             if(Usage & WINED3DUSAGE_AUTOGENMIPMAP) {
2355                 /* Check for automatic mipmap generation support */
2356                 if(GL_SUPPORT(SGIS_GENERATE_MIPMAP)) {
2357                     UsageCaps |= WINED3DUSAGE_AUTOGENMIPMAP;
2358                 } else {
2359                     /* When autogenmipmap isn't around continue and return WINED3DOK_NOAUOTGEN instead of D3D_OK */
2360                     TRACE_(d3d_caps)("[FAILED] - No autogenmipmap support, but continuing\n");
2361                 }
2362             }
2363
2364             /* Always report dynamic locking */
2365             if(Usage & WINED3DUSAGE_DYNAMIC)
2366                 UsageCaps |= WINED3DUSAGE_DYNAMIC;
2367
2368             if(Usage & WINED3DUSAGE_RENDERTARGET) {
2369                 if(CheckRenderTargetCapability(AdapterFormat, CheckFormat)) {
2370                     UsageCaps |= WINED3DUSAGE_RENDERTARGET;
2371                 } else {
2372                     TRACE_(d3d_caps)("[FAILED] - No rendertarget support\n");
2373                      return WINED3DERR_NOTAVAILABLE;
2374                  }
2375             }
2376
2377             /* Always report software processing */
2378             if(Usage & WINED3DUSAGE_SOFTWAREPROCESSING)
2379                 UsageCaps |= WINED3DUSAGE_SOFTWAREPROCESSING;
2380
2381             /* Check QUERY_FILTER support */
2382             if(Usage & WINED3DUSAGE_QUERY_FILTER) {
2383                 if(CheckFilterCapability(CheckFormat)) {
2384                     UsageCaps |= WINED3DUSAGE_QUERY_FILTER;
2385                 } else {
2386                     TRACE_(d3d_caps)("[FAILED] - No query filter support\n");
2387                     return WINED3DERR_NOTAVAILABLE;
2388                 }
2389             }
2390
2391             /* Check QUERY_LEGACYBUMPMAP support */
2392             if(Usage & WINED3DUSAGE_QUERY_LEGACYBUMPMAP) {
2393                 if(CheckBumpMapCapability(Adapter, CheckFormat)) {
2394                     UsageCaps |= WINED3DUSAGE_QUERY_LEGACYBUMPMAP;
2395                 } else {
2396                     TRACE_(d3d_caps)("[FAILED] - No legacy bumpmap support\n");
2397                     return WINED3DERR_NOTAVAILABLE;
2398                 }
2399             }
2400
2401             /* Check QUERY_SRGBREAD support */
2402             if(Usage & WINED3DUSAGE_QUERY_SRGBREAD) {
2403                 if(CheckSrgbReadCapability(Adapter, CheckFormat)) {
2404                     UsageCaps |= WINED3DUSAGE_QUERY_SRGBREAD;
2405                 } else {
2406                     TRACE_(d3d_caps)("[FAILED] - No query srgbread support\n");
2407                     return WINED3DERR_NOTAVAILABLE;
2408                 }
2409             }
2410
2411             /* Check QUERY_VERTEXTEXTURE support */
2412             if(Usage & WINED3DUSAGE_QUERY_VERTEXTEXTURE) {
2413                 if(CheckVertexTextureCapability(Adapter, CheckFormat)) {
2414                     UsageCaps |= WINED3DUSAGE_QUERY_VERTEXTEXTURE;
2415                 } else {
2416                     TRACE_(d3d_caps)("[FAILED] - No query vertextexture support\n");
2417                     return WINED3DERR_NOTAVAILABLE;
2418                 }
2419             }
2420         } else if(CheckDepthStencilCapability(Adapter, AdapterFormat, CheckFormat)) {
2421             if(Usage & WINED3DUSAGE_DEPTHSTENCIL)
2422                 UsageCaps |= WINED3DUSAGE_DEPTHSTENCIL;
2423         }
2424     } else if(RType == WINED3DRTYPE_VOLUMETEXTURE) {
2425         /* Volumetexture allows:
2426          *                      - D3DUSAGE_DYNAMIC
2427          *                      - D3DUSAGE_NONSECURE (d3d9ex)
2428          *                      - D3DUSAGE_SOFTWAREPROCESSING
2429          */
2430
2431         /* Check volume texture and volume usage caps */
2432         if(GL_SUPPORT(EXT_TEXTURE3D)) {
2433             if(CheckTextureCapability(Adapter, CheckFormat) == FALSE) {
2434                 TRACE_(d3d_caps)("[FAILED] - Format not supported\n");
2435                 return WINED3DERR_NOTAVAILABLE;
2436             }
2437
2438             /* Always report dynamic locking */
2439             if(Usage & WINED3DUSAGE_DYNAMIC)
2440                 UsageCaps |= WINED3DUSAGE_DYNAMIC;
2441
2442             /* Always report software processing */
2443             if(Usage & WINED3DUSAGE_SOFTWAREPROCESSING)
2444                 UsageCaps |= WINED3DUSAGE_SOFTWAREPROCESSING;
2445
2446             /* Check QUERY_FILTER support */
2447             if(Usage & WINED3DUSAGE_QUERY_FILTER) {
2448                 if(CheckFilterCapability(CheckFormat)) {
2449                     UsageCaps |= WINED3DUSAGE_QUERY_FILTER;
2450                 } else {
2451                     TRACE_(d3d_caps)("[FAILED] - No query filter support\n");
2452                     return WINED3DERR_NOTAVAILABLE;
2453                 }
2454             }
2455
2456             /* Check QUERY_SRGBREAD support */
2457             if(Usage & WINED3DUSAGE_QUERY_SRGBREAD) {
2458                 if(CheckSrgbReadCapability(Adapter, CheckFormat)) {
2459                     UsageCaps |= WINED3DUSAGE_QUERY_SRGBREAD;
2460                 } else {
2461                     TRACE_(d3d_caps)("[FAILED] - No query srgbread support\n");
2462                     return WINED3DERR_NOTAVAILABLE;
2463                 }
2464             }
2465
2466             /* Check QUERY_VERTEXTEXTURE support */
2467             if(Usage & WINED3DUSAGE_QUERY_VERTEXTEXTURE) {
2468                 if(CheckVertexTextureCapability(Adapter, CheckFormat)) {
2469                     UsageCaps |= WINED3DUSAGE_QUERY_VERTEXTEXTURE;
2470                 } else {
2471                     TRACE_(d3d_caps)("[FAILED] - No query vertextexture support\n");
2472                     return WINED3DERR_NOTAVAILABLE;
2473                 }
2474             }
2475         } else {
2476             TRACE_(d3d_caps)("[FAILED] - No volume texture support\n");
2477             return WINED3DERR_NOTAVAILABLE;
2478         }
2479
2480         /* Filter formats that need conversion; For one part, this conversion is unimplemented,
2481          * and volume textures are huge, so it would be a big performance hit. Unless we hit an
2482          * app needing one of those formats, don't advertize them to avoid leading apps into
2483          * temptation. The windows drivers don't support most of those formats on volumes anyway,
2484          * except of R32F.
2485          */
2486         switch(CheckFormat) {
2487             case WINED3DFMT_P8:
2488             case WINED3DFMT_A4L4:
2489             case WINED3DFMT_R32F:
2490             case WINED3DFMT_R16F:
2491             case WINED3DFMT_X8L8V8U8:
2492             case WINED3DFMT_L6V5U5:
2493             case WINED3DFMT_G16R16:
2494                 TRACE_(d3d_caps)("[FAILED] - No converted formats on volumes\n");
2495                 return WINED3DERR_NOTAVAILABLE;
2496
2497             case WINED3DFMT_Q8W8V8U8:
2498             case WINED3DFMT_V16U16:
2499             if(!GL_SUPPORT(NV_TEXTURE_SHADER)) {
2500                 TRACE_(d3d_caps)("[FAILED] - No converted formats on volumes\n");
2501                 return WINED3DERR_NOTAVAILABLE;
2502             }
2503             break;
2504
2505             case WINED3DFMT_V8U8:
2506             if(!GL_SUPPORT(NV_TEXTURE_SHADER) || !GL_SUPPORT(ATI_ENVMAP_BUMPMAP)) {
2507                 TRACE_(d3d_caps)("[FAILED] - No converted formats on volumes\n");
2508                 return WINED3DERR_NOTAVAILABLE;
2509             }
2510             break;
2511
2512             case WINED3DFMT_DXT1:
2513             case WINED3DFMT_DXT2:
2514             case WINED3DFMT_DXT3:
2515             case WINED3DFMT_DXT4:
2516             case WINED3DFMT_DXT5:
2517                 /* The GL_EXT_texture_compression_s3tc spec requires that loading an s3tc
2518                  * compressed texture results in an error. While the D3D refrast does
2519                  * support s3tc volumes, at least the nvidia windows driver does not, so
2520                  * we're free not to support this format.
2521                  */
2522                 TRACE_(d3d_caps)("[FAILED] - DXTn does not support 3D textures\n");
2523                 return WINED3DERR_NOTAVAILABLE;
2524
2525             default:
2526                 /* Do nothing, continue with checking the format below */
2527                 break;
2528         }
2529     } else if((RType == WINED3DRTYPE_INDEXBUFFER) || (RType == WINED3DRTYPE_VERTEXBUFFER)){
2530         /* For instance vertexbuffer/indexbuffer aren't supported yet because no Windows drivers seem to offer it */
2531         TRACE_(d3d_caps)("Unhandled resource type D3DRTYPE_INDEXBUFFER / D3DRTYPE_VERTEXBUFFER\n");
2532         return WINED3DERR_NOTAVAILABLE;
2533      }
2534
2535     /* This format is nothing special and it is supported perfectly.
2536      * However, ati and nvidia driver on windows do not mark this format as
2537      * supported (tested with the dxCapsViewer) and pretending to
2538      * support this format uncovers a bug in Battlefield 1942 (fonts are missing)
2539      * So do the same as Windows drivers and pretend not to support it on dx8 and 9
2540      * Enable it on dx7. It will need additional checking on dx10 when we support it.
2541      */
2542     if(This->dxVersion > 7 && CheckFormat == WINED3DFMT_R8G8B8) {
2543         TRACE_(d3d_caps)("[FAILED]\n");
2544         return WINED3DERR_NOTAVAILABLE;
2545     }
2546
2547     switch (CheckFormat) {
2548
2549         /*****
2550          *  supported: RGB(A) formats
2551          */
2552         case WINED3DFMT_R8G8B8: /* Enable for dx7, blacklisted for 8 and 9 above */
2553         case WINED3DFMT_A8R8G8B8:
2554         case WINED3DFMT_X8R8G8B8:
2555         case WINED3DFMT_R5G6B5:
2556         case WINED3DFMT_X1R5G5B5:
2557         case WINED3DFMT_A1R5G5B5:
2558         case WINED3DFMT_A4R4G4B4:
2559         case WINED3DFMT_R3G3B2:
2560         case WINED3DFMT_A8:
2561         case WINED3DFMT_X4R4G4B4:
2562         case WINED3DFMT_A8B8G8R8:
2563         case WINED3DFMT_X8B8G8R8:
2564         case WINED3DFMT_A2R10G10B10:
2565         case WINED3DFMT_A2B10G10R10:
2566         case WINED3DFMT_G16R16:
2567             TRACE_(d3d_caps)("[OK]\n");
2568             return WINED3D_OK;
2569
2570         /*****
2571          *  supported: Palettized
2572          */
2573         case WINED3DFMT_P8:
2574             TRACE_(d3d_caps)("[OK]\n");
2575             return WINED3D_OK;
2576
2577         /*****
2578          *  Supported: (Alpha)-Luminance
2579          */
2580         case WINED3DFMT_L8:
2581         case WINED3DFMT_A8L8:
2582         case WINED3DFMT_A4L4:
2583             TRACE_(d3d_caps)("[OK]\n");
2584             return WINED3D_OK;
2585
2586         /*****
2587          *  Not supported everywhere(depends on GL_ATI_envmap_bumpmap or
2588          *  GL_NV_texture_shader), but advertized to make apps happy.
2589          *  Enable some because games often fail when they are not available
2590          *  and are still playable even without bump mapping
2591          */
2592         case WINED3DFMT_V8U8:
2593         case WINED3DFMT_V16U16:
2594         case WINED3DFMT_L6V5U5:
2595         case WINED3DFMT_X8L8V8U8:
2596         case WINED3DFMT_Q8W8V8U8:
2597             WARN_(d3d_caps)("[Not supported, but pretended to do]\n");
2598             return WINED3D_OK;
2599
2600         /* Those are not advertized by the nvidia windows driver, and not
2601          * supported natively by GL_NV_texture_shader or GL_ATI_envmap_bumpmap.
2602          * WINED3DFMT_A2W10V10U10 could be loaded into shaders using the unsigned
2603          * ARGB format if needed
2604          */
2605         case WINED3DFMT_W11V11U10:
2606         case WINED3DFMT_A2W10V10U10:
2607             WARN_(d3d_caps)("[FAILED]\n");
2608             return WINED3DERR_NOTAVAILABLE;
2609
2610         case WINED3DFMT_DXT1:
2611         case WINED3DFMT_DXT2:
2612         case WINED3DFMT_DXT3:
2613         case WINED3DFMT_DXT4:
2614         case WINED3DFMT_DXT5:
2615             if (GL_SUPPORT(EXT_TEXTURE_COMPRESSION_S3TC)) {
2616                 TRACE_(d3d_caps)("[OK]\n");
2617                 return WINED3D_OK;
2618             } else {
2619                 TRACE_(d3d_caps)("[FAILED]\n");
2620                 return WINED3DERR_NOTAVAILABLE;
2621             }
2622
2623
2624         /*****
2625          *  Odd formats - not supported
2626          */
2627         case WINED3DFMT_VERTEXDATA:
2628         case WINED3DFMT_INDEX16:
2629         case WINED3DFMT_INDEX32:
2630         case WINED3DFMT_Q16W16V16U16:
2631             TRACE_(d3d_caps)("[FAILED]\n"); /* Enable when implemented */
2632             return WINED3DERR_NOTAVAILABLE;
2633
2634         /*****
2635          *  WINED3DFMT_CxV8U8: Not supported right now
2636          */
2637         case WINED3DFMT_CxV8U8:
2638             TRACE_(d3d_caps)("[FAILED]\n"); /* Enable when implemented */
2639             return WINED3DERR_NOTAVAILABLE;
2640
2641             /* Not supported */
2642         case WINED3DFMT_A16B16G16R16:
2643         case WINED3DFMT_A8R3G3B2:
2644             TRACE_(d3d_caps)("[FAILED]\n"); /* Enable when implemented */
2645             return WINED3DERR_NOTAVAILABLE;
2646
2647             /* Floating point formats */
2648         case WINED3DFMT_R16F:
2649         case WINED3DFMT_A16B16G16R16F:
2650             if(GL_SUPPORT(ARB_HALF_FLOAT_PIXEL)) {
2651                 TRACE_(d3d_caps)("[OK]\n");
2652                 return WINED3D_OK;
2653             } else {
2654                 TRACE_(d3d_caps)("[FAILED]\n");
2655                 return WINED3DERR_NOTAVAILABLE;
2656             }
2657         case WINED3DFMT_R32F:
2658         case WINED3DFMT_A32B32G32R32F:
2659             if (GL_SUPPORT(ARB_TEXTURE_FLOAT)) {
2660                 TRACE_(d3d_caps)("[OK]\n");
2661                 return WINED3D_OK;
2662             } else {
2663                 TRACE_(d3d_caps)("[FAILED]\n");
2664                 return WINED3DERR_NOTAVAILABLE;
2665             }
2666
2667         case WINED3DFMT_G16R16F:
2668         case WINED3DFMT_G32R32F:
2669             TRACE_(d3d_caps)("[FAILED]\n");
2670             return WINED3DERR_NOTAVAILABLE;
2671
2672         /* ATI instancing hack: Although ATI cards do not support Shader Model 3.0, they support
2673          * instancing. To query if the card supports instancing CheckDeviceFormat with the special format
2674          * MAKEFOURCC('I','N','S','T') is used. Should a (broken) app check for this provide a proper return value.
2675          * We can do instancing with all shader versions, but we need vertex shaders.
2676          *
2677          * Additionally applications have to set the D3DRS_POINTSIZE render state to MAKEFOURCC('I','N','S','T') once
2678          * to enable instancing. WineD3D doesn't need that and just ignores it.
2679          *
2680          * With Shader Model 3.0 capable cards Instancing 'just works' in Windows.
2681          */
2682         case WINEMAKEFOURCC('I','N','S','T'):
2683             TRACE("ATI Instancing check hack\n");
2684             if(GL_SUPPORT(ARB_VERTEX_PROGRAM) || GL_SUPPORT(ARB_VERTEX_SHADER)) {
2685                 TRACE_(d3d_caps)("[OK]\n");
2686                 return WINED3D_OK;
2687             } else {
2688                 TRACE_(d3d_caps)("[FAILED]\n");
2689                 return WINED3DERR_NOTAVAILABLE;
2690             }
2691
2692         default:
2693             break;
2694     }
2695
2696     /* When the UsageCaps exactly matches Usage return WINED3D_OK except for the situation in which
2697      * WINED3DUSAGE_AUTOGENMIPMAP isn't around, then WINED3DOK_NOAUTOGEN is returned if all the other
2698      * usage flags match. */
2699     if(UsageCaps == Usage) {
2700         return WINED3D_OK;
2701     } else if((UsageCaps == (Usage & ~WINED3DUSAGE_AUTOGENMIPMAP)) && (Usage & WINED3DUSAGE_AUTOGENMIPMAP)){
2702         return WINED3DOK_NOAUTOGEN;
2703     } else {
2704         TRACE_(d3d_caps)("[FAILED] - Usage=%#08x requested but only %#08x is available\n", Usage, UsageCaps);
2705         return WINED3DERR_NOTAVAILABLE;
2706     }
2707 }
2708
2709 static HRESULT  WINAPI IWineD3DImpl_CheckDeviceFormatConversion(IWineD3D *iface, UINT Adapter, WINED3DDEVTYPE DeviceType,
2710                                                           WINED3DFORMAT SourceFormat, WINED3DFORMAT TargetFormat) {
2711     IWineD3DImpl *This = (IWineD3DImpl *)iface;
2712
2713     FIXME_(d3d_caps)("(%p)-> (STUB) (Adptr:%d, DevType:(%u,%s), SrcFmt:(%u,%s), TgtFmt:(%u,%s))\n",
2714           This,
2715           Adapter,
2716           DeviceType, debug_d3ddevicetype(DeviceType),
2717           SourceFormat, debug_d3dformat(SourceFormat),
2718           TargetFormat, debug_d3dformat(TargetFormat));
2719     return WINED3D_OK;
2720 }
2721
2722 /* Note: d3d8 passes in a pointer to a D3DCAPS8 structure, which is a true
2723       subset of a D3DCAPS9 structure. However, it has to come via a void *
2724       as the d3d8 interface cannot import the d3d9 header                  */
2725 static HRESULT WINAPI IWineD3DImpl_GetDeviceCaps(IWineD3D *iface, UINT Adapter, WINED3DDEVTYPE DeviceType, WINED3DCAPS* pCaps) {
2726
2727     IWineD3DImpl    *This = (IWineD3DImpl *)iface;
2728     int vs_selected_mode;
2729     int ps_selected_mode;
2730
2731     TRACE_(d3d_caps)("(%p)->(Adptr:%d, DevType: %x, pCaps: %p)\n", This, Adapter, DeviceType, pCaps);
2732
2733     if (Adapter >= IWineD3D_GetAdapterCount(iface)) {
2734         return WINED3DERR_INVALIDCALL;
2735     }
2736
2737     select_shader_mode(&Adapters[Adapter].gl_info, DeviceType, &ps_selected_mode, &vs_selected_mode);
2738
2739     /* This function should *not* be modifying GL caps
2740      * TODO: move the functionality where it belongs */
2741     select_shader_max_constants(ps_selected_mode, vs_selected_mode, &Adapters[Adapter].gl_info);
2742
2743     /* ------------------------------------------------
2744        The following fields apply to both d3d8 and d3d9
2745        ------------------------------------------------ */
2746     *pCaps->DeviceType              = (DeviceType == WINED3DDEVTYPE_HAL) ? WINED3DDEVTYPE_HAL : WINED3DDEVTYPE_REF;  /* Not quite true, but use h/w supported by opengl I suppose */
2747     *pCaps->AdapterOrdinal          = Adapter;
2748
2749     *pCaps->Caps                    = 0;
2750     *pCaps->Caps2                   = WINED3DCAPS2_CANRENDERWINDOWED |
2751                                       WINED3DCAPS2_FULLSCREENGAMMA |
2752                                       WINED3DCAPS2_DYNAMICTEXTURES;
2753     if(GL_SUPPORT(SGIS_GENERATE_MIPMAP)) {
2754         *pCaps->Caps2 |= WINED3DCAPS2_CANAUTOGENMIPMAP;
2755     }
2756     *pCaps->Caps3                   = WINED3DCAPS3_ALPHA_FULLSCREEN_FLIP_OR_DISCARD;
2757     *pCaps->PresentationIntervals   = WINED3DPRESENT_INTERVAL_IMMEDIATE  |
2758                                       WINED3DPRESENT_INTERVAL_ONE;
2759
2760     *pCaps->CursorCaps              = WINED3DCURSORCAPS_COLOR            |
2761                                       WINED3DCURSORCAPS_LOWRES;
2762
2763     *pCaps->DevCaps                 = WINED3DDEVCAPS_FLOATTLVERTEX       |
2764                                       WINED3DDEVCAPS_EXECUTESYSTEMMEMORY |
2765                                       WINED3DDEVCAPS_TLVERTEXSYSTEMMEMORY|
2766                                       WINED3DDEVCAPS_TLVERTEXVIDEOMEMORY |
2767                                       WINED3DDEVCAPS_DRAWPRIMTLVERTEX    |
2768                                       WINED3DDEVCAPS_HWTRANSFORMANDLIGHT |
2769                                       WINED3DDEVCAPS_EXECUTEVIDEOMEMORY  |
2770                                       WINED3DDEVCAPS_PUREDEVICE          |
2771                                       WINED3DDEVCAPS_HWRASTERIZATION     |
2772                                       WINED3DDEVCAPS_TEXTUREVIDEOMEMORY  |
2773                                       WINED3DDEVCAPS_TEXTURESYSTEMMEMORY |
2774                                       WINED3DDEVCAPS_CANRENDERAFTERFLIP  |
2775                                       WINED3DDEVCAPS_DRAWPRIMITIVES2     |
2776                                       WINED3DDEVCAPS_DRAWPRIMITIVES2EX   |
2777                                       WINED3DDEVCAPS_RTPATCHES;
2778
2779     *pCaps->PrimitiveMiscCaps       = WINED3DPMISCCAPS_CULLNONE              |
2780                                       WINED3DPMISCCAPS_CULLCCW               |
2781                                       WINED3DPMISCCAPS_CULLCW                |
2782                                       WINED3DPMISCCAPS_COLORWRITEENABLE      |
2783                                       WINED3DPMISCCAPS_CLIPTLVERTS           |
2784                                       WINED3DPMISCCAPS_CLIPPLANESCALEDPOINTS |
2785                                       WINED3DPMISCCAPS_MASKZ                 |
2786                                       WINED3DPMISCCAPS_BLENDOP;
2787                                     /* TODO:
2788                                         WINED3DPMISCCAPS_NULLREFERENCE
2789                                         WINED3DPMISCCAPS_INDEPENDENTWRITEMASKS
2790                                         WINED3DPMISCCAPS_FOGANDSPECULARALPHA
2791                                         WINED3DPMISCCAPS_MRTINDEPENDENTBITDEPTHS
2792                                         WINED3DPMISCCAPS_MRTPOSTPIXELSHADERBLENDING
2793                                         WINED3DPMISCCAPS_FOGVERTEXCLAMPED */
2794
2795     if(GL_SUPPORT(EXT_BLEND_EQUATION_SEPARATE) && GL_SUPPORT(EXT_BLEND_FUNC_SEPARATE))
2796         *pCaps->PrimitiveMiscCaps |= WINED3DPMISCCAPS_SEPARATEALPHABLEND;
2797
2798 /* The caps below can be supported but aren't handled yet in utils.c 'd3dta_to_combiner_input', disable them until support is fixed */
2799 #if 0
2800     if (GL_SUPPORT(NV_REGISTER_COMBINERS))
2801         *pCaps->PrimitiveMiscCaps |=  WINED3DPMISCCAPS_TSSARGTEMP;
2802     if (GL_SUPPORT(NV_REGISTER_COMBINERS2))
2803         *pCaps->PrimitiveMiscCaps |=  WINED3DPMISCCAPS_PERSTAGECONSTANT;
2804 #endif
2805
2806     *pCaps->RasterCaps              = WINED3DPRASTERCAPS_DITHER    |
2807                                       WINED3DPRASTERCAPS_PAT       |
2808                                       WINED3DPRASTERCAPS_WFOG      |
2809                                       WINED3DPRASTERCAPS_ZFOG      |
2810                                       WINED3DPRASTERCAPS_FOGVERTEX |
2811                                       WINED3DPRASTERCAPS_FOGTABLE  |
2812                                       WINED3DPRASTERCAPS_STIPPLE   |
2813                                       WINED3DPRASTERCAPS_SUBPIXEL  |
2814                                       WINED3DPRASTERCAPS_ZTEST     |
2815                                       WINED3DPRASTERCAPS_SCISSORTEST   |
2816                                       WINED3DPRASTERCAPS_SLOPESCALEDEPTHBIAS |
2817                                       WINED3DPRASTERCAPS_DEPTHBIAS;
2818
2819     if (GL_SUPPORT(EXT_TEXTURE_FILTER_ANISOTROPIC)) {
2820       *pCaps->RasterCaps |= WINED3DPRASTERCAPS_ANISOTROPY    |
2821                             WINED3DPRASTERCAPS_ZBIAS         |
2822                             WINED3DPRASTERCAPS_MIPMAPLODBIAS;
2823     }
2824     if(GL_SUPPORT(NV_FOG_DISTANCE)) {
2825         *pCaps->RasterCaps         |= WINED3DPRASTERCAPS_FOGRANGE;
2826     }
2827                         /* FIXME Add:
2828                            WINED3DPRASTERCAPS_COLORPERSPECTIVE
2829                            WINED3DPRASTERCAPS_STRETCHBLTMULTISAMPLE
2830                            WINED3DPRASTERCAPS_ANTIALIASEDGES
2831                            WINED3DPRASTERCAPS_ZBUFFERLESSHSR
2832                            WINED3DPRASTERCAPS_WBUFFER */
2833
2834     *pCaps->ZCmpCaps = WINED3DPCMPCAPS_ALWAYS       |
2835                        WINED3DPCMPCAPS_EQUAL        |
2836                        WINED3DPCMPCAPS_GREATER      |
2837                        WINED3DPCMPCAPS_GREATEREQUAL |
2838                        WINED3DPCMPCAPS_LESS         |
2839                        WINED3DPCMPCAPS_LESSEQUAL    |
2840                        WINED3DPCMPCAPS_NEVER        |
2841                        WINED3DPCMPCAPS_NOTEQUAL;
2842
2843     *pCaps->SrcBlendCaps  = WINED3DPBLENDCAPS_BOTHINVSRCALPHA |
2844                             WINED3DPBLENDCAPS_BOTHSRCALPHA    |
2845                             WINED3DPBLENDCAPS_DESTALPHA       |
2846                             WINED3DPBLENDCAPS_DESTCOLOR       |
2847                             WINED3DPBLENDCAPS_INVDESTALPHA    |
2848                             WINED3DPBLENDCAPS_INVDESTCOLOR    |
2849                             WINED3DPBLENDCAPS_INVSRCALPHA     |
2850                             WINED3DPBLENDCAPS_INVSRCCOLOR     |
2851                             WINED3DPBLENDCAPS_ONE             |
2852                             WINED3DPBLENDCAPS_SRCALPHA        |
2853                             WINED3DPBLENDCAPS_SRCALPHASAT     |
2854                             WINED3DPBLENDCAPS_SRCCOLOR        |
2855                             WINED3DPBLENDCAPS_ZERO;
2856
2857     *pCaps->DestBlendCaps = WINED3DPBLENDCAPS_DESTALPHA       |
2858                             WINED3DPBLENDCAPS_DESTCOLOR       |
2859                             WINED3DPBLENDCAPS_INVDESTALPHA    |
2860                             WINED3DPBLENDCAPS_INVDESTCOLOR    |
2861                             WINED3DPBLENDCAPS_INVSRCALPHA     |
2862                             WINED3DPBLENDCAPS_INVSRCCOLOR     |
2863                             WINED3DPBLENDCAPS_ONE             |
2864                             WINED3DPBLENDCAPS_SRCALPHA        |
2865                             WINED3DPBLENDCAPS_SRCCOLOR        |
2866                             WINED3DPBLENDCAPS_ZERO;
2867     /* NOTE: WINED3DPBLENDCAPS_SRCALPHASAT is not supported as dest blend factor,
2868      * according to the glBlendFunc manpage
2869      *
2870      * WINED3DPBLENDCAPS_BOTHINVSRCALPHA and WINED3DPBLENDCAPS_BOTHSRCALPHA are
2871      * legacy settings for srcblend only
2872      */
2873
2874     if( GL_SUPPORT(EXT_BLEND_COLOR)) {
2875         *pCaps->SrcBlendCaps |= WINED3DPBLENDCAPS_BLENDFACTOR;
2876         *pCaps->DestBlendCaps |= WINED3DPBLENDCAPS_BLENDFACTOR;
2877     }
2878
2879
2880     *pCaps->AlphaCmpCaps = WINED3DPCMPCAPS_ALWAYS       |
2881                            WINED3DPCMPCAPS_EQUAL        |
2882                            WINED3DPCMPCAPS_GREATER      |
2883                            WINED3DPCMPCAPS_GREATEREQUAL |
2884                            WINED3DPCMPCAPS_LESS         |
2885                            WINED3DPCMPCAPS_LESSEQUAL    |
2886                            WINED3DPCMPCAPS_NEVER        |
2887                            WINED3DPCMPCAPS_NOTEQUAL;
2888
2889     *pCaps->ShadeCaps     = WINED3DPSHADECAPS_SPECULARGOURAUDRGB |
2890                             WINED3DPSHADECAPS_COLORGOURAUDRGB    |
2891                             WINED3DPSHADECAPS_ALPHAFLATBLEND     |
2892                             WINED3DPSHADECAPS_ALPHAGOURAUDBLEND  |
2893                             WINED3DPSHADECAPS_COLORFLATRGB       |
2894                             WINED3DPSHADECAPS_FOGFLAT            |
2895                             WINED3DPSHADECAPS_FOGGOURAUD         |
2896                             WINED3DPSHADECAPS_SPECULARFLATRGB;
2897
2898     *pCaps->TextureCaps =  WINED3DPTEXTURECAPS_ALPHA              |
2899                            WINED3DPTEXTURECAPS_ALPHAPALETTE       |
2900                            WINED3DPTEXTURECAPS_BORDER             |
2901                            WINED3DPTEXTURECAPS_MIPMAP             |
2902                            WINED3DPTEXTURECAPS_PROJECTED          |
2903                            WINED3DPTEXTURECAPS_PERSPECTIVE;
2904
2905     if( !GL_SUPPORT(ARB_TEXTURE_NON_POWER_OF_TWO)) {
2906         *pCaps->TextureCaps |= WINED3DPTEXTURECAPS_POW2 |
2907                                 WINED3DPTEXTURECAPS_NONPOW2CONDITIONAL;
2908     }
2909
2910     if( GL_SUPPORT(EXT_TEXTURE3D)) {
2911         *pCaps->TextureCaps |=  WINED3DPTEXTURECAPS_VOLUMEMAP      |
2912                                 WINED3DPTEXTURECAPS_MIPVOLUMEMAP   |
2913                                 WINED3DPTEXTURECAPS_VOLUMEMAP_POW2;
2914     }
2915
2916     if (GL_SUPPORT(ARB_TEXTURE_CUBE_MAP)) {
2917         *pCaps->TextureCaps |= WINED3DPTEXTURECAPS_CUBEMAP     |
2918                              WINED3DPTEXTURECAPS_MIPCUBEMAP    |
2919                              WINED3DPTEXTURECAPS_CUBEMAP_POW2;
2920
2921     }
2922
2923     *pCaps->TextureFilterCaps = WINED3DPTFILTERCAPS_MAGFLINEAR       |
2924                                 WINED3DPTFILTERCAPS_MAGFPOINT        |
2925                                 WINED3DPTFILTERCAPS_MINFLINEAR       |
2926                                 WINED3DPTFILTERCAPS_MINFPOINT        |
2927                                 WINED3DPTFILTERCAPS_MIPFLINEAR       |
2928                                 WINED3DPTFILTERCAPS_MIPFPOINT        |
2929                                 WINED3DPTFILTERCAPS_LINEAR           |
2930                                 WINED3DPTFILTERCAPS_LINEARMIPLINEAR  |
2931                                 WINED3DPTFILTERCAPS_LINEARMIPNEAREST |
2932                                 WINED3DPTFILTERCAPS_MIPLINEAR        |
2933                                 WINED3DPTFILTERCAPS_MIPNEAREST       |
2934                                 WINED3DPTFILTERCAPS_NEAREST;
2935
2936     if (GL_SUPPORT(EXT_TEXTURE_FILTER_ANISOTROPIC)) {
2937         *pCaps->TextureFilterCaps |= WINED3DPTFILTERCAPS_MAGFANISOTROPIC |
2938                                      WINED3DPTFILTERCAPS_MINFANISOTROPIC;
2939     }
2940
2941     if (GL_SUPPORT(ARB_TEXTURE_CUBE_MAP)) {
2942         *pCaps->CubeTextureFilterCaps = WINED3DPTFILTERCAPS_MAGFLINEAR       |
2943                                         WINED3DPTFILTERCAPS_MAGFPOINT        |
2944                                         WINED3DPTFILTERCAPS_MINFLINEAR       |
2945                                         WINED3DPTFILTERCAPS_MINFPOINT        |
2946                                         WINED3DPTFILTERCAPS_MIPFLINEAR       |
2947                                         WINED3DPTFILTERCAPS_MIPFPOINT        |
2948                                         WINED3DPTFILTERCAPS_LINEAR           |
2949                                         WINED3DPTFILTERCAPS_LINEARMIPLINEAR  |
2950                                         WINED3DPTFILTERCAPS_LINEARMIPNEAREST |
2951                                         WINED3DPTFILTERCAPS_MIPLINEAR        |
2952                                         WINED3DPTFILTERCAPS_MIPNEAREST       |
2953                                         WINED3DPTFILTERCAPS_NEAREST;
2954
2955         if (GL_SUPPORT(EXT_TEXTURE_FILTER_ANISOTROPIC)) {
2956             *pCaps->CubeTextureFilterCaps |= WINED3DPTFILTERCAPS_MAGFANISOTROPIC |
2957                                             WINED3DPTFILTERCAPS_MINFANISOTROPIC;
2958         }
2959     } else
2960         *pCaps->CubeTextureFilterCaps = 0;
2961
2962     if (GL_SUPPORT(EXT_TEXTURE3D)) {
2963         *pCaps->VolumeTextureFilterCaps = WINED3DPTFILTERCAPS_MAGFLINEAR       |
2964                                           WINED3DPTFILTERCAPS_MAGFPOINT        |
2965                                           WINED3DPTFILTERCAPS_MINFLINEAR       |
2966                                           WINED3DPTFILTERCAPS_MINFPOINT        |
2967                                           WINED3DPTFILTERCAPS_MIPFLINEAR       |
2968                                           WINED3DPTFILTERCAPS_MIPFPOINT        |
2969                                           WINED3DPTFILTERCAPS_LINEAR           |
2970                                           WINED3DPTFILTERCAPS_LINEARMIPLINEAR  |
2971                                           WINED3DPTFILTERCAPS_LINEARMIPNEAREST |
2972                                           WINED3DPTFILTERCAPS_MIPLINEAR        |
2973                                           WINED3DPTFILTERCAPS_MIPNEAREST       |
2974                                           WINED3DPTFILTERCAPS_NEAREST;
2975     } else
2976         *pCaps->VolumeTextureFilterCaps = 0;
2977
2978     *pCaps->TextureAddressCaps =  WINED3DPTADDRESSCAPS_INDEPENDENTUV |
2979                                   WINED3DPTADDRESSCAPS_CLAMP  |
2980                                   WINED3DPTADDRESSCAPS_WRAP;
2981
2982     if (GL_SUPPORT(ARB_TEXTURE_BORDER_CLAMP)) {
2983         *pCaps->TextureAddressCaps |= WINED3DPTADDRESSCAPS_BORDER;
2984     }
2985     if (GL_SUPPORT(ARB_TEXTURE_MIRRORED_REPEAT)) {
2986         *pCaps->TextureAddressCaps |= WINED3DPTADDRESSCAPS_MIRROR;
2987     }
2988     if (GL_SUPPORT(ATI_TEXTURE_MIRROR_ONCE)) {
2989         *pCaps->TextureAddressCaps |= WINED3DPTADDRESSCAPS_MIRRORONCE;
2990     }
2991
2992     if (GL_SUPPORT(EXT_TEXTURE3D)) {
2993         *pCaps->VolumeTextureAddressCaps =  WINED3DPTADDRESSCAPS_INDEPENDENTUV |
2994                                             WINED3DPTADDRESSCAPS_CLAMP  |
2995                                             WINED3DPTADDRESSCAPS_WRAP;
2996         if (GL_SUPPORT(ARB_TEXTURE_BORDER_CLAMP)) {
2997             *pCaps->VolumeTextureAddressCaps |= WINED3DPTADDRESSCAPS_BORDER;
2998         }
2999         if (GL_SUPPORT(ARB_TEXTURE_MIRRORED_REPEAT)) {
3000             *pCaps->VolumeTextureAddressCaps |= WINED3DPTADDRESSCAPS_MIRROR;
3001         }
3002         if (GL_SUPPORT(ATI_TEXTURE_MIRROR_ONCE)) {
3003             *pCaps->VolumeTextureAddressCaps |= WINED3DPTADDRESSCAPS_MIRRORONCE;
3004         }
3005     } else
3006         *pCaps->VolumeTextureAddressCaps = 0;
3007
3008     *pCaps->LineCaps = WINED3DLINECAPS_TEXTURE |
3009                        WINED3DLINECAPS_ZTEST;
3010                       /* FIXME: Add
3011                         WINED3DLINECAPS_BLEND
3012                         WINED3DLINECAPS_ALPHACMP
3013                         WINED3DLINECAPS_FOG */
3014
3015     *pCaps->MaxTextureWidth  = GL_LIMITS(texture_size);
3016     *pCaps->MaxTextureHeight = GL_LIMITS(texture_size);
3017
3018     if(GL_SUPPORT(EXT_TEXTURE3D))
3019         *pCaps->MaxVolumeExtent = GL_LIMITS(texture3d_size);
3020     else
3021         *pCaps->MaxVolumeExtent = 0;
3022
3023     *pCaps->MaxTextureRepeat = 32768;
3024     *pCaps->MaxTextureAspectRatio = GL_LIMITS(texture_size);
3025     *pCaps->MaxVertexW = 1.0;
3026
3027     *pCaps->GuardBandLeft = 0;
3028     *pCaps->GuardBandTop = 0;
3029     *pCaps->GuardBandRight = 0;
3030     *pCaps->GuardBandBottom = 0;
3031
3032     *pCaps->ExtentsAdjust = 0;
3033
3034     *pCaps->StencilCaps =  WINED3DSTENCILCAPS_DECRSAT |
3035                            WINED3DSTENCILCAPS_INCRSAT |
3036                            WINED3DSTENCILCAPS_INVERT  |
3037                            WINED3DSTENCILCAPS_KEEP    |
3038                            WINED3DSTENCILCAPS_REPLACE |
3039                            WINED3DSTENCILCAPS_ZERO;
3040     if (GL_SUPPORT(EXT_STENCIL_WRAP)) {
3041       *pCaps->StencilCaps |= WINED3DSTENCILCAPS_DECR  |
3042                              WINED3DSTENCILCAPS_INCR;
3043     }
3044     if ( This->dxVersion > 8 &&
3045         ( GL_SUPPORT(EXT_STENCIL_TWO_SIDE) ||
3046             GL_SUPPORT(ATI_SEPARATE_STENCIL) ) ) {
3047         *pCaps->StencilCaps |= WINED3DSTENCILCAPS_TWOSIDED;
3048     }
3049
3050     *pCaps->FVFCaps = WINED3DFVFCAPS_PSIZE | 0x0008; /* 8 texture coords */
3051
3052     *pCaps->TextureOpCaps =  WINED3DTEXOPCAPS_ADD         |
3053                              WINED3DTEXOPCAPS_ADDSIGNED   |
3054                              WINED3DTEXOPCAPS_ADDSIGNED2X |
3055                              WINED3DTEXOPCAPS_MODULATE    |
3056                              WINED3DTEXOPCAPS_MODULATE2X  |
3057                              WINED3DTEXOPCAPS_MODULATE4X  |
3058                              WINED3DTEXOPCAPS_SELECTARG1  |
3059                              WINED3DTEXOPCAPS_SELECTARG2  |
3060                              WINED3DTEXOPCAPS_DISABLE;
3061
3062     if (GL_SUPPORT(ARB_TEXTURE_ENV_COMBINE) ||
3063         GL_SUPPORT(EXT_TEXTURE_ENV_COMBINE) ||
3064         GL_SUPPORT(NV_TEXTURE_ENV_COMBINE4)) {
3065         *pCaps->TextureOpCaps |= WINED3DTEXOPCAPS_BLENDDIFFUSEALPHA |
3066                                 WINED3DTEXOPCAPS_BLENDTEXTUREALPHA  |
3067                                 WINED3DTEXOPCAPS_BLENDFACTORALPHA   |
3068                                 WINED3DTEXOPCAPS_BLENDCURRENTALPHA  |
3069                                 WINED3DTEXOPCAPS_LERP               |
3070                                 WINED3DTEXOPCAPS_SUBTRACT;
3071     }
3072     if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3) ||
3073          GL_SUPPORT(NV_TEXTURE_ENV_COMBINE4)) {
3074         *pCaps->TextureOpCaps |= WINED3DTEXOPCAPS_ADDSMOOTH             |
3075                                 WINED3DTEXOPCAPS_MULTIPLYADD            |
3076                                 WINED3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR |
3077                                 WINED3DTEXOPCAPS_MODULATECOLOR_ADDALPHA |
3078                                 WINED3DTEXOPCAPS_BLENDTEXTUREALPHAPM;
3079     }
3080     if (GL_SUPPORT(ARB_TEXTURE_ENV_DOT3))
3081         *pCaps->TextureOpCaps |= WINED3DTEXOPCAPS_DOTPRODUCT3;
3082
3083     if (GL_SUPPORT(NV_REGISTER_COMBINERS)) {
3084         *pCaps->TextureOpCaps |= WINED3DTEXOPCAPS_MODULATEINVALPHA_ADDCOLOR |
3085                                  WINED3DTEXOPCAPS_MODULATEINVCOLOR_ADDALPHA;
3086     }
3087
3088     if(GL_SUPPORT(ATI_ENVMAP_BUMPMAP)) {
3089         *pCaps->TextureOpCaps |= WINED3DTEXOPCAPS_BUMPENVMAP;
3090     } else if(GL_SUPPORT(NV_TEXTURE_SHADER2)) {
3091         /* Bump mapping is supported already in NV_TEXTURE_SHADER, but that extension does
3092          * not support 3D textures. This asks for trouble if an app uses both bump mapping
3093          * and 3D textures. It also allows us to keep the code simpler by having texture
3094          * shaders constantly enabled.
3095          */
3096         *pCaps->TextureOpCaps |= WINED3DTEXOPCAPS_BUMPENVMAP;
3097         /* TODO: Luminance bump map? */
3098     }
3099 #if 0
3100     /* FIXME: Add
3101     *pCaps->TextureOpCaps |= WINED3DTEXOPCAPS_BUMPENVMAPLUMINANCE
3102                              WINED3DTEXOPCAPS_PREMODULATE */
3103 #endif
3104
3105     *pCaps->MaxTextureBlendStages   = GL_LIMITS(texture_stages);
3106     *pCaps->MaxSimultaneousTextures = GL_LIMITS(textures);
3107     *pCaps->MaxUserClipPlanes       = GL_LIMITS(clipplanes);
3108     *pCaps->MaxActiveLights         = GL_LIMITS(lights);
3109
3110     *pCaps->MaxVertexBlendMatrices      = GL_LIMITS(blends);
3111     *pCaps->MaxVertexBlendMatrixIndex   = 0;
3112
3113     *pCaps->MaxAnisotropy   = GL_LIMITS(anisotropy);
3114     *pCaps->MaxPointSize    = GL_LIMITS(pointsize);
3115
3116
3117     *pCaps->VertexProcessingCaps = WINED3DVTXPCAPS_DIRECTIONALLIGHTS |
3118                                    WINED3DVTXPCAPS_MATERIALSOURCE7   |
3119                                    WINED3DVTXPCAPS_POSITIONALLIGHTS  |
3120                                    WINED3DVTXPCAPS_LOCALVIEWER       |
3121                                    WINED3DVTXPCAPS_VERTEXFOG         |
3122                                    WINED3DVTXPCAPS_TEXGEN;
3123                                   /* FIXME: Add 
3124                                      D3DVTXPCAPS_TWEENING, D3DVTXPCAPS_TEXGEN_SPHEREMAP */
3125
3126     *pCaps->MaxPrimitiveCount   = 0xFFFFF; /* For now set 2^20-1 which is used by most >=Geforce3/Radeon8500 cards */
3127     *pCaps->MaxVertexIndex      = 0xFFFFF;
3128     *pCaps->MaxStreams          = MAX_STREAMS;
3129     *pCaps->MaxStreamStride     = 1024;
3130
3131     if (vs_selected_mode == SHADER_GLSL) {
3132         /* Nvidia Geforce6/7 or Ati R4xx/R5xx cards with GLSL support, support VS 3.0 but older Nvidia/Ati
3133          * models with GLSL support only support 2.0. In case of nvidia we can detect VS 2.0 support using
3134          * vs_nv_version which is based on NV_vertex_program.
3135          * For Ati cards there's no way using glsl (it abstracts the lowlevel info away) and also not
3136          * using ARB_vertex_program. It is safe to assume that when a card supports pixel shader 2.0 it
3137          * supports vertex shader 2.0 too and the way around. We can detect ps2.0 using the maximum number
3138          * of native instructions, so use that here. For more info see the pixel shader versioning code below. */
3139         if((GLINFO_LOCATION.vs_nv_version == VS_VERSION_20) || (GLINFO_LOCATION.ps_arb_max_instructions <= 512))
3140             *pCaps->VertexShaderVersion = WINED3DVS_VERSION(2,0);
3141         else
3142             *pCaps->VertexShaderVersion = WINED3DVS_VERSION(3,0);
3143         TRACE_(d3d_caps)("Hardware vertex shader version %d.%d enabled (GLSL)\n", (*pCaps->VertexShaderVersion >> 8) & 0xff, *pCaps->VertexShaderVersion & 0xff);
3144     } else if (vs_selected_mode == SHADER_ARB) {
3145         *pCaps->VertexShaderVersion = WINED3DVS_VERSION(1,1);
3146         TRACE_(d3d_caps)("Hardware vertex shader version 1.1 enabled (ARB_PROGRAM)\n");
3147     } else {
3148         *pCaps->VertexShaderVersion  = 0;
3149         TRACE_(d3d_caps)("Vertex shader functionality not available\n");
3150     }
3151
3152     *pCaps->MaxVertexShaderConst = GL_LIMITS(vshader_constantsF);
3153
3154     if (ps_selected_mode == SHADER_GLSL) {
3155         /* Older DX9-class videocards (GeforceFX / Radeon >9500/X*00) only support pixel shader 2.0/2.0a/2.0b.
3156          * In OpenGL the extensions related to GLSL abstract lowlevel GL info away which is needed
3157          * to distinguish between 2.0 and 3.0 (and 2.0a/2.0b). In case of Nvidia we use their fragment
3158          * program extensions. On other hardware including ATI GL_ARB_fragment_program offers the info
3159          * in max native instructions. Intel and others also offer the info in this extension but they
3160          * don't support GLSL (at least on Windows).
3161          *
3162          * PS2.0 requires at least 96 instructions, 2.0a/2.0b go up to 512. Assume that if the number
3163          * of instructions is 512 or less we have to do with ps2.0 hardware.
3164          * 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.
3165          */
3166         if((GLINFO_LOCATION.ps_nv_version == PS_VERSION_20) || (GLINFO_LOCATION.ps_arb_max_instructions <= 512))
3167             *pCaps->PixelShaderVersion = WINED3DPS_VERSION(2,0);
3168         else
3169             *pCaps->PixelShaderVersion = WINED3DPS_VERSION(3,0);
3170         /* FIXME: The following line is card dependent. -8.0 to 8.0 is the
3171          * Direct3D minimum requirement.
3172          *
3173          * Both GL_ARB_fragment_program and GLSL require a "maximum representable magnitude"
3174          * of colors to be 2^10, and 2^32 for other floats. Should we use 1024 here?
3175          *
3176          * The problem is that the refrast clamps temporary results in the shader to
3177          * [-MaxValue;+MaxValue]. If the card's max value is bigger than the one we advertize here,
3178          * then applications may miss the clamping behavior. On the other hand, if it is smaller,
3179          * the shader will generate incorrect results too. Unfortunately, GL deliberately doesn't
3180          * offer a way to query this.
3181          */
3182         *pCaps->PixelShader1xMaxValue = 8.0;
3183         TRACE_(d3d_caps)("Hardware pixel shader version %d.%d enabled (GLSL)\n", (*pCaps->PixelShaderVersion >> 8) & 0xff, *pCaps->PixelShaderVersion & 0xff);
3184     } else if (ps_selected_mode == SHADER_ARB) {
3185         *pCaps->PixelShaderVersion    = WINED3DPS_VERSION(1,4);
3186         *pCaps->PixelShader1xMaxValue = 8.0;
3187         TRACE_(d3d_caps)("Hardware pixel shader version 1.4 enabled (ARB_PROGRAM)\n");
3188     } else {
3189         *pCaps->PixelShaderVersion    = 0;
3190         *pCaps->PixelShader1xMaxValue = 0.0;
3191         TRACE_(d3d_caps)("Pixel shader functionality not available\n");
3192     }
3193
3194     /* ------------------------------------------------
3195        The following fields apply to d3d9 only
3196        ------------------------------------------------ */
3197     if (This->dxVersion > 8) {
3198         /* d3d9.dll sets D3DDEVCAPS2_CAN_STRETCHRECT_FROM_TEXTURES here because StretchRects is implemented in d3d9 */
3199         *pCaps->DevCaps2                          = WINED3DDEVCAPS2_STREAMOFFSET;
3200         /* TODO: VS3.0 needs at least D3DDEVCAPS2_VERTEXELEMENTSCANSHARESTREAMOFFSET */
3201         *pCaps->MaxNpatchTessellationLevel        = 0;
3202         *pCaps->MasterAdapterOrdinal              = 0;
3203         *pCaps->AdapterOrdinalInGroup             = 0;
3204         *pCaps->NumberOfAdaptersInGroup           = 1;
3205
3206         if(*pCaps->VertexShaderVersion >= WINED3DVS_VERSION(2,0)) {
3207             /* OpenGL supports all the formats below, perhaps not always
3208              * without conversion, but it supports them.
3209              * Further GLSL doesn't seem to have an official unsigned type so
3210              * don't advertise it yet as I'm not sure how we handle it.
3211              * We might need to add some clamping in the shader engine to
3212              * support it.
3213              * TODO: WINED3DDTCAPS_USHORT2N, WINED3DDTCAPS_USHORT4N, WINED3DDTCAPS_UDEC3, WINED3DDTCAPS_DEC3N */
3214             *pCaps->DeclTypes = WINED3DDTCAPS_UBYTE4    |
3215                                 WINED3DDTCAPS_UBYTE4N   |
3216                                 WINED3DDTCAPS_SHORT2N   |
3217                                 WINED3DDTCAPS_SHORT4N;
3218             if (GL_SUPPORT(NV_HALF_FLOAT)) {
3219                 *pCaps->DeclTypes |=
3220                                 WINED3DDTCAPS_FLOAT16_2 |
3221                                 WINED3DDTCAPS_FLOAT16_4;
3222             }
3223         } else
3224             *pCaps->DeclTypes                         = 0;
3225
3226         *pCaps->NumSimultaneousRTs = GL_LIMITS(buffers);
3227
3228             
3229         *pCaps->StretchRectFilterCaps             = WINED3DPTFILTERCAPS_MINFPOINT  |
3230                                                     WINED3DPTFILTERCAPS_MAGFPOINT  |
3231                                                     WINED3DPTFILTERCAPS_MINFLINEAR |
3232                                                     WINED3DPTFILTERCAPS_MAGFLINEAR;
3233         *pCaps->VertexTextureFilterCaps           = 0;
3234         
3235         if(*pCaps->VertexShaderVersion == WINED3DVS_VERSION(3,0)) {
3236             /* Where possible set the caps based on OpenGL extensions and if they aren't set (in case of software rendering)
3237                use the VS 3.0 from MSDN or else if there's OpenGL spec use a hardcoded value minimum VS3.0 value. */
3238             *pCaps->VS20Caps.Caps                     = WINED3DVS20CAPS_PREDICATION;
3239             *pCaps->VS20Caps.DynamicFlowControlDepth  = WINED3DVS20_MAX_DYNAMICFLOWCONTROLDEPTH; /* VS 3.0 requires MAX_DYNAMICFLOWCONTROLDEPTH (24) */
3240             *pCaps->VS20Caps.NumTemps                 = max(32, GLINFO_LOCATION.vs_arb_max_temps);
3241             *pCaps->VS20Caps.StaticFlowControlDepth   = WINED3DVS20_MAX_STATICFLOWCONTROLDEPTH ; /* level of nesting in loops / if-statements; VS 3.0 requires MAX (4) */
3242
3243             *pCaps->MaxVShaderInstructionsExecuted    = 65535; /* VS 3.0 needs at least 65535, some cards even use 2^32-1 */
3244             *pCaps->MaxVertexShader30InstructionSlots = max(512, GLINFO_LOCATION.vs_arb_max_instructions);
3245         } else if(*pCaps->VertexShaderVersion == WINED3DVS_VERSION(2,0)) {
3246             *pCaps->VS20Caps.Caps                     = 0;
3247             *pCaps->VS20Caps.DynamicFlowControlDepth  = WINED3DVS20_MIN_DYNAMICFLOWCONTROLDEPTH;
3248             *pCaps->VS20Caps.NumTemps                 = max(12, GLINFO_LOCATION.vs_arb_max_temps);
3249             *pCaps->VS20Caps.StaticFlowControlDepth   = 1;    
3250
3251             *pCaps->MaxVShaderInstructionsExecuted    = 65535;
3252             *pCaps->MaxVertexShader30InstructionSlots = 0;
3253         } else { /* VS 1.x */
3254             *pCaps->VS20Caps.Caps                     = 0;
3255             *pCaps->VS20Caps.DynamicFlowControlDepth  = 0;
3256             *pCaps->VS20Caps.NumTemps                 = 0;
3257             *pCaps->VS20Caps.StaticFlowControlDepth   = 0;    
3258
3259             *pCaps->MaxVShaderInstructionsExecuted    = 0;
3260             *pCaps->MaxVertexShader30InstructionSlots = 0;        
3261         }
3262
3263         if(*pCaps->PixelShaderVersion == WINED3DPS_VERSION(3,0)) {
3264             /* Where possible set the caps based on OpenGL extensions and if they aren't set (in case of software rendering)
3265                use the PS 3.0 from MSDN or else if there's OpenGL spec use a hardcoded value minimum PS 3.0 value. */
3266             
3267             /* 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 */
3268             *pCaps->PS20Caps.Caps                     = WINED3DPS20CAPS_ARBITRARYSWIZZLE     |
3269                                                         WINED3DPS20CAPS_GRADIENTINSTRUCTIONS |
3270                                                         WINED3DPS20CAPS_PREDICATION          |
3271                                                         WINED3DPS20CAPS_NODEPENDENTREADLIMIT |
3272                                                         WINED3DPS20CAPS_NOTEXINSTRUCTIONLIMIT;
3273             *pCaps->PS20Caps.DynamicFlowControlDepth  = WINED3DPS20_MAX_DYNAMICFLOWCONTROLDEPTH; /* PS 3.0 requires MAX_DYNAMICFLOWCONTROLDEPTH (24) */
3274             *pCaps->PS20Caps.NumTemps                 = max(32, GLINFO_LOCATION.ps_arb_max_temps);
3275             *pCaps->PS20Caps.StaticFlowControlDepth   = WINED3DPS20_MAX_STATICFLOWCONTROLDEPTH; /* PS 3.0 requires MAX_STATICFLOWCONTROLDEPTH (4) */
3276             *pCaps->PS20Caps.NumInstructionSlots      = WINED3DPS20_MAX_NUMINSTRUCTIONSLOTS; /* PS 3.0 requires MAX_NUMINSTRUCTIONSLOTS (512) */
3277
3278             *pCaps->MaxPShaderInstructionsExecuted    = 65535;
3279             *pCaps->MaxPixelShader30InstructionSlots  = max(WINED3DMIN30SHADERINSTRUCTIONS, GLINFO_LOCATION.ps_arb_max_instructions);
3280         } else if(*pCaps->PixelShaderVersion == WINED3DPS_VERSION(2,0)) {
3281             /* Below we assume PS2.0 specs, not extended 2.0a(GeforceFX)/2.0b(Radeon R3xx) ones */
3282             *pCaps->PS20Caps.Caps                     = 0;
3283             *pCaps->PS20Caps.DynamicFlowControlDepth  = 0; /* WINED3DVS20_MIN_DYNAMICFLOWCONTROLDEPTH = 0 */
3284             *pCaps->PS20Caps.NumTemps                 = max(12, GLINFO_LOCATION.ps_arb_max_temps);
3285             *pCaps->PS20Caps.StaticFlowControlDepth   = WINED3DPS20_MIN_STATICFLOWCONTROLDEPTH; /* Minimum: 1 */
3286             *pCaps->PS20Caps.NumInstructionSlots      = WINED3DPS20_MIN_NUMINSTRUCTIONSLOTS; /* Minimum number (64 ALU + 32 Texture), a GeforceFX uses 512 */
3287
3288             *pCaps->MaxPShaderInstructionsExecuted    = 512; /* Minimum value, a GeforceFX uses 1024 */
3289             *pCaps->MaxPixelShader30InstructionSlots  = 0;
3290         } else { /* PS 1.x */
3291             *pCaps->PS20Caps.Caps                     = 0;
3292             *pCaps->PS20Caps.DynamicFlowControlDepth  = 0;
3293             *pCaps->PS20Caps.NumTemps                 = 0;
3294             *pCaps->PS20Caps.StaticFlowControlDepth   = 0;
3295             *pCaps->PS20Caps.NumInstructionSlots      = 0;
3296
3297             *pCaps->MaxPShaderInstructionsExecuted    = 0;
3298             *pCaps->MaxPixelShader30InstructionSlots  = 0;
3299         }
3300     }
3301
3302     return WINED3D_OK;
3303 }
3304
3305 static unsigned int glsl_program_key_hash(void *key) {
3306     glsl_program_key_t *k = (glsl_program_key_t *)key;
3307
3308     unsigned int hash = k->vshader | k->pshader << 16;
3309     hash += ~(hash << 15);
3310     hash ^=  (hash >> 10);
3311     hash +=  (hash << 3);
3312     hash ^=  (hash >> 6);
3313     hash += ~(hash << 11);
3314     hash ^=  (hash >> 16);
3315
3316     return hash;
3317 }
3318
3319 static BOOL glsl_program_key_compare(void *keya, void *keyb) {
3320     glsl_program_key_t *ka = (glsl_program_key_t *)keya;
3321     glsl_program_key_t *kb = (glsl_program_key_t *)keyb;
3322
3323     return ka->vshader == kb->vshader && ka->pshader == kb->pshader;
3324 }
3325
3326 /* Note due to structure differences between dx8 and dx9 D3DPRESENT_PARAMETERS,
3327    and fields being inserted in the middle, a new structure is used in place    */
3328 static HRESULT  WINAPI IWineD3DImpl_CreateDevice(IWineD3D *iface, UINT Adapter, WINED3DDEVTYPE DeviceType, HWND hFocusWindow,
3329                                            DWORD BehaviourFlags, IWineD3DDevice** ppReturnedDeviceInterface,
3330                                            IUnknown *parent) {
3331
3332     IWineD3DDeviceImpl *object  = NULL;
3333     IWineD3DImpl       *This    = (IWineD3DImpl *)iface;
3334     WINED3DDISPLAYMODE  mode;
3335     int i;
3336
3337     /* Validate the adapter number. If no adapters are available(no GL), ignore the adapter
3338      * number and create a device without a 3D adapter for 2D only operation.
3339      */
3340     if (IWineD3D_GetAdapterCount(iface) && Adapter >= IWineD3D_GetAdapterCount(iface)) {
3341         return WINED3DERR_INVALIDCALL;
3342     }
3343
3344     /* Create a WineD3DDevice object */
3345     object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IWineD3DDeviceImpl));
3346     *ppReturnedDeviceInterface = (IWineD3DDevice *)object;
3347     TRACE("Created WineD3DDevice object @ %p\n", object);
3348     if (NULL == object) {
3349       return WINED3DERR_OUTOFVIDEOMEMORY;
3350     }
3351
3352     /* Set up initial COM information */
3353     object->lpVtbl  = &IWineD3DDevice_Vtbl;
3354     object->ref     = 1;
3355     object->wineD3D = iface;
3356     object->adapter = numAdapters ? &Adapters[Adapter] : NULL;
3357     IWineD3D_AddRef(object->wineD3D);
3358     object->parent  = parent;
3359     list_init(&object->resources);
3360     list_init(&object->shaders);
3361
3362     if(This->dxVersion == 7) {
3363         object->surface_alignment = 8;
3364     } else {
3365         object->surface_alignment = 4;
3366     }
3367     object->posFixup[0] = 1.0; /* This is needed to get the x coord unmodified through a MAD */
3368
3369     /* Set the state up as invalid until the device is fully created */
3370     object->state   = WINED3DERR_DRIVERINTERNALERROR;
3371
3372     TRACE("(%p)->(Adptr:%d, DevType: %x, FocusHwnd: %p, BehFlags: %x, RetDevInt: %p)\n", This, Adapter, DeviceType,
3373           hFocusWindow, BehaviourFlags, ppReturnedDeviceInterface);
3374
3375     /* Save the creation parameters */
3376     object->createParms.AdapterOrdinal = Adapter;
3377     object->createParms.DeviceType     = DeviceType;
3378     object->createParms.hFocusWindow   = hFocusWindow;
3379     object->createParms.BehaviorFlags  = BehaviourFlags;
3380
3381     /* Initialize other useful values */
3382     object->adapterNo                    = Adapter;
3383     object->devType                      = DeviceType;
3384
3385     select_shader_mode(&GLINFO_LOCATION, DeviceType, &object->ps_selected_mode, &object->vs_selected_mode);
3386     if (object->ps_selected_mode == SHADER_GLSL || object->vs_selected_mode == SHADER_GLSL) {
3387         object->shader_backend = &glsl_shader_backend;
3388         object->glsl_program_lookup = hash_table_create(&glsl_program_key_hash, &glsl_program_key_compare);
3389     } else if (object->ps_selected_mode == SHADER_ARB || object->vs_selected_mode == SHADER_ARB) {
3390         object->shader_backend = &arb_program_shader_backend;
3391     } else {
3392         object->shader_backend = &none_shader_backend;
3393     }
3394     if(FAILED(object->shader_backend->shader_alloc_private((IWineD3DDevice *) object))) {
3395         IWineD3D_Release(object->wineD3D);
3396         HeapFree(GetProcessHeap(), 0, object);
3397         *ppReturnedDeviceInterface = NULL;
3398         return E_OUTOFMEMORY;
3399     }
3400
3401     /* Prefer the vtable with functions optimized for single dirtifyable objects if the shader
3402      * model can deal with that. It is essentially the same, just with adjusted
3403      * Set*ShaderConstantF implementations
3404      */
3405     if(object->shader_backend->shader_dirtifyable_constants((IWineD3DDevice *) object)) {
3406         object->lpVtbl  = &IWineD3DDevice_DirtyConst_Vtbl;
3407     }
3408
3409     /* set the state of the device to valid */
3410     object->state = WINED3D_OK;
3411
3412     /* Get the initial screen setup for ddraw */
3413     IWineD3DImpl_GetAdapterDisplayMode(iface, Adapter, &mode);
3414
3415     object->ddraw_width = mode.Width;
3416     object->ddraw_height = mode.Height;
3417     object->ddraw_format = mode.Format;
3418
3419     for(i = 0; i < PATCHMAP_SIZE; i++) {
3420         list_init(&object->patches[i]);
3421     }
3422     return WINED3D_OK;
3423 }
3424 #undef GLINFO_LOCATION
3425
3426 static HRESULT WINAPI IWineD3DImpl_GetParent(IWineD3D *iface, IUnknown **pParent) {
3427     IWineD3DImpl *This = (IWineD3DImpl *)iface;
3428     IUnknown_AddRef(This->parent);
3429     *pParent = This->parent;
3430     return WINED3D_OK;
3431 }
3432
3433 ULONG WINAPI D3DCB_DefaultDestroySurface(IWineD3DSurface *pSurface) {
3434     IUnknown* surfaceParent;
3435     TRACE("(%p) call back\n", pSurface);
3436
3437     /* Now, release the parent, which will take care of cleaning up the surface for us */
3438     IWineD3DSurface_GetParent(pSurface, &surfaceParent);
3439     IUnknown_Release(surfaceParent);
3440     return IUnknown_Release(surfaceParent);
3441 }
3442
3443 ULONG WINAPI D3DCB_DefaultDestroyVolume(IWineD3DVolume *pVolume) {
3444     IUnknown* volumeParent;
3445     TRACE("(%p) call back\n", pVolume);
3446
3447     /* Now, release the parent, which will take care of cleaning up the volume for us */
3448     IWineD3DVolume_GetParent(pVolume, &volumeParent);
3449     IUnknown_Release(volumeParent);
3450     return IUnknown_Release(volumeParent);
3451 }
3452
3453 static BOOL implementation_is_apple(WineD3D_GL_Info *gl_info) {
3454     /* MacOS has various specialities in the extensions it advertises. Some have to be loaded from
3455      * the opengl 1.2+ core, while other extensions are advertised, but software emulated. So try to
3456      * detect the Apple OpenGL implementation to apply some extension fixups afterwards.
3457      *
3458      * Detecting this isn't really easy. The vendor string doesn't mention Apple. Compile-time checks
3459      * aren't sufficient either because a Linux binary may display on a macos X server via remote X11.
3460      * So try to detect the GL implementation by looking at certain Apple extensions. Some extensions
3461      * like client storage might be supported on other implementations too, but GL_APPLE_flush_render
3462      * is specific to the Mac OS X window management, and GL_APPLE_ycbcr_422 is QuickTime specific. So
3463      * the chance that other implementations support them is rather small since Win32 QuickTime uses
3464      * DirectDraw, not OpenGL.
3465      */
3466     if(gl_info->supported[APPLE_FENCE] &&
3467        gl_info->supported[APPLE_CLIENT_STORAGE] &&
3468        gl_info->supported[APPLE_FLUSH_RENDER] &&
3469        gl_info->supported[APPLE_YCBCR_422]) {
3470         TRACE_(d3d_caps)("GL_APPLE_fence, GL_APPLE_client_storage, GL_APPLE_flush_render and GL_ycbcr_422 are supported\n");
3471         TRACE_(d3d_caps)("Activating MacOS fixups\n");
3472         return TRUE;
3473     } else {
3474         TRACE_(d3d_caps)("Apple extensions are not supported\n");
3475         TRACE_(d3d_caps)("Not activating MacOS fixups\n");
3476         return FALSE;
3477     }
3478 }
3479
3480 #define GLINFO_LOCATION (*gl_info)
3481 static void test_pbo_functionality(WineD3D_GL_Info *gl_info) {
3482     /* Some OpenGL implementations, namely Apple's Geforce 8 driver, advertises PBOs,
3483      * but glTexSubImage from a PBO fails miserably, with the first line repeated over
3484      * all the texture. This function detects this bug by its symptom and disables PBOs
3485      * if the test fails.
3486      *
3487      * The test uplaods a 4x4 texture via the PBO in the "native" format GL_BGRA,
3488      * GL_UNSIGNED_INT_8_8_8_8_REV. This format triggers the bug, and it is what we use
3489      * for D3DFMT_A8R8G8B8. Then the texture is read back without any PBO and the data
3490      * read back is compared to the original. If they are equal PBOs are assumed to work,
3491      * otherwise the PBO extension is disabled.
3492      */
3493     GLuint texture, pbo;
3494     static const unsigned int pattern[] = {
3495         0x00000000, 0x000000ff, 0x0000ff00, 0x40ff0000,
3496         0x80ffffff, 0x40ffff00, 0x00ff00ff, 0x0000ffff,
3497         0x00ffff00, 0x00ff00ff, 0x0000ffff, 0x000000ff,
3498         0x80ff00ff, 0x0000ffff, 0x00ff00ff, 0x40ff00ff
3499     };
3500     unsigned int check[sizeof(pattern) / sizeof(pattern[0])];
3501
3502     if(!gl_info->supported[ARB_PIXEL_BUFFER_OBJECT]) {
3503         /* No PBO -> No point in testing them */
3504         return;
3505     }
3506
3507     while(glGetError());
3508     glGenTextures(1, &texture);
3509     glBindTexture(GL_TEXTURE_2D, texture);
3510     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 4, 4, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, 0);
3511     checkGLcall("Specifying the PBO test texture\n");
3512
3513     GL_EXTCALL(glGenBuffersARB(1, &pbo));
3514     GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, pbo));
3515     GL_EXTCALL(glBufferDataARB(GL_PIXEL_UNPACK_BUFFER_ARB, sizeof(pattern), pattern, GL_STREAM_DRAW_ARB));
3516     checkGLcall("Specifying the PBO test pbo\n");
3517
3518     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 4, 4, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL);
3519     checkGLcall("Loading the PBO test texture\n");
3520
3521     GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0));
3522     glFinish(); /* just to be sure */
3523
3524     memset(check, 0, sizeof(check));
3525     glGetTexImage(GL_TEXTURE_2D, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, check);
3526     checkGLcall("Reading back the PBO test texture\n");
3527
3528     glDeleteTextures(1, &texture);
3529     GL_EXTCALL(glDeleteBuffersARB(1, &pbo));
3530     checkGLcall("PBO test cleanup\n");
3531
3532     if(memcmp(check, pattern, sizeof(check)) != 0) {
3533         WARN_(d3d_caps)("PBO test failed, read back data doesn't match original\n");
3534         WARN_(d3d_caps)("Disabling PBOs. This may result in slower performance\n");
3535         gl_info->supported[ARB_PIXEL_BUFFER_OBJECT] = FALSE;
3536     } else {
3537         TRACE_(d3d_caps)("PBO test successful\n");
3538     }
3539 }
3540 #undef GLINFO_LOCATION
3541
3542 /* Certain applications(Steam) complain if we report an outdated driver version. In general,
3543  * reporting a driver version is moot because we are not the Windows driver, and we have different
3544  * bugs, features, etc.
3545  *
3546  * If a card is not found in this table, the gl driver version is reported
3547  */
3548 struct driver_version_information {
3549     WORD vendor;                        /* reported PCI card vendor ID  */
3550     WORD card;                          /* reported PCI card device ID  */
3551     WORD hipart_hi, hipart_lo;          /* driver hiword to report      */
3552     WORD lopart_hi, lopart_lo;          /* driver loword to report      */
3553 };
3554
3555 static const struct driver_version_information driver_version_table[] = {
3556     /* Nvidia drivers. Geforce FX and newer cards are supported by the current driver */
3557     {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCEFX_5200,     7,  15, 10, 16921   },
3558     {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCEFX_5600,     7,  15, 10, 16921   },
3559     {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCEFX_5800,     7,  15, 10, 16921   },
3560     {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_6200,       7,  15, 10, 16921   },
3561     {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_6600GT,     7,  15, 10, 16921   },
3562     {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_6800,       7,  15, 10, 16921   },
3563     {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_7400,       7,  15, 10, 16921   },
3564     {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_7300,       7,  15, 10, 16921   },
3565     {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_7600,       7,  15, 10, 16921   },
3566     {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_7800GT,     7,  15, 10, 16921   },
3567     {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_8300GS,     7,  15, 10, 16921   },
3568     {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_8600GT,     7,  15, 10, 16921   },
3569     {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_8600MGT,    7,  15, 10, 16921   },
3570     {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_8800GTS,    7,  15, 10, 16921   },
3571
3572     /* ATI cards. The driver versions are somewhat similar, but not quite the same. Let's hardcode */
3573     {VENDOR_ATI,        CARD_ATI_RADEON_9500,           6,  14, 10, 6764    },
3574     {VENDOR_ATI,        CARD_ATI_RADEON_X700,           6,  14, 10, 6764    },
3575     {VENDOR_ATI,        CARD_ATI_RADEON_X1600,          6,  14, 10, 6764    },
3576     {VENDOR_ATI,        CARD_ATI_RADEON_HD2300,         6,  14, 10, 6764    },
3577     {VENDOR_ATI,        CARD_ATI_RADEON_HD2600,         6,  14, 10, 6764    },
3578     {VENDOR_ATI,        CARD_ATI_RADEON_HD2900,         6,  14, 10, 6764    },
3579
3580     /* TODO: Add information about legacy nvidia and ATI hardware, Intel and other cards */
3581 };
3582
3583 static void fixup_extensions(WineD3D_GL_Info *gl_info) {
3584     unsigned int i;
3585     BOOL apple = implementation_is_apple(gl_info);
3586
3587     if(apple) {
3588         /* MacOS advertises more GLSL vertex shader uniforms than supported by the hardware, and if more are
3589          * used it falls back to software. While the compiler can detect if the shader uses all declared
3590          * uniforms, the optimization fails if the shader uses relative addressing. So any GLSL shader
3591          * using relative addressing falls back to software.
3592          *
3593          * ARB vp gives the correct amount of uniforms, so use it instead of GLSL
3594          */
3595         if(gl_info->vs_glsl_constantsF <= gl_info->vs_arb_constantsF) {
3596             FIXME("GLSL doesn't advertise more vertex shader uniforms than ARB. Driver fixup outdated?\n");
3597         } else {
3598             TRACE("Driver claims %u GLSL vs uniforms, replacing with %u ARB vp uniforms\n",
3599                   gl_info->vs_glsl_constantsF, gl_info->vs_arb_constantsF);
3600             gl_info->vs_glsl_constantsF = gl_info->vs_arb_constantsF;
3601         }
3602
3603         /* MacOS advertises GL_ARB_texture_non_power_of_two on ATI r500 and earlier cards, although
3604          * these cards only support GL_ARB_texture_rectangle(D3DPTEXTURECAPS_NONPOW2CONDITIONAL).
3605          * If real NP2 textures are used, the driver falls back to software. So remove the supported
3606          * flag for this extension
3607          */
3608         if(gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO] && gl_info->gl_vendor == VENDOR_ATI) {
3609             if(gl_info->gl_card == CARD_ATI_RADEON_X700 || gl_info->gl_card == CARD_ATI_RADEON_X1600 ||
3610                gl_info->gl_card == CARD_ATI_RADEON_9500 || gl_info->gl_card == CARD_ATI_RADEON_8500  ||
3611                gl_info->gl_card == CARD_ATI_RADEON_7200 || gl_info->gl_card == CARD_ATI_RAGE_128PRO) {
3612                 TRACE("GL_ARB_texture_non_power_of_two advertised on R500 or earlier card, removing\n");
3613                 gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO] = FALSE;
3614                 gl_info->supported[ARB_TEXTURE_RECTANGLE] = TRUE;
3615             }
3616         }
3617
3618         /* The Intel GPUs on MacOS set the .w register of texcoords to 0.0 by default, which causes problems
3619          * with fixed function fragment processing. Ideally this flag should be detected with a test shader
3620          * and OpenGL feedback mode, but some GL implementations (MacOS ATI at least, probably all MacOS ones)
3621          * do not like vertex shaders in feedback mode and return an error, even though it should be valid
3622          * according to the spec.
3623          *
3624          * We don't want to enable this on all cards, as it adds an extra instruction per texcoord used. This
3625          * makes the shader slower and eats instruction slots which should be available to the d3d app.
3626          *
3627          * ATI Radeon HD 2xxx cards on MacOS have the issue. Instead of checking for the buggy cards, blacklist
3628          * all radeon cards on Macs and whitelist the good ones. That way we're prepared for the future. If
3629          * this workaround is activated on cards that do not need it, it won't break things, just affect
3630          * performance negatively.
3631          */
3632         if(gl_info->gl_vendor == VENDOR_INTEL ||
3633            (gl_info->gl_vendor == VENDOR_ATI && gl_info->gl_card != CARD_ATI_RADEON_X1600)) {
3634             TRACE("Enabling vertex texture coord fixes in vertex shaders\n");
3635             gl_info->set_texcoord_w = TRUE;
3636         }
3637     }
3638
3639     /* Find out if PBOs work as they are supposed to */
3640     test_pbo_functionality(gl_info);
3641
3642     /* Fixup the driver version */
3643     for(i = 0; i < (sizeof(driver_version_table) / sizeof(driver_version_table[0])); i++) {
3644         if(gl_info->gl_vendor == driver_version_table[i].vendor &&
3645            gl_info->gl_card   == driver_version_table[i].card) {
3646             TRACE_(d3d_caps)("Found card 0x%04x, 0x%04x in driver version DB\n", gl_info->gl_vendor, gl_info->gl_card);
3647
3648             gl_info->driver_version        = MAKEDWORD_VERSION(driver_version_table[i].lopart_hi,
3649                                                                driver_version_table[i].lopart_lo);
3650             gl_info->driver_version_hipart = MAKEDWORD_VERSION(driver_version_table[i].hipart_hi,
3651                                                                driver_version_table[i].hipart_lo);
3652             break;
3653         }
3654     }
3655 }
3656
3657 void invalid_func(void *data) {
3658     ERR("Invalid vertex attribute function called\n");
3659     DebugBreak();
3660 }
3661
3662 #define GLINFO_LOCATION (Adapters[0].gl_info)
3663
3664 /* Helper functions for providing vertex data to opengl. The arrays are initialized based on
3665  * the extension detection and are used in drawStridedSlow
3666  */
3667 static void position_d3dcolor(void *data) {
3668     DWORD pos = *((DWORD *) data);
3669
3670     FIXME("Add a test for fixed function position from d3dcolor type\n");
3671     glVertex4s(D3DCOLOR_B_R(pos),
3672                D3DCOLOR_B_G(pos),
3673                D3DCOLOR_B_B(pos),
3674                D3DCOLOR_B_A(pos));
3675 }
3676 static void position_float4(void *data) {
3677     GLfloat *pos = (float *) data;
3678
3679     if (pos[3] < eps && pos[3] > -eps)
3680         glVertex3fv(pos);
3681     else {
3682         float w = 1.0 / pos[3];
3683
3684         glVertex4f(pos[0] * w, pos[1] * w, pos[2] * w, w);
3685     }
3686 }
3687
3688 static void diffuse_d3dcolor(void *data) {
3689     DWORD diffuseColor = *((DWORD *) data);
3690
3691     glColor4ub(D3DCOLOR_B_R(diffuseColor),
3692                D3DCOLOR_B_G(diffuseColor),
3693                D3DCOLOR_B_B(diffuseColor),
3694                D3DCOLOR_B_A(diffuseColor));
3695 }
3696
3697 static void specular_d3dcolor(void *data) {
3698     DWORD specularColor = *((DWORD *) data);
3699
3700     GL_EXTCALL(glSecondaryColor3ubEXT)(D3DCOLOR_B_R(specularColor),
3701                                        D3DCOLOR_B_G(specularColor),
3702                                        D3DCOLOR_B_B(specularColor));
3703 }
3704 static void warn_no_specular_func(void *data) {
3705     WARN("GL_EXT_secondary_color not supported\n");
3706 }
3707
3708 void fillGLAttribFuncs(WineD3D_GL_Info *gl_info) {
3709     position_funcs[WINED3DDECLTYPE_FLOAT1]      = (void *) invalid_func;
3710     position_funcs[WINED3DDECLTYPE_FLOAT2]      = (void *) invalid_func;
3711     position_funcs[WINED3DDECLTYPE_FLOAT3]      = (void *) glVertex3fv;
3712     position_funcs[WINED3DDECLTYPE_FLOAT4]      = (void *) position_float4;
3713     position_funcs[WINED3DDECLTYPE_D3DCOLOR]    = (void *) position_d3dcolor;
3714     position_funcs[WINED3DDECLTYPE_UBYTE4]      = (void *) invalid_func;
3715     position_funcs[WINED3DDECLTYPE_SHORT2]      = (void *) invalid_func;
3716     position_funcs[WINED3DDECLTYPE_SHORT4]      = (void *) glVertex2sv;
3717     position_funcs[WINED3DDECLTYPE_UBYTE4N]     = (void *) invalid_func;
3718     position_funcs[WINED3DDECLTYPE_SHORT2N]     = (void *) invalid_func;
3719     position_funcs[WINED3DDECLTYPE_SHORT4N]     = (void *) invalid_func;
3720     position_funcs[WINED3DDECLTYPE_USHORT2N]    = (void *) invalid_func;
3721     position_funcs[WINED3DDECLTYPE_USHORT4N]    = (void *) invalid_func;
3722     position_funcs[WINED3DDECLTYPE_UDEC3]       = (void *) invalid_func;
3723     position_funcs[WINED3DDECLTYPE_DEC3N]       = (void *) invalid_func;
3724     position_funcs[WINED3DDECLTYPE_FLOAT16_2]   = (void *) invalid_func;
3725     position_funcs[WINED3DDECLTYPE_FLOAT16_4]   = (void *) invalid_func;
3726
3727     diffuse_funcs[WINED3DDECLTYPE_FLOAT1]       = (void *) invalid_func;
3728     diffuse_funcs[WINED3DDECLTYPE_FLOAT2]       = (void *) invalid_func;
3729     diffuse_funcs[WINED3DDECLTYPE_FLOAT3]       = (void *) glColor3fv;
3730     diffuse_funcs[WINED3DDECLTYPE_FLOAT4]       = (void *) glColor4fv;
3731     diffuse_funcs[WINED3DDECLTYPE_D3DCOLOR]     = (void *) diffuse_d3dcolor;
3732     diffuse_funcs[WINED3DDECLTYPE_UBYTE4]       = (void *) invalid_func;
3733     diffuse_funcs[WINED3DDECLTYPE_SHORT2]       = (void *) invalid_func;
3734     diffuse_funcs[WINED3DDECLTYPE_SHORT4]       = (void *) invalid_func;
3735     diffuse_funcs[WINED3DDECLTYPE_UBYTE4N]      = (void *) glColor4ubv;
3736     diffuse_funcs[WINED3DDECLTYPE_SHORT2N]      = (void *) invalid_func;
3737     diffuse_funcs[WINED3DDECLTYPE_SHORT4N]      = (void *) glColor4sv;
3738     diffuse_funcs[WINED3DDECLTYPE_USHORT2N]     = (void *) invalid_func;
3739     diffuse_funcs[WINED3DDECLTYPE_USHORT4N]     = (void *) glColor4usv;
3740     diffuse_funcs[WINED3DDECLTYPE_UDEC3]        = (void *) invalid_func;
3741     diffuse_funcs[WINED3DDECLTYPE_DEC3N]        = (void *) invalid_func;
3742     diffuse_funcs[WINED3DDECLTYPE_FLOAT16_2]    = (void *) invalid_func;
3743     diffuse_funcs[WINED3DDECLTYPE_FLOAT16_4]    = (void *) invalid_func;
3744
3745     /* No 4 component entry points here */
3746     specular_funcs[WINED3DDECLTYPE_FLOAT1]      = (void *) invalid_func;
3747     specular_funcs[WINED3DDECLTYPE_FLOAT2]      = (void *) invalid_func;
3748     if(GL_SUPPORT(EXT_SECONDARY_COLOR)) {
3749         specular_funcs[WINED3DDECLTYPE_FLOAT3]      = (void *) GL_EXTCALL(glSecondaryColor3fvEXT);
3750     } else {
3751         specular_funcs[WINED3DDECLTYPE_FLOAT3]      = (void *) warn_no_specular_func;
3752     }
3753     specular_funcs[WINED3DDECLTYPE_FLOAT4]      = (void *) invalid_func;
3754     if(GL_SUPPORT(EXT_SECONDARY_COLOR)) {
3755         specular_funcs[WINED3DDECLTYPE_D3DCOLOR]    = (void *) specular_d3dcolor;
3756     } else {
3757         specular_funcs[WINED3DDECLTYPE_D3DCOLOR]      = (void *) warn_no_specular_func;
3758     }
3759     specular_funcs[WINED3DDECLTYPE_UBYTE4]      = (void *) invalid_func;
3760     specular_funcs[WINED3DDECLTYPE_SHORT2]      = (void *) invalid_func;
3761     specular_funcs[WINED3DDECLTYPE_SHORT4]      = (void *) invalid_func;
3762     specular_funcs[WINED3DDECLTYPE_UBYTE4N]     = (void *) invalid_func;
3763     specular_funcs[WINED3DDECLTYPE_SHORT2N]     = (void *) invalid_func;
3764     specular_funcs[WINED3DDECLTYPE_SHORT4N]     = (void *) invalid_func;
3765     specular_funcs[WINED3DDECLTYPE_USHORT2N]    = (void *) invalid_func;
3766     specular_funcs[WINED3DDECLTYPE_USHORT4N]    = (void *) invalid_func;
3767     specular_funcs[WINED3DDECLTYPE_UDEC3]       = (void *) invalid_func;
3768     specular_funcs[WINED3DDECLTYPE_DEC3N]       = (void *) invalid_func;
3769     specular_funcs[WINED3DDECLTYPE_FLOAT16_2]   = (void *) invalid_func;
3770     specular_funcs[WINED3DDECLTYPE_FLOAT16_4]   = (void *) invalid_func;
3771
3772     /* Only 3 component entry points here. Test how others behave. Float4 normals are used
3773      * by one of our tests, trying to pass it to the pixel shader, which fails on Windows.
3774      */
3775     normal_funcs[WINED3DDECLTYPE_FLOAT1]         = (void *) invalid_func;
3776     normal_funcs[WINED3DDECLTYPE_FLOAT2]         = (void *) invalid_func;
3777     normal_funcs[WINED3DDECLTYPE_FLOAT3]         = (void *) glNormal3fv;
3778     normal_funcs[WINED3DDECLTYPE_FLOAT4]         = (void *) glNormal3fv; /* Just ignore the 4th value */
3779     normal_funcs[WINED3DDECLTYPE_D3DCOLOR]       = (void *) invalid_func;
3780     normal_funcs[WINED3DDECLTYPE_UBYTE4]         = (void *) invalid_func;
3781     normal_funcs[WINED3DDECLTYPE_SHORT2]         = (void *) invalid_func;
3782     normal_funcs[WINED3DDECLTYPE_SHORT4]         = (void *) invalid_func;
3783     normal_funcs[WINED3DDECLTYPE_UBYTE4N]        = (void *) invalid_func;
3784     normal_funcs[WINED3DDECLTYPE_SHORT2N]        = (void *) invalid_func;
3785     normal_funcs[WINED3DDECLTYPE_SHORT4N]        = (void *) invalid_func;
3786     normal_funcs[WINED3DDECLTYPE_USHORT2N]       = (void *) invalid_func;
3787     normal_funcs[WINED3DDECLTYPE_USHORT4N]       = (void *) invalid_func;
3788     normal_funcs[WINED3DDECLTYPE_UDEC3]          = (void *) invalid_func;
3789     normal_funcs[WINED3DDECLTYPE_DEC3N]          = (void *) invalid_func;
3790     normal_funcs[WINED3DDECLTYPE_FLOAT16_2]      = (void *) invalid_func;
3791     normal_funcs[WINED3DDECLTYPE_FLOAT16_4]      = (void *) invalid_func;
3792 }
3793
3794 #define PUSH1(att)        attribs[nAttribs++] = (att);
3795 BOOL InitAdapters(void) {
3796     static HMODULE mod_gl;
3797     BOOL ret;
3798     int ps_selected_mode, vs_selected_mode;
3799
3800     /* No need to hold any lock. The calling library makes sure only one thread calls
3801      * wined3d simultaneously
3802      */
3803     if(numAdapters > 0) return TRUE;
3804
3805     TRACE("Initializing adapters\n");
3806
3807     if(!mod_gl) {
3808 #ifdef USE_WIN32_OPENGL
3809 #define USE_GL_FUNC(pfn) pfn = (void*)GetProcAddress(mod_gl, #pfn);
3810         mod_gl = LoadLibraryA("opengl32.dll");
3811         if(!mod_gl) {
3812             ERR("Can't load opengl32.dll!\n");
3813             return FALSE;
3814         }
3815 #else
3816 #define USE_GL_FUNC(pfn) pfn = (void*)pwglGetProcAddress(#pfn);
3817         /* To bypass the opengl32 thunks load wglGetProcAddress from gdi32 (glXGetProcAddress wrapper) instead of opengl32's */
3818         mod_gl = GetModuleHandleA("gdi32.dll");
3819 #endif
3820     }
3821
3822 /* Load WGL core functions from opengl32.dll */
3823 #define USE_WGL_FUNC(pfn) p##pfn = (void*)GetProcAddress(mod_gl, #pfn);
3824     WGL_FUNCS_GEN;
3825 #undef USE_WGL_FUNC
3826
3827     if(!pwglGetProcAddress) {
3828         ERR("Unable to load wglGetProcAddress!\n");
3829         return FALSE;
3830     }
3831
3832 /* Dynamically load all GL core functions */
3833     GL_FUNCS_GEN;
3834 #undef USE_GL_FUNC
3835
3836     /* For now only one default adapter */
3837     {
3838         int iPixelFormat;
3839         int attribs[8];
3840         int values[8];
3841         int nAttribs = 0;
3842         int res;
3843         WineD3D_PixelFormat *cfgs;
3844         int attribute;
3845         DISPLAY_DEVICEW DisplayDevice;
3846         HDC hdc;
3847
3848         TRACE("Initializing default adapter\n");
3849         Adapters[0].num = 0;
3850         Adapters[0].monitorPoint.x = -1;
3851         Adapters[0].monitorPoint.y = -1;
3852
3853         if (!WineD3D_CreateFakeGLContext()) {
3854             ERR("Failed to get a gl context for default adapter\n");
3855             HeapFree(GetProcessHeap(), 0, Adapters);
3856             WineD3D_ReleaseFakeGLContext();
3857             return FALSE;
3858         }
3859
3860         ret = IWineD3DImpl_FillGLCaps(&Adapters[0].gl_info);
3861         if(!ret) {
3862             ERR("Failed to initialize gl caps for default adapter\n");
3863             HeapFree(GetProcessHeap(), 0, Adapters);
3864             WineD3D_ReleaseFakeGLContext();
3865             return FALSE;
3866         }
3867         ret = initPixelFormats(&Adapters[0].gl_info);
3868         if(!ret) {
3869             ERR("Failed to init gl formats\n");
3870             HeapFree(GetProcessHeap(), 0, Adapters);
3871             WineD3D_ReleaseFakeGLContext();
3872             return FALSE;
3873         }
3874
3875         hdc = pwglGetCurrentDC();
3876         if(!hdc) {
3877             ERR("Failed to get gl HDC\n");
3878             HeapFree(GetProcessHeap(), 0, Adapters);
3879             WineD3D_ReleaseFakeGLContext();
3880             return FALSE;
3881         }
3882
3883         Adapters[0].driver = "Display";
3884         Adapters[0].description = "Direct3D HAL";
3885
3886         /* Use the VideoRamSize registry setting when set */
3887         if(wined3d_settings.emulated_textureram)
3888             Adapters[0].TextureRam = wined3d_settings.emulated_textureram;
3889         else
3890             Adapters[0].TextureRam = Adapters[0].gl_info.vidmem;
3891         Adapters[0].UsedTextureRam = 0;
3892         TRACE("Emulating %dMB of texture ram\n", Adapters[0].TextureRam/(1024*1024));
3893
3894         /* Initialize the Adapter's DeviceName which is required for ChangeDisplaySettings and friends */
3895         DisplayDevice.cb = sizeof(DisplayDevice);
3896         EnumDisplayDevicesW(NULL, 0 /* Adapter 0 = iDevNum 0 */, &DisplayDevice, 0);
3897         TRACE("DeviceName: %s\n", debugstr_w(DisplayDevice.DeviceName));
3898         strcpyW(Adapters[0].DeviceName, DisplayDevice.DeviceName);
3899
3900         attribute = WGL_NUMBER_PIXEL_FORMATS_ARB;
3901         GL_EXTCALL(wglGetPixelFormatAttribivARB(hdc, 0, 0, 1, &attribute, &Adapters[0].nCfgs));
3902
3903         Adapters[0].cfgs = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, Adapters[0].nCfgs *sizeof(WineD3D_PixelFormat));
3904         cfgs = Adapters[0].cfgs;
3905         PUSH1(WGL_RED_BITS_ARB)
3906         PUSH1(WGL_GREEN_BITS_ARB)
3907         PUSH1(WGL_BLUE_BITS_ARB)
3908         PUSH1(WGL_ALPHA_BITS_ARB)
3909         PUSH1(WGL_DEPTH_BITS_ARB)
3910         PUSH1(WGL_STENCIL_BITS_ARB)
3911         PUSH1(WGL_DRAW_TO_WINDOW_ARB)
3912         PUSH1(WGL_PIXEL_TYPE_ARB)
3913
3914         for(iPixelFormat=1; iPixelFormat<=Adapters[0].nCfgs; iPixelFormat++) {
3915             res = GL_EXTCALL(wglGetPixelFormatAttribivARB(hdc, iPixelFormat, 0, nAttribs, attribs, values));
3916
3917             if(!res)
3918                 continue;
3919
3920             /* Cache the pixel format */
3921             cfgs->iPixelFormat = iPixelFormat;
3922             cfgs->redSize = values[0];
3923             cfgs->greenSize = values[1];
3924             cfgs->blueSize = values[2];
3925             cfgs->alphaSize = values[3];
3926             cfgs->depthSize = values[4];
3927             cfgs->stencilSize = values[5];
3928             cfgs->windowDrawable = values[6];
3929             cfgs->iPixelType = values[7];
3930
3931             cfgs->pbufferDrawable = FALSE;
3932             /* Check for pbuffer support when it is around as wglGetPixelFormatAttribiv fails for unknown
3933 attributes. */
3934             if(GL_SUPPORT(WGL_ARB_PBUFFER)) {
3935                 int attrib = WGL_DRAW_TO_PBUFFER_ARB;
3936                 int value;
3937                 if(GL_EXTCALL(wglGetPixelFormatAttribivARB(hdc, iPixelFormat, 0, 1, &attrib, &value)))
3938                     cfgs->pbufferDrawable = value;
3939             }
3940
3941             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);
3942             cfgs++;
3943         }
3944
3945         fixup_extensions(&Adapters[0].gl_info);
3946
3947         WineD3D_ReleaseFakeGLContext();
3948
3949         select_shader_mode(&Adapters[0].gl_info, WINED3DDEVTYPE_HAL, &ps_selected_mode, &vs_selected_mode);
3950         select_shader_max_constants(ps_selected_mode, vs_selected_mode, &Adapters[0].gl_info);
3951         fillGLAttribFuncs(&Adapters[0].gl_info);
3952         init_type_lookup(&Adapters[0].gl_info);
3953     }
3954     numAdapters = 1;
3955     TRACE("%d adapters successfully initialized\n", numAdapters);
3956
3957     return TRUE;
3958 }
3959 #undef PUSH1
3960 #undef GLINFO_LOCATION
3961
3962 /**********************************************************
3963  * IWineD3D VTbl follows
3964  **********************************************************/
3965
3966 const IWineD3DVtbl IWineD3D_Vtbl =
3967 {
3968     /* IUnknown */
3969     IWineD3DImpl_QueryInterface,
3970     IWineD3DImpl_AddRef,
3971     IWineD3DImpl_Release,
3972     /* IWineD3D */
3973     IWineD3DImpl_GetParent,
3974     IWineD3DImpl_GetAdapterCount,
3975     IWineD3DImpl_RegisterSoftwareDevice,
3976     IWineD3DImpl_GetAdapterMonitor,
3977     IWineD3DImpl_GetAdapterModeCount,
3978     IWineD3DImpl_EnumAdapterModes,
3979     IWineD3DImpl_GetAdapterDisplayMode,
3980     IWineD3DImpl_GetAdapterIdentifier,
3981     IWineD3DImpl_CheckDeviceMultiSampleType,
3982     IWineD3DImpl_CheckDepthStencilMatch,
3983     IWineD3DImpl_CheckDeviceType,
3984     IWineD3DImpl_CheckDeviceFormat,
3985     IWineD3DImpl_CheckDeviceFormatConversion,
3986     IWineD3DImpl_GetDeviceCaps,
3987     IWineD3DImpl_CreateDevice
3988 };