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