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