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