wined3d: Support bump environment mapping using GL_NV_texture_shader.
[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                 /* Prevent both extensions to be used at the same time. I don't expect them to play nice together */
766                 gl_info->supported[ATI_ENVMAP_BUMPMAP] = FALSE;
767             } else if (strcmp(ThisExtn, "GL_NV_texture_shader3") == 0) {
768                 TRACE_(d3d_caps)(" FOUND: NVIDIA (NV) Texture Shader (3) support\n");
769                 gl_info->supported[NV_TEXTURE_SHADER3] = TRUE;
770             } else if (strcmp(ThisExtn, "GL_NV_occlusion_query") == 0) {
771                 TRACE_(d3d_caps)(" FOUND: NVIDIA (NV) Occlusion Query (3) support\n");
772                 gl_info->supported[NV_OCCLUSION_QUERY] = TRUE;
773             } else if (strstr(ThisExtn, "GL_NV_vertex_program")) {
774                 if(strcmp(ThisExtn, "GL_NV_vertex_program3") == 0)
775                     gl_info->vs_nv_version = VS_VERSION_30;
776                 else if(strcmp(ThisExtn, "GL_NV_vertex_program2") == 0)
777                     gl_info->vs_nv_version = VS_VERSION_20;
778                 else if(strcmp(ThisExtn, "GL_NV_vertex_program1_1") == 0)
779                     gl_info->vs_nv_version = VS_VERSION_11;
780                 else
781                     gl_info->vs_nv_version = VS_VERSION_10;
782                 TRACE_(d3d_caps)(" FOUND: NVIDIA (NV) Vertex Shader support - version=%02x\n", gl_info->vs_nv_version);
783                 gl_info->supported[NV_VERTEX_PROGRAM] = TRUE;
784             } else if (strstr(ThisExtn, "GL_NV_fence")) {
785                 if(!gl_info->supported[APPLE_FENCE]) {
786                     gl_info->supported[NV_FENCE] = TRUE;
787                 }
788
789             /**
790              * ATI
791              */
792             /** TODO */
793             } else if (strcmp(ThisExtn, "GL_ATI_separate_stencil") == 0) {
794                 TRACE_(d3d_caps)(" FOUND: ATI Separate stencil support\n");
795                 gl_info->supported[ATI_SEPARATE_STENCIL] = TRUE;
796             } else if (strcmp(ThisExtn, "GL_ATI_texture_env_combine3") == 0) {
797                 TRACE_(d3d_caps)(" FOUND: ATI Texture Env combine (3) support\n");
798                 gl_info->supported[ATI_TEXTURE_ENV_COMBINE3] = TRUE;
799             } else if (strcmp(ThisExtn, "GL_ATI_texture_mirror_once") == 0) {
800                 TRACE_(d3d_caps)(" FOUND: ATI Texture Mirror Once support\n");
801                 gl_info->supported[ATI_TEXTURE_MIRROR_ONCE] = TRUE;
802             } else if (strcmp(ThisExtn, "GL_EXT_vertex_shader") == 0) {
803                 gl_info->vs_ati_version = VS_VERSION_11;
804                 TRACE_(d3d_caps)(" FOUND: ATI (EXT) Vertex Shader support - version=%02x\n", gl_info->vs_ati_version);
805                 gl_info->supported[EXT_VERTEX_SHADER] = TRUE;
806             } else if (strcmp(ThisExtn, "GL_ATI_envmap_bumpmap") == 0) {
807                 TRACE_(d3d_caps)(" FOUND: ATI Environment Bump Mapping support\n");
808                 /* GL_ATI_envmap_bumpmap won't play nice with texture shaders, so disable it
809                  * Won't occur in any real world situation though
810                  */
811                 if(!gl_info->supported[NV_TEXTURE_SHADER2]) {
812                     gl_info->supported[ATI_ENVMAP_BUMPMAP] = TRUE;
813                 }
814             /**
815              * Apple
816              */
817             } else if (strstr(ThisExtn, "GL_APPLE_fence")) {
818                 /* GL_NV_fence and GL_APPLE_fence provide the same functionality basically.
819                  * The apple extension interacts with some other apple exts. Disable the NV
820                  * extension if the apple one is support to prevent confusion in other parts
821                  * of the code
822                  */
823                 gl_info->supported[NV_FENCE] = FALSE;
824                 gl_info->supported[APPLE_FENCE] = TRUE;
825             } else if (strstr(ThisExtn, "GL_APPLE_client_storage")) {
826                 gl_info->supported[APPLE_CLIENT_STORAGE] = TRUE;
827             }
828
829             if (*GL_Extensions == ' ') GL_Extensions++;
830         }
831     }
832     checkGLcall("extension detection\n");
833
834     /* In some cases the number of texture stages can be larger than the number
835      * of samplers. The GF4 for example can use only 2 samplers (no fragment
836      * shaders), but 8 texture stages (register combiners). */
837     gl_info->max_sampler_stages = max(gl_info->max_samplers, gl_info->max_texture_stages);
838
839     /* We can only use ORM_FBO when the hardware supports it. */
840     if (wined3d_settings.offscreen_rendering_mode == ORM_FBO && !gl_info->supported[EXT_FRAMEBUFFER_OBJECT]) {
841         WARN_(d3d_caps)("GL_EXT_framebuffer_object not supported, falling back to PBuffer offscreen rendering mode.\n");
842         wined3d_settings.offscreen_rendering_mode = ORM_PBUFFER;
843     }
844
845     /* MRTs are currently only supported when FBOs are used. */
846     if (wined3d_settings.offscreen_rendering_mode != ORM_FBO) {
847         gl_info->max_buffers = 1;
848     }
849
850     /* Below is a list of Nvidia and ATI GPUs. Both vendors have dozens of different GPUs with roughly the same
851      * features. In most cases GPUs from a certain family differ in clockspeeds, the amount of video memory and
852      * in case of the latest videocards in the number of pixel/vertex pipelines.
853      *
854      * A Direct3D device object contains the PCI id (vendor + device) of the videocard which is used for
855      * rendering. Various games use this information to get a rough estimation of the features of the card
856      * and some might use it for enabling 3d effects only on certain types of videocards. In some cases
857      * games might even use it to work around bugs which happen on certain videocards/driver combinations.
858      * The problem is that OpenGL only exposes a rendering string containing the name of the videocard and
859      * not the PCI id.
860      *
861      * Various games depend on the PCI id, so somehow we need to provide one. A simple option is to parse
862      * the renderer string and translate this to the right PCI id. This is a lot of work because there are more
863      * than 200 GPUs just for Nvidia. Various cards share the same renderer string, so the amount of code might
864      * be 'small' but there are quite a number of exceptions which would make this a pain to maintain.
865      * Another way would be to query the PCI id from the operating system (assuming this is the videocard which
866      * is used for rendering which is not always the case). This would work but it is not very portable. Second
867      * it would not work well in, let's say, a remote X situation in which the amount of 3d features which can be used
868      * is limited.
869      *
870      * As said most games only use the PCI id to get an indication of the capabilities of the card.
871      * It doesn't really matter if the given id is the correct one if we return the id of a card with
872      * similar 3d features.
873      *
874      * The code below checks the OpenGL capabilities of a videocard and matches that to a certain level of
875      * Direct3D functionality. Once a card passes the Direct3D9 check, we know that the card (in case of Nvidia)
876      * is at least a GeforceFX. To give a better estimate we do a basic check on the renderer string but if that
877      * won't pass we return a default card. This way is better than maintaining a full card database as even
878      * without a full database we can return a card with similar features. Second the size of the database
879      * can be made quite small because when you know what type of 3d functionality a card has, you know to which
880      * GPU family the GPU must belong. Because of this you only have to check a small part of the renderer string
881      * to distinguishes between different models from that family. 
882      */
883     switch (gl_info->gl_vendor) {
884         case VENDOR_NVIDIA:
885             /* Both the GeforceFX, 6xxx and 7xxx series support D3D9. The last two types have more
886              * shader capabilities, so we use the shader capabilities to distinguish between FX and 6xxx/7xxx.
887              */
888             if(WINE_D3D9_CAPABLE(gl_info) && (gl_info->vs_nv_version == VS_VERSION_30)) {
889                 if (strstr(gl_info->gl_renderer, "7800") ||
890                     strstr(gl_info->gl_renderer, "7900") ||
891                     strstr(gl_info->gl_renderer, "7950") ||
892                     strstr(gl_info->gl_renderer, "Quadro FX 4") ||
893                     strstr(gl_info->gl_renderer, "Quadro FX 5"))
894                         gl_info->gl_card = CARD_NVIDIA_GEFORCE_7800GT;
895                 else if(strstr(gl_info->gl_renderer, "6800") ||
896                         strstr(gl_info->gl_renderer, "7600"))
897                             gl_info->gl_card = CARD_NVIDIA_GEFORCE_6800;
898                 else if(strstr(gl_info->gl_renderer, "6600") ||
899                         strstr(gl_info->gl_renderer, "6610") ||
900                         strstr(gl_info->gl_renderer, "6700"))
901                             gl_info->gl_card = CARD_NVIDIA_GEFORCE_6600GT;
902                 else
903                     gl_info->gl_card = CARD_NVIDIA_GEFORCE_6200; /* Geforce 6100/6150/6200/7300/7400 */
904             } else if(WINE_D3D9_CAPABLE(gl_info)) {
905                 if (strstr(gl_info->gl_renderer, "5800") ||
906                     strstr(gl_info->gl_renderer, "5900") ||
907                     strstr(gl_info->gl_renderer, "5950") ||
908                     strstr(gl_info->gl_renderer, "Quadro FX"))
909                         gl_info->gl_card = CARD_NVIDIA_GEFORCEFX_5800;
910                 else if(strstr(gl_info->gl_renderer, "5600") ||
911                         strstr(gl_info->gl_renderer, "5650") ||
912                         strstr(gl_info->gl_renderer, "5700") ||
913                         strstr(gl_info->gl_renderer, "5750"))
914                             gl_info->gl_card = CARD_NVIDIA_GEFORCEFX_5600;
915                 else
916                     gl_info->gl_card = CARD_NVIDIA_GEFORCEFX_5200; /* GeforceFX 5100/5200/5250/5300/5500 */
917             } else if(WINE_D3D8_CAPABLE(gl_info)) {
918                 if (strstr(gl_info->gl_renderer, "GeForce4 Ti") || strstr(gl_info->gl_renderer, "Quadro4"))
919                     gl_info->gl_card = CARD_NVIDIA_GEFORCE4_TI4200; /* Geforce4 Ti4200/Ti4400/Ti4600/Ti4800, Quadro4 */
920                 else
921                     gl_info->gl_card = CARD_NVIDIA_GEFORCE3; /* Geforce3 standard/Ti200/Ti500, Quadro DCC */
922             } else if(WINE_D3D7_CAPABLE(gl_info)) {
923                 if (strstr(gl_info->gl_renderer, "GeForce4 MX"))
924                     gl_info->gl_card = CARD_NVIDIA_GEFORCE4_MX; /* MX420/MX440/MX460/MX4000 */
925                 else if(strstr(gl_info->gl_renderer, "GeForce2 MX") || strstr(gl_info->gl_renderer, "Quadro2 MXR"))
926                     gl_info->gl_card = CARD_NVIDIA_GEFORCE2_MX; /* Geforce2 standard/MX100/MX200/MX400, Quadro2 MXR */
927                 else if(strstr(gl_info->gl_renderer, "GeForce2") || strstr(gl_info->gl_renderer, "Quadro2"))
928                     gl_info->gl_card = CARD_NVIDIA_GEFORCE2; /* Geforce2 GTS/Pro/Ti/Ultra, Quadro2 */
929                 else
930                     gl_info->gl_card = CARD_NVIDIA_GEFORCE; /* Geforce 256/DDR, Quadro */
931             } else {
932                 if (strstr(gl_info->gl_renderer, "TNT2"))
933                     gl_info->gl_card = CARD_NVIDIA_RIVA_TNT2; /* Riva TNT2 standard/M64/Pro/Ultra */
934                 else
935                     gl_info->gl_card = CARD_NVIDIA_RIVA_TNT; /* Riva TNT, Vanta */
936             }
937             break;
938         case VENDOR_ATI:
939             if(WINE_D3D9_CAPABLE(gl_info)) {
940                 /* Radeon R5xx */
941                 if (strstr(gl_info->gl_renderer, "X1600") ||
942                     strstr(gl_info->gl_renderer, "X1800") ||
943                     strstr(gl_info->gl_renderer, "X1900") ||
944                     strstr(gl_info->gl_renderer, "X1950"))
945                         gl_info->gl_card = CARD_ATI_RADEON_X1600;
946                 /* Radeon R4xx + X1300/X1400 (lowend R5xx) */
947                 else if(strstr(gl_info->gl_renderer, "X700") ||
948                         strstr(gl_info->gl_renderer, "X800") ||
949                         strstr(gl_info->gl_renderer, "X850") ||
950                         strstr(gl_info->gl_renderer, "X1300") ||
951                         strstr(gl_info->gl_renderer, "X1400"))
952                             gl_info->gl_card = CARD_ATI_RADEON_X700;
953                 /* Radeon R3xx */ 
954                 else
955                     gl_info->gl_card = CARD_ATI_RADEON_9500; /* Radeon 9500/9550/9600/9700/9800/X300/X550/X600 */
956             } else if(WINE_D3D8_CAPABLE(gl_info)) {
957                     gl_info->gl_card = CARD_ATI_RADEON_8500; /* Radeon 8500/9000/9100/9200/9300 */
958             } else if(WINE_D3D7_CAPABLE(gl_info)) {
959                     gl_info->gl_card = CARD_ATI_RADEON_7200; /* Radeon 7000/7100/7200/7500 */
960             } else
961                 gl_info->gl_card = CARD_ATI_RAGE_128PRO;
962             break;
963         case VENDOR_INTEL:
964             if (strstr(gl_info->gl_renderer, "915GM")) {
965                 gl_info->gl_card = CARD_INTEL_I915GM;
966             } else if (strstr(gl_info->gl_renderer, "915G")) {
967                 gl_info->gl_card = CARD_INTEL_I915G;
968             } else if (strstr(gl_info->gl_renderer, "865G")) {
969                 gl_info->gl_card = CARD_INTEL_I865G;
970             } else if (strstr(gl_info->gl_renderer, "855G")) {
971                 gl_info->gl_card = CARD_INTEL_I855G;
972             } else if (strstr(gl_info->gl_renderer, "830G")) {
973                 gl_info->gl_card = CARD_INTEL_I830G;
974             } else {
975                 gl_info->gl_card = CARD_INTEL_I915G;
976             }
977             break;
978         case VENDOR_MESA:
979         case VENDOR_WINE:
980         default:
981             /* Default to generic Nvidia hardware based on the supported OpenGL extensions. The choice 
982              * for Nvidia was because the hardware and drivers they make are of good quality. This makes
983              * them a good generic choice.
984              */
985             gl_info->gl_vendor = VENDOR_NVIDIA;
986             if(WINE_D3D9_CAPABLE(gl_info))
987                 gl_info->gl_card = CARD_NVIDIA_GEFORCEFX_5600;
988             else if(WINE_D3D8_CAPABLE(gl_info))
989                 gl_info->gl_card = CARD_NVIDIA_GEFORCE3;            
990             else if(WINE_D3D7_CAPABLE(gl_info))
991                 gl_info->gl_card = CARD_NVIDIA_GEFORCE;
992             else if(WINE_D3D6_CAPABLE(gl_info))
993                 gl_info->gl_card = CARD_NVIDIA_RIVA_TNT;
994             else
995                 gl_info->gl_card = CARD_NVIDIA_RIVA_128;
996     }
997     TRACE("FOUND (fake) card: 0x%x (vendor id), 0x%x (device id)\n", gl_info->gl_vendor, gl_info->gl_card);
998
999     /* Load all the lookup tables
1000     TODO: It may be a good idea to make minLookup and maxLookup const and populate them in wined3d_private.h where they are declared */
1001     minLookup[WINELOOKUP_WARPPARAM] = WINED3DTADDRESS_WRAP;
1002     maxLookup[WINELOOKUP_WARPPARAM] = WINED3DTADDRESS_MIRRORONCE;
1003
1004     minLookup[WINELOOKUP_MAGFILTER] = WINED3DTEXF_NONE;
1005     maxLookup[WINELOOKUP_MAGFILTER] = WINED3DTEXF_ANISOTROPIC;
1006
1007
1008     for (i = 0; i < MAX_LOOKUPS; i++) {
1009         stateLookup[i] = HeapAlloc(GetProcessHeap(), 0, sizeof(*stateLookup[i]) * (1 + maxLookup[i] - minLookup[i]) );
1010     }
1011
1012     stateLookup[WINELOOKUP_WARPPARAM][WINED3DTADDRESS_WRAP   - minLookup[WINELOOKUP_WARPPARAM]] = GL_REPEAT;
1013     stateLookup[WINELOOKUP_WARPPARAM][WINED3DTADDRESS_CLAMP  - minLookup[WINELOOKUP_WARPPARAM]] = GL_CLAMP_TO_EDGE;
1014     stateLookup[WINELOOKUP_WARPPARAM][WINED3DTADDRESS_BORDER - minLookup[WINELOOKUP_WARPPARAM]] =
1015              gl_info->supported[ARB_TEXTURE_BORDER_CLAMP] ? GL_CLAMP_TO_BORDER_ARB : GL_REPEAT;
1016     stateLookup[WINELOOKUP_WARPPARAM][WINED3DTADDRESS_BORDER - minLookup[WINELOOKUP_WARPPARAM]] =
1017              gl_info->supported[ARB_TEXTURE_BORDER_CLAMP] ? GL_CLAMP_TO_BORDER_ARB : GL_REPEAT;
1018     stateLookup[WINELOOKUP_WARPPARAM][WINED3DTADDRESS_MIRROR - minLookup[WINELOOKUP_WARPPARAM]] =
1019              gl_info->supported[ARB_TEXTURE_MIRRORED_REPEAT] ? GL_MIRRORED_REPEAT_ARB : GL_REPEAT;
1020     stateLookup[WINELOOKUP_WARPPARAM][WINED3DTADDRESS_MIRRORONCE - minLookup[WINELOOKUP_WARPPARAM]] =
1021              gl_info->supported[ATI_TEXTURE_MIRROR_ONCE] ? GL_MIRROR_CLAMP_TO_EDGE_ATI : GL_REPEAT;
1022
1023     stateLookup[WINELOOKUP_MAGFILTER][WINED3DTEXF_NONE        - minLookup[WINELOOKUP_MAGFILTER]]  = GL_NEAREST;
1024     stateLookup[WINELOOKUP_MAGFILTER][WINED3DTEXF_POINT       - minLookup[WINELOOKUP_MAGFILTER]] = GL_NEAREST;
1025     stateLookup[WINELOOKUP_MAGFILTER][WINED3DTEXF_LINEAR      - minLookup[WINELOOKUP_MAGFILTER]] = GL_LINEAR;
1026     stateLookup[WINELOOKUP_MAGFILTER][WINED3DTEXF_ANISOTROPIC - minLookup[WINELOOKUP_MAGFILTER]] =
1027              gl_info->supported[EXT_TEXTURE_FILTER_ANISOTROPIC] ? GL_LINEAR : GL_NEAREST;
1028
1029
1030     minMipLookup[WINED3DTEXF_NONE][WINED3DTEXF_NONE]     = GL_LINEAR;
1031     minMipLookup[WINED3DTEXF_NONE][WINED3DTEXF_POINT]    = GL_LINEAR;
1032     minMipLookup[WINED3DTEXF_NONE][WINED3DTEXF_LINEAR]   = GL_LINEAR;
1033     minMipLookup[WINED3DTEXF_POINT][WINED3DTEXF_NONE]    = GL_NEAREST;
1034     minMipLookup[WINED3DTEXF_POINT][WINED3DTEXF_POINT]   = GL_NEAREST_MIPMAP_NEAREST;
1035     minMipLookup[WINED3DTEXF_POINT][WINED3DTEXF_LINEAR]  = GL_NEAREST_MIPMAP_LINEAR;
1036     minMipLookup[WINED3DTEXF_LINEAR][WINED3DTEXF_NONE]   = GL_LINEAR;
1037     minMipLookup[WINED3DTEXF_LINEAR][WINED3DTEXF_POINT]  = GL_LINEAR_MIPMAP_NEAREST;
1038     minMipLookup[WINED3DTEXF_LINEAR][WINED3DTEXF_LINEAR] = GL_LINEAR_MIPMAP_LINEAR;
1039     minMipLookup[WINED3DTEXF_ANISOTROPIC][WINED3DTEXF_NONE]   = gl_info->supported[EXT_TEXTURE_FILTER_ANISOTROPIC] ?
1040     GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR;
1041     minMipLookup[WINED3DTEXF_ANISOTROPIC][WINED3DTEXF_POINT]  = gl_info->supported[EXT_TEXTURE_FILTER_ANISOTROPIC] ? GL_LINEAR_MIPMAP_NEAREST : GL_LINEAR;
1042     minMipLookup[WINED3DTEXF_ANISOTROPIC][WINED3DTEXF_LINEAR] = gl_info->supported[EXT_TEXTURE_FILTER_ANISOTROPIC] ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR;
1043
1044 /* TODO: config lookups */
1045
1046     if (display != NULL) {
1047         GLX_Extensions = glXQueryExtensionsString(display, DefaultScreen(display));
1048         TRACE_(d3d_caps)("GLX_Extensions reported:\n");
1049
1050         if (NULL == GLX_Extensions) {
1051             ERR("   GLX_Extensions returns NULL\n");
1052         } else {
1053             while (*GLX_Extensions != 0x00) {
1054                 const char *Start = GLX_Extensions;
1055                 char ThisExtn[256];
1056
1057                 memset(ThisExtn, 0x00, sizeof(ThisExtn));
1058                 while (*GLX_Extensions != ' ' && *GLX_Extensions != 0x00) {
1059                     GLX_Extensions++;
1060                 }
1061                 memcpy(ThisExtn, Start, (GLX_Extensions - Start));
1062                 TRACE_(d3d_caps)("- %s\n", ThisExtn);
1063                 if (*GLX_Extensions == ' ') GLX_Extensions++;
1064             }
1065         }
1066     }
1067
1068
1069     WineD3D_ReleaseFakeGLContext();
1070     return return_value;
1071 }
1072
1073 /**********************************************************
1074  * IWineD3D implementation follows
1075  **********************************************************/
1076
1077 static UINT     WINAPI IWineD3DImpl_GetAdapterCount (IWineD3D *iface) {
1078     IWineD3DImpl *This = (IWineD3DImpl *)iface;
1079
1080     /* FIXME: Set to one for now to imply the display */
1081     TRACE_(d3d_caps)("(%p): Mostly stub, only returns primary display\n", This);
1082     return 1;
1083 }
1084
1085 static HRESULT  WINAPI IWineD3DImpl_RegisterSoftwareDevice(IWineD3D *iface, void* pInitializeFunction) {
1086     IWineD3DImpl *This = (IWineD3DImpl *)iface;
1087     FIXME("(%p)->(%p): stub\n", This, pInitializeFunction);
1088     return WINED3D_OK;
1089 }
1090
1091 static HMONITOR WINAPI IWineD3DImpl_GetAdapterMonitor(IWineD3D *iface, UINT Adapter) {
1092     IWineD3DImpl *This = (IWineD3DImpl *)iface;
1093     POINT pt = { -1, -1 };
1094
1095     if (Adapter >= IWineD3DImpl_GetAdapterCount(iface)) {
1096         return NULL;
1097     }
1098
1099     FIXME_(d3d_caps)("(%p): returning the primary monitor for adapter %d\n", This, Adapter);
1100     return MonitorFromPoint(pt, MONITOR_DEFAULTTOPRIMARY);
1101 }
1102
1103 /* FIXME: GetAdapterModeCount and EnumAdapterModes currently only returns modes
1104      of the same bpp but different resolutions                                  */
1105
1106 /* Note: dx9 supplies a format. Calls from d3d8 supply WINED3DFMT_UNKNOWN */
1107 static UINT     WINAPI IWineD3DImpl_GetAdapterModeCount(IWineD3D *iface, UINT Adapter, WINED3DFORMAT Format) {
1108     IWineD3DImpl *This = (IWineD3DImpl *)iface;
1109     TRACE_(d3d_caps)("(%p}->(Adapter: %d, Format: %s)\n", This, Adapter, debug_d3dformat(Format));
1110
1111     if (Adapter >= IWineD3D_GetAdapterCount(iface)) {
1112         return 0;
1113     }
1114
1115     if (Adapter == 0) { /* Display */
1116         int i = 0;
1117         int j = 0;
1118
1119         if (!DEBUG_SINGLE_MODE) {
1120             DEVMODEW DevModeW;
1121
1122             while (EnumDisplaySettingsExW(NULL, j, &DevModeW, 0)) {
1123                 j++;
1124                 switch (Format)
1125                 {
1126                     case WINED3DFMT_UNKNOWN:
1127                         /* This is for D3D8, do not enumerate P8 here */
1128                         if (DevModeW.dmBitsPerPel == 32 ||
1129                             DevModeW.dmBitsPerPel == 16) i++;
1130                         break;
1131                     case WINED3DFMT_X8R8G8B8:
1132                         if (DevModeW.dmBitsPerPel == 32) i++;
1133                         break;
1134                     case WINED3DFMT_R5G6B5:
1135                         if (DevModeW.dmBitsPerPel == 16) i++;
1136                         break;
1137                     case WINED3DFMT_P8:
1138                         if (DevModeW.dmBitsPerPel == 8) i++;
1139                         break;
1140                     default:
1141                         /* Skip other modes as they do not match the requested format */
1142                         break;
1143                 }
1144             }
1145         } else {
1146             i = 1;
1147             j = 1;
1148         }
1149
1150         TRACE_(d3d_caps)("(%p}->(Adapter: %d) => %d (out of %d)\n", This, Adapter, i, j);
1151         return i;
1152     } else {
1153         FIXME_(d3d_caps)("Adapter not primary display\n");
1154     }
1155     return 0;
1156 }
1157
1158 /* Note: dx9 supplies a format. Calls from d3d8 supply WINED3DFMT_UNKNOWN */
1159 static HRESULT WINAPI IWineD3DImpl_EnumAdapterModes(IWineD3D *iface, UINT Adapter, WINED3DFORMAT Format, UINT Mode, WINED3DDISPLAYMODE* pMode) {
1160     IWineD3DImpl *This = (IWineD3DImpl *)iface;
1161     TRACE_(d3d_caps)("(%p}->(Adapter:%d, mode:%d, pMode:%p, format:%s)\n", This, Adapter, Mode, pMode, debug_d3dformat(Format));
1162
1163     /* Validate the parameters as much as possible */
1164     if (NULL == pMode ||
1165         Adapter >= IWineD3DImpl_GetAdapterCount(iface) ||
1166         Mode    >= IWineD3DImpl_GetAdapterModeCount(iface, Adapter, Format)) {
1167         return WINED3DERR_INVALIDCALL;
1168     }
1169
1170     if (Adapter == 0 && !DEBUG_SINGLE_MODE) { /* Display */
1171         DEVMODEW DevModeW;
1172         int ModeIdx = 0;
1173         int i = 0;
1174         int j = 0;
1175
1176         /* If we are filtering to a specific format (D3D9), then need to skip
1177            all unrelated modes, but if mode is irrelevant (D3D8), then we can
1178            just count through the ones with valid bit depths */
1179         while ((i<=Mode) && EnumDisplaySettingsExW(NULL, j++, &DevModeW, 0)) {
1180             switch (Format)
1181             {
1182                 case WINED3DFMT_UNKNOWN:
1183                     /* This is D3D8. Do not enumerate P8 here */
1184                     if (DevModeW.dmBitsPerPel == 32 ||
1185                         DevModeW.dmBitsPerPel == 16) i++;
1186                     break;
1187                 case WINED3DFMT_X8R8G8B8:
1188                     if (DevModeW.dmBitsPerPel == 32) i++;
1189                     break;
1190                 case WINED3DFMT_R5G6B5:
1191                     if (DevModeW.dmBitsPerPel == 16) i++;
1192                     break;
1193                 case WINED3DFMT_P8:
1194                     if (DevModeW.dmBitsPerPel == 8) i++;
1195                     break;
1196                 default:
1197                     /* Modes that don't match what we support can get an early-out */
1198                     TRACE_(d3d_caps)("Searching for %s, returning D3DERR_INVALIDCALL\n", debug_d3dformat(Format));
1199                     return WINED3DERR_INVALIDCALL;
1200             }
1201         }
1202
1203         if (i == 0) {
1204             TRACE_(d3d_caps)("No modes found for format (%x - %s)\n", Format, debug_d3dformat(Format));
1205             return WINED3DERR_INVALIDCALL;
1206         }
1207         ModeIdx = j - 1;
1208
1209         /* Now get the display mode via the calculated index */
1210         if (EnumDisplaySettingsExW(NULL, ModeIdx, &DevModeW, 0)) {
1211             pMode->Width        = DevModeW.dmPelsWidth;
1212             pMode->Height       = DevModeW.dmPelsHeight;
1213             pMode->RefreshRate  = WINED3DADAPTER_DEFAULT;
1214             if (DevModeW.dmFields & DM_DISPLAYFREQUENCY)
1215                 pMode->RefreshRate = DevModeW.dmDisplayFrequency;
1216
1217             if (Format == WINED3DFMT_UNKNOWN)
1218             {
1219                 switch (DevModeW.dmBitsPerPel)
1220                 {
1221                     case 8:
1222                         pMode->Format = WINED3DFMT_P8;
1223                         break;
1224                     case 16:
1225                         pMode->Format = WINED3DFMT_R5G6B5;
1226                         break;
1227                     case 32:
1228                         pMode->Format = WINED3DFMT_X8R8G8B8;
1229                         break;
1230                     default:
1231                         pMode->Format = WINED3DFMT_UNKNOWN;
1232                         ERR("Unhandled bit depth (%u) in mode list!\n", DevModeW.dmBitsPerPel);
1233                 }
1234             } else {
1235                 pMode->Format = Format;
1236             }
1237         } else {
1238             TRACE_(d3d_caps)("Requested mode out of range %d\n", Mode);
1239             return WINED3DERR_INVALIDCALL;
1240         }
1241
1242         TRACE_(d3d_caps)("W %d H %d rr %d fmt (%x - %s) bpp %u\n", pMode->Width, pMode->Height,
1243                 pMode->RefreshRate, pMode->Format, debug_d3dformat(pMode->Format),
1244                 DevModeW.dmBitsPerPel);
1245
1246     } else if (DEBUG_SINGLE_MODE) {
1247         /* Return one setting of the format requested */
1248         if (Mode > 0) return WINED3DERR_INVALIDCALL;
1249         pMode->Width        = 800;
1250         pMode->Height       = 600;
1251         pMode->RefreshRate  = 60;
1252         pMode->Format       = (Format == WINED3DFMT_UNKNOWN) ? WINED3DFMT_X8R8G8B8 : Format;
1253     } else {
1254         FIXME_(d3d_caps)("Adapter not primary display\n");
1255     }
1256
1257     return WINED3D_OK;
1258 }
1259
1260 static HRESULT WINAPI IWineD3DImpl_GetAdapterDisplayMode(IWineD3D *iface, UINT Adapter, WINED3DDISPLAYMODE* pMode) {
1261     IWineD3DImpl *This = (IWineD3DImpl *)iface;
1262     TRACE_(d3d_caps)("(%p}->(Adapter: %d, pMode: %p)\n", This, Adapter, pMode);
1263
1264     if (NULL == pMode ||
1265         Adapter >= IWineD3D_GetAdapterCount(iface)) {
1266         return WINED3DERR_INVALIDCALL;
1267     }
1268
1269     if (Adapter == 0) { /* Display */
1270         int bpp = 0;
1271         DEVMODEW DevModeW;
1272
1273         EnumDisplaySettingsExW(NULL, (DWORD)-1, &DevModeW, 0);
1274         pMode->Width        = DevModeW.dmPelsWidth;
1275         pMode->Height       = DevModeW.dmPelsHeight;
1276         bpp                 = DevModeW.dmBitsPerPel;
1277         pMode->RefreshRate  = WINED3DADAPTER_DEFAULT;
1278         if (DevModeW.dmFields&DM_DISPLAYFREQUENCY)
1279         {
1280             pMode->RefreshRate = DevModeW.dmDisplayFrequency;
1281         }
1282
1283         switch (bpp) {
1284         case  8: pMode->Format       = WINED3DFMT_R3G3B2;   break;
1285         case 16: pMode->Format       = WINED3DFMT_R5G6B5;   break;
1286         case 24: pMode->Format       = WINED3DFMT_X8R8G8B8; break; /* Robots needs 24bit to be X8R8G8B8 */
1287         case 32: pMode->Format       = WINED3DFMT_X8R8G8B8; break; /* EVE online and the Fur demo need 32bit AdapterDisplatMode to return X8R8G8B8 */
1288         default: pMode->Format       = WINED3DFMT_UNKNOWN;
1289         }
1290
1291     } else {
1292         FIXME_(d3d_caps)("Adapter not primary display\n");
1293     }
1294
1295     TRACE_(d3d_caps)("returning w:%d, h:%d, ref:%d, fmt:%s\n", pMode->Width,
1296           pMode->Height, pMode->RefreshRate, debug_d3dformat(pMode->Format));
1297     return WINED3D_OK;
1298 }
1299
1300 static Display * WINAPI IWineD3DImpl_GetAdapterDisplay(IWineD3D *iface, UINT Adapter) {
1301     Display *display;
1302     HDC     device_context;
1303     /* only works with one adapter at the moment... */
1304
1305     /* Get the display */
1306     device_context = GetDC(0);
1307     display = get_display(device_context);
1308     ReleaseDC(0, device_context);
1309     return display;
1310 }
1311
1312 /* NOTE: due to structure differences between dx8 and dx9 D3DADAPTER_IDENTIFIER,
1313    and fields being inserted in the middle, a new structure is used in place    */
1314 static HRESULT WINAPI IWineD3DImpl_GetAdapterIdentifier(IWineD3D *iface, UINT Adapter, DWORD Flags,
1315                                                    WINED3DADAPTER_IDENTIFIER* pIdentifier) {
1316     IWineD3DImpl *This = (IWineD3DImpl *)iface;
1317
1318     TRACE_(d3d_caps)("(%p}->(Adapter: %d, Flags: %x, pId=%p)\n", This, Adapter, Flags, pIdentifier);
1319
1320     if (Adapter >= IWineD3D_GetAdapterCount(iface)) {
1321         return WINED3DERR_INVALIDCALL;
1322     }
1323
1324     if (Adapter == 0) { /* Display - only device supported for now */
1325
1326         BOOL isGLInfoValid = This->isGLInfoValid;
1327
1328         /* FillGLCaps updates gl_info, but we only want to store and
1329            reuse the values once we have a context which is valid. Values from
1330            a temporary context may differ from the final ones                 */
1331         if (!isGLInfoValid) {
1332             /* If we don't know the device settings, go query them now */
1333             isGLInfoValid = IWineD3DImpl_FillGLCaps(iface, IWineD3DImpl_GetAdapterDisplay(iface, Adapter));
1334         }
1335
1336         /* Return the information requested */
1337         TRACE_(d3d_caps)("device/Vendor Name and Version detection using FillGLCaps\n");
1338         strcpy(pIdentifier->Driver, "Display");
1339         strcpy(pIdentifier->Description, "Direct3D HAL");
1340
1341         /* Note dx8 doesn't supply a DeviceName */
1342         if (NULL != pIdentifier->DeviceName) strcpy(pIdentifier->DeviceName, "\\\\.\\DISPLAY"); /* FIXME: May depend on desktop? */
1343         /* Current Windows drivers have versions like 6.14.... (some older have an earlier version) */
1344         pIdentifier->DriverVersion->u.HighPart = MAKEDWORD_VERSION(6, 14);
1345         pIdentifier->DriverVersion->u.LowPart = This->gl_info.gl_driver_version;
1346         *(pIdentifier->VendorId) = This->gl_info.gl_vendor;
1347         *(pIdentifier->DeviceId) = This->gl_info.gl_card;
1348         *(pIdentifier->SubSysId) = 0;
1349         *(pIdentifier->Revision) = 0;
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             /* In theory we could do all formats, just fetch them accordingly should the buffer be locked.
1642              * Windows supports only those 3, and enumerating the other formats confuses applications
1643              */
1644             case WINED3DFMT_D24S8:
1645             case WINED3DFMT_D24X8:
1646             case WINED3DFMT_D16:
1647                 TRACE_(d3d_caps)("[OK]\n");
1648                 return WINED3D_OK;
1649             case WINED3DFMT_D16_LOCKABLE:
1650             case WINED3DFMT_D24FS8:
1651             case WINED3DFMT_D32F_LOCKABLE:
1652             case WINED3DFMT_D24X4S4:
1653             case WINED3DFMT_D15S1:
1654             case WINED3DFMT_D32:
1655                 TRACE_(d3d_caps)("[FAILED]. Disabled because not enumerated on windows\n");
1656                 return WINED3DERR_NOTAVAILABLE;
1657             default:
1658                 TRACE_(d3d_caps)("[FAILED]\n");
1659                 return WINED3DERR_NOTAVAILABLE;
1660         }
1661     } else if(Usage & WINED3DUSAGE_RENDERTARGET) {
1662         switch (CheckFormat) {
1663             case WINED3DFMT_R8G8B8:
1664             case WINED3DFMT_A8R8G8B8:
1665             case WINED3DFMT_X8R8G8B8:
1666             case WINED3DFMT_R5G6B5:
1667             case WINED3DFMT_X1R5G5B5:
1668             case WINED3DFMT_A1R5G5B5:
1669             case WINED3DFMT_A4R4G4B4:
1670             case WINED3DFMT_R3G3B2:
1671             case WINED3DFMT_X4R4G4B4:
1672             case WINED3DFMT_A8B8G8R8:
1673             case WINED3DFMT_X8B8G8R8:
1674             case WINED3DFMT_P8:
1675                 TRACE_(d3d_caps)("[OK]\n");
1676                 return WINED3D_OK;
1677             case WINED3DFMT_R16F:
1678             case WINED3DFMT_A16B16G16R16F:
1679                 if (!GL_SUPPORT(ARB_HALF_FLOAT_PIXEL) || !GL_SUPPORT(ARB_TEXTURE_FLOAT)) {
1680                     TRACE_(d3d_caps)("[FAILED]\n");
1681                     return WINED3DERR_NOTAVAILABLE;
1682                 }
1683                 TRACE_(d3d_caps)("[OK]\n");
1684                 return WINED3D_OK;
1685             default:
1686                 TRACE_(d3d_caps)("[FAILED]\n");
1687                 return WINED3DERR_NOTAVAILABLE;
1688         }
1689     } else if(Usage & WINED3DUSAGE_QUERY_LEGACYBUMPMAP) {
1690         if(GL_SUPPORT(NV_REGISTER_COMBINERS) && GL_SUPPORT(NV_TEXTURE_SHADER2)) {
1691             switch (CheckFormat) {
1692                 case WINED3DFMT_V8U8:
1693                     TRACE_(d3d_caps)("[OK]\n");
1694                     return WINED3D_OK;
1695                 /* TODO: Other bump map formats */
1696                 default:
1697                     TRACE_(d3d_caps)("[FAILED]\n");
1698                     return WINED3DERR_NOTAVAILABLE;
1699             }
1700         }
1701         if(GL_SUPPORT(ATI_ENVMAP_BUMPMAP)) {
1702             switch (CheckFormat) {
1703                 case WINED3DFMT_V8U8:
1704                     TRACE_(d3d_caps)("[OK]\n");
1705                     return WINED3D_OK;
1706                 default:
1707                     TRACE_(d3d_caps)("[FAILED]\n");
1708                     return WINED3DERR_NOTAVAILABLE;
1709             }
1710         }
1711         TRACE_(d3d_caps)("[FAILED]\n");
1712         return WINED3DERR_NOTAVAILABLE;
1713     }
1714
1715     if (GL_SUPPORT(EXT_TEXTURE_COMPRESSION_S3TC)) {
1716         switch (CheckFormat) {
1717         case WINED3DFMT_DXT1:
1718         case WINED3DFMT_DXT2:
1719         case WINED3DFMT_DXT3:
1720         case WINED3DFMT_DXT4:
1721         case WINED3DFMT_DXT5:
1722           TRACE_(d3d_caps)("[OK]\n");
1723           return WINED3D_OK;
1724         default:
1725             break; /* Avoid compiler warnings */
1726         }
1727     }
1728
1729     if (GL_SUPPORT(ARB_TEXTURE_FLOAT)) {
1730
1731         BOOL half_pixel_support = GL_SUPPORT(ARB_HALF_FLOAT_PIXEL);
1732
1733         switch (CheckFormat) {
1734             case WINED3DFMT_R16F:
1735             case WINED3DFMT_A16B16G16R16F:
1736                 if (!half_pixel_support) break;
1737             case WINED3DFMT_R32F:
1738             case WINED3DFMT_A32B32G32R32F:
1739                 TRACE_(d3d_caps)("[OK]\n");
1740                 return WINED3D_OK;
1741             default:
1742                 break; /* Avoid compiler warnings */
1743         }
1744     }
1745
1746     /* This format is nothing special and it is supported perfectly.
1747      * However, ati and nvidia driver on windows do not mark this format as
1748      * supported (tested with the dxCapsViewer) and pretending to
1749      * support this format uncovers a bug in Battlefield 1942 (fonts are missing)
1750      * So do the same as Windows drivers and pretend not to support it on dx8 and 9
1751      * Enable it on dx7. It will need additional checking on dx10 when we support it.
1752      */
1753     if(This->dxVersion > 7 && CheckFormat == WINED3DFMT_R8G8B8) {
1754         TRACE_(d3d_caps)("[FAILED]\n");
1755         return WINED3DERR_NOTAVAILABLE;
1756     }
1757
1758     switch (CheckFormat) {
1759
1760         /*****
1761          *  supported: RGB(A) formats
1762          */
1763         case WINED3DFMT_R8G8B8: /* Enable for dx7, blacklisted for 8 and 9 above */
1764         case WINED3DFMT_A8R8G8B8:
1765         case WINED3DFMT_X8R8G8B8:
1766         case WINED3DFMT_R5G6B5:
1767         case WINED3DFMT_X1R5G5B5:
1768         case WINED3DFMT_A1R5G5B5:
1769         case WINED3DFMT_A4R4G4B4:
1770         case WINED3DFMT_R3G3B2:
1771         case WINED3DFMT_A8:
1772         case WINED3DFMT_A8R3G3B2:
1773         case WINED3DFMT_X4R4G4B4:
1774         case WINED3DFMT_A8B8G8R8:
1775         case WINED3DFMT_X8B8G8R8:
1776         case WINED3DFMT_A2R10G10B10:
1777         case WINED3DFMT_A2B10G10R10:
1778             TRACE_(d3d_caps)("[OK]\n");
1779             return WINED3D_OK;
1780
1781         /*****
1782          *  supported: Palettized
1783          */
1784         case WINED3DFMT_P8:
1785             TRACE_(d3d_caps)("[OK]\n");
1786             return WINED3D_OK;
1787
1788         /*****
1789          *  Supported: (Alpha)-Luminance
1790          */
1791         case WINED3DFMT_L8:
1792         case WINED3DFMT_A8L8:
1793         case WINED3DFMT_A4L4:
1794             TRACE_(d3d_caps)("[OK]\n");
1795             return WINED3D_OK;
1796
1797         /*****
1798          *  Not supported for now: Bump mapping formats
1799          *  Enable some because games often fail when they are not available
1800          *  and are still playable even without bump mapping
1801          */
1802         case WINED3DFMT_V8U8:
1803         case WINED3DFMT_V16U16:
1804         case WINED3DFMT_L6V5U5:
1805         case WINED3DFMT_X8L8V8U8:
1806         case WINED3DFMT_Q8W8V8U8:
1807         case WINED3DFMT_W11V11U10:
1808         case WINED3DFMT_A2W10V10U10:
1809             WARN_(d3d_caps)("[Not supported, but pretended to do]\n");
1810             return WINED3D_OK;
1811
1812         /*****
1813          *  DXTN Formats: Handled above
1814          * WINED3DFMT_DXT1
1815          * WINED3DFMT_DXT2
1816          * WINED3DFMT_DXT3
1817          * WINED3DFMT_DXT4
1818          * WINED3DFMT_DXT5
1819          */
1820
1821         /*****
1822          *  Odd formats - not supported
1823          */
1824         case WINED3DFMT_VERTEXDATA:
1825         case WINED3DFMT_INDEX16:
1826         case WINED3DFMT_INDEX32:
1827         case WINED3DFMT_Q16W16V16U16:
1828             TRACE_(d3d_caps)("[FAILED]\n"); /* Enable when implemented */
1829             return WINED3DERR_NOTAVAILABLE;
1830
1831         /*****
1832          *  Float formats: Not supported right now
1833          */
1834         case WINED3DFMT_G16R16F:
1835         case WINED3DFMT_G32R32F:
1836         case WINED3DFMT_CxV8U8:
1837             TRACE_(d3d_caps)("[FAILED]\n"); /* Enable when implemented */
1838             return WINED3DERR_NOTAVAILABLE;
1839
1840             /* Not supported */
1841         case WINED3DFMT_G16R16:
1842         case WINED3DFMT_A16B16G16R16:
1843             TRACE_(d3d_caps)("[FAILED]\n"); /* Enable when implemented */
1844             return WINED3DERR_NOTAVAILABLE;
1845
1846         /* ATI instancing hack: Although ATI cards do not support Shader Model 3.0, they support
1847          * instancing. To query if the card supports instancing CheckDeviceFormat with the special format
1848          * MAKEFOURCC('I','N','S','T') is used. Should a (broken) app check for this provide a proper return value.
1849          * We can do instancing with all shader versions, but we need vertex shaders.
1850          *
1851          * Additionally applications have to set the D3DRS_POINTSIZE render state to MAKEFOURCC('I','N','S','T') once
1852          * to enable instancing. WineD3D doesn't need that and just ignores it.
1853          *
1854          * With Shader Model 3.0 capable cards Instancing 'just works' in Windows.
1855          */
1856         case WINEMAKEFOURCC('I','N','S','T'):
1857             TRACE("ATI Instancing check hack\n");
1858             if(GL_SUPPORT(ARB_VERTEX_PROGRAM) || GL_SUPPORT(ARB_VERTEX_SHADER)) {
1859                 TRACE_(d3d_caps)("[OK]\n");
1860                 return WINED3D_OK;
1861             } else {
1862                 TRACE_(d3d_caps)("[FAILED]\n");
1863                 return WINED3DERR_NOTAVAILABLE;
1864             }
1865
1866         default:
1867             break;
1868     }
1869
1870     TRACE_(d3d_caps)("[FAILED]\n");
1871     return WINED3DERR_NOTAVAILABLE;
1872 }
1873
1874 static HRESULT  WINAPI IWineD3DImpl_CheckDeviceFormatConversion(IWineD3D *iface, UINT Adapter, WINED3DDEVTYPE DeviceType,
1875                                                           WINED3DFORMAT SourceFormat, WINED3DFORMAT TargetFormat) {
1876     IWineD3DImpl *This = (IWineD3DImpl *)iface;
1877
1878     FIXME_(d3d_caps)("(%p)-> (STUB) (Adptr:%d, DevType:(%u,%s), SrcFmt:(%u,%s), TgtFmt:(%u,%s))\n",
1879           This,
1880           Adapter,
1881           DeviceType, debug_d3ddevicetype(DeviceType),
1882           SourceFormat, debug_d3dformat(SourceFormat),
1883           TargetFormat, debug_d3dformat(TargetFormat));
1884     return WINED3D_OK;
1885 }
1886
1887 /* Note: d3d8 passes in a pointer to a D3DCAPS8 structure, which is a true
1888       subset of a D3DCAPS9 structure. However, it has to come via a void *
1889       as the d3d8 interface cannot import the d3d9 header                  */
1890 static HRESULT WINAPI IWineD3DImpl_GetDeviceCaps(IWineD3D *iface, UINT Adapter, WINED3DDEVTYPE DeviceType, WINED3DCAPS* pCaps) {
1891
1892     IWineD3DImpl    *This = (IWineD3DImpl *)iface;
1893     int vs_selected_mode;
1894     int ps_selected_mode;
1895
1896     TRACE_(d3d_caps)("(%p)->(Adptr:%d, DevType: %x, pCaps: %p)\n", This, Adapter, DeviceType, pCaps);
1897
1898     if (Adapter >= IWineD3D_GetAdapterCount(iface)) {
1899         return WINED3DERR_INVALIDCALL;
1900     }
1901
1902     /* FIXME: GL info should be per adapter */
1903
1904     /* If we don't know the device settings, go query them now */
1905     if (!This->isGLInfoValid) {
1906         /* use the desktop window to fill gl caps */
1907         BOOL rc = IWineD3DImpl_FillGLCaps(iface, IWineD3DImpl_GetAdapterDisplay(iface, Adapter));
1908
1909         /* We are running off a real context, save the values */
1910         if (rc) This->isGLInfoValid = TRUE;
1911     }
1912     select_shader_mode(&This->gl_info, DeviceType, &ps_selected_mode, &vs_selected_mode);
1913
1914     /* This function should *not* be modifying GL caps
1915      * TODO: move the functionality where it belongs */
1916     select_shader_max_constants(ps_selected_mode, vs_selected_mode, &This->gl_info);
1917
1918     /* ------------------------------------------------
1919        The following fields apply to both d3d8 and d3d9
1920        ------------------------------------------------ */
1921     *pCaps->DeviceType              = (DeviceType == WINED3DDEVTYPE_HAL) ? WINED3DDEVTYPE_HAL : WINED3DDEVTYPE_REF;  /* Not quite true, but use h/w supported by opengl I suppose */
1922     *pCaps->AdapterOrdinal          = Adapter;
1923
1924     *pCaps->Caps                    = 0;
1925     *pCaps->Caps2                   = WINED3DCAPS2_CANRENDERWINDOWED |
1926                                       WINED3DCAPS2_FULLSCREENGAMMA |
1927                                       WINED3DCAPS2_DYNAMICTEXTURES;
1928     *pCaps->Caps3                   = WINED3DCAPS3_ALPHA_FULLSCREEN_FLIP_OR_DISCARD;
1929     *pCaps->PresentationIntervals   = WINED3DPRESENT_INTERVAL_IMMEDIATE;
1930
1931     *pCaps->CursorCaps              = 0;
1932
1933
1934     *pCaps->DevCaps                 = WINED3DDEVCAPS_FLOATTLVERTEX       |
1935                                       WINED3DDEVCAPS_EXECUTESYSTEMMEMORY |
1936                                       WINED3DDEVCAPS_TLVERTEXSYSTEMMEMORY|
1937                                       WINED3DDEVCAPS_TLVERTEXVIDEOMEMORY |
1938                                       WINED3DDEVCAPS_DRAWPRIMTLVERTEX    |
1939                                       WINED3DDEVCAPS_HWTRANSFORMANDLIGHT |
1940                                       WINED3DDEVCAPS_EXECUTEVIDEOMEMORY  |
1941                                       WINED3DDEVCAPS_PUREDEVICE          |
1942                                       WINED3DDEVCAPS_HWRASTERIZATION     |
1943                                       WINED3DDEVCAPS_TEXTUREVIDEOMEMORY  |
1944                                       WINED3DDEVCAPS_TEXTURESYSTEMMEMORY |
1945                                       WINED3DDEVCAPS_CANRENDERAFTERFLIP  |
1946                                       WINED3DDEVCAPS_DRAWPRIMITIVES2     |
1947                                       WINED3DDEVCAPS_DRAWPRIMITIVES2EX;
1948
1949     *pCaps->PrimitiveMiscCaps       = WINED3DPMISCCAPS_CULLNONE              |
1950                                       WINED3DPMISCCAPS_CULLCCW               |
1951                                       WINED3DPMISCCAPS_CULLCW                |
1952                                       WINED3DPMISCCAPS_COLORWRITEENABLE      |
1953                                       WINED3DPMISCCAPS_CLIPTLVERTS           |
1954                                       WINED3DPMISCCAPS_CLIPPLANESCALEDPOINTS |
1955                                       WINED3DPMISCCAPS_MASKZ                 |
1956                                       WINED3DPMISCCAPS_BLENDOP;
1957                                     /* TODO:
1958                                         WINED3DPMISCCAPS_NULLREFERENCE
1959                                         WINED3DPMISCCAPS_INDEPENDENTWRITEMASKS
1960                                         WINED3DPMISCCAPS_FOGANDSPECULARALPHA
1961                                         WINED3DPMISCCAPS_SEPARATEALPHABLEND
1962                                         WINED3DPMISCCAPS_MRTINDEPENDENTBITDEPTHS
1963                                         WINED3DPMISCCAPS_MRTPOSTPIXELSHADERBLENDING
1964                                         WINED3DPMISCCAPS_FOGVERTEXCLAMPED */
1965
1966 /* The caps below can be supported but aren't handled yet in utils.c 'd3dta_to_combiner_input', disable them until support is fixed */
1967 #if 0
1968     if (GL_SUPPORT(NV_REGISTER_COMBINERS))
1969         *pCaps->PrimitiveMiscCaps |=  WINED3DPMISCCAPS_TSSARGTEMP;
1970     if (GL_SUPPORT(NV_REGISTER_COMBINERS2))
1971         *pCaps->PrimitiveMiscCaps |=  WINED3DPMISCCAPS_PERSTAGECONSTANT;
1972 #endif
1973
1974     *pCaps->RasterCaps              = WINED3DPRASTERCAPS_DITHER    |
1975                                       WINED3DPRASTERCAPS_PAT       |
1976                                       WINED3DPRASTERCAPS_WFOG      |
1977                                       WINED3DPRASTERCAPS_ZFOG      |
1978                                       WINED3DPRASTERCAPS_FOGVERTEX |
1979                                       WINED3DPRASTERCAPS_FOGTABLE  |
1980                                       WINED3DPRASTERCAPS_FOGRANGE  |
1981                                       WINED3DPRASTERCAPS_STIPPLE   |
1982                                       WINED3DPRASTERCAPS_SUBPIXEL  |
1983                                       WINED3DPRASTERCAPS_ZTEST     |
1984                                       WINED3DPRASTERCAPS_SCISSORTEST   |
1985                                       WINED3DPRASTERCAPS_SLOPESCALEDEPTHBIAS |
1986                                       WINED3DPRASTERCAPS_DEPTHBIAS;
1987
1988     if (GL_SUPPORT(EXT_TEXTURE_FILTER_ANISOTROPIC)) {
1989       *pCaps->RasterCaps |= WINED3DPRASTERCAPS_ANISOTROPY    |
1990                             WINED3DPRASTERCAPS_ZBIAS         |
1991                             WINED3DPRASTERCAPS_MIPMAPLODBIAS;
1992     }
1993                         /* FIXME Add:
1994                            WINED3DPRASTERCAPS_COLORPERSPECTIVE
1995                            WINED3DPRASTERCAPS_STRETCHBLTMULTISAMPLE
1996                            WINED3DPRASTERCAPS_ANTIALIASEDGES
1997                            WINED3DPRASTERCAPS_ZBUFFERLESSHSR
1998                            WINED3DPRASTERCAPS_WBUFFER */
1999
2000     *pCaps->ZCmpCaps = WINED3DPCMPCAPS_ALWAYS       |
2001                        WINED3DPCMPCAPS_EQUAL        |
2002                        WINED3DPCMPCAPS_GREATER      |
2003                        WINED3DPCMPCAPS_GREATEREQUAL |
2004                        WINED3DPCMPCAPS_LESS         |
2005                        WINED3DPCMPCAPS_LESSEQUAL    |
2006                        WINED3DPCMPCAPS_NEVER        |
2007                        WINED3DPCMPCAPS_NOTEQUAL;
2008
2009     *pCaps->SrcBlendCaps  = WINED3DPBLENDCAPS_BLENDFACTOR     |
2010                             WINED3DPBLENDCAPS_BOTHINVSRCALPHA |
2011                             WINED3DPBLENDCAPS_BOTHSRCALPHA    |
2012                             WINED3DPBLENDCAPS_DESTALPHA       |
2013                             WINED3DPBLENDCAPS_DESTCOLOR       |
2014                             WINED3DPBLENDCAPS_INVDESTALPHA    |
2015                             WINED3DPBLENDCAPS_INVDESTCOLOR    |
2016                             WINED3DPBLENDCAPS_INVSRCALPHA     |
2017                             WINED3DPBLENDCAPS_INVSRCCOLOR     |
2018                             WINED3DPBLENDCAPS_ONE             |
2019                             WINED3DPBLENDCAPS_SRCALPHA        |
2020                             WINED3DPBLENDCAPS_SRCALPHASAT     |
2021                             WINED3DPBLENDCAPS_SRCCOLOR        |
2022                             WINED3DPBLENDCAPS_ZERO;
2023
2024     *pCaps->DestBlendCaps = WINED3DPBLENDCAPS_BLENDFACTOR     |
2025                             WINED3DPBLENDCAPS_BOTHINVSRCALPHA |
2026                             WINED3DPBLENDCAPS_BOTHSRCALPHA    |
2027                             WINED3DPBLENDCAPS_DESTALPHA       |
2028                             WINED3DPBLENDCAPS_DESTCOLOR       |
2029                             WINED3DPBLENDCAPS_INVDESTALPHA    |
2030                             WINED3DPBLENDCAPS_INVDESTCOLOR    |
2031                             WINED3DPBLENDCAPS_INVSRCALPHA     |
2032                             WINED3DPBLENDCAPS_INVSRCCOLOR     |
2033                             WINED3DPBLENDCAPS_ONE             |
2034                             WINED3DPBLENDCAPS_SRCALPHA        |
2035                             WINED3DPBLENDCAPS_SRCALPHASAT     |
2036                             WINED3DPBLENDCAPS_SRCCOLOR        |
2037                             WINED3DPBLENDCAPS_ZERO;
2038
2039     *pCaps->AlphaCmpCaps = WINED3DPCMPCAPS_ALWAYS       |
2040                            WINED3DPCMPCAPS_EQUAL        |
2041                            WINED3DPCMPCAPS_GREATER      |
2042                            WINED3DPCMPCAPS_GREATEREQUAL |
2043                            WINED3DPCMPCAPS_LESS         |
2044                            WINED3DPCMPCAPS_LESSEQUAL    |
2045                            WINED3DPCMPCAPS_NEVER        |
2046                            WINED3DPCMPCAPS_NOTEQUAL;
2047
2048     *pCaps->ShadeCaps     = WINED3DPSHADECAPS_SPECULARGOURAUDRGB |
2049                             WINED3DPSHADECAPS_COLORGOURAUDRGB    |
2050                             WINED3DPSHADECAPS_ALPHAFLATBLEND     |
2051                             WINED3DPSHADECAPS_ALPHAGOURAUDBLEND  |
2052                             WINED3DPSHADECAPS_COLORFLATRGB       |
2053                             WINED3DPSHADECAPS_FOGFLAT            |
2054                             WINED3DPSHADECAPS_FOGGOURAUD         |
2055                             WINED3DPSHADECAPS_SPECULARFLATRGB;
2056
2057     *pCaps->TextureCaps =  WINED3DPTEXTURECAPS_ALPHA              |
2058                            WINED3DPTEXTURECAPS_ALPHAPALETTE       |
2059                            WINED3DPTEXTURECAPS_BORDER             |
2060                            WINED3DPTEXTURECAPS_MIPMAP             |
2061                            WINED3DPTEXTURECAPS_PROJECTED          |
2062                            WINED3DPTEXTURECAPS_PERSPECTIVE        |
2063                            WINED3DPTEXTURECAPS_NONPOW2CONDITIONAL;
2064
2065     if( GL_SUPPORT(EXT_TEXTURE3D)) {
2066         *pCaps->TextureCaps |=  WINED3DPTEXTURECAPS_VOLUMEMAP      |
2067                                 WINED3DPTEXTURECAPS_MIPVOLUMEMAP   |
2068                                 WINED3DPTEXTURECAPS_VOLUMEMAP_POW2;
2069     }
2070
2071     if (GL_SUPPORT(ARB_TEXTURE_CUBE_MAP)) {
2072         *pCaps->TextureCaps |= WINED3DPTEXTURECAPS_CUBEMAP     |
2073                              WINED3DPTEXTURECAPS_MIPCUBEMAP    |
2074                              WINED3DPTEXTURECAPS_CUBEMAP_POW2;
2075
2076     }
2077
2078     *pCaps->TextureFilterCaps = WINED3DPTFILTERCAPS_MAGFLINEAR       |
2079                                 WINED3DPTFILTERCAPS_MAGFPOINT        |
2080                                 WINED3DPTFILTERCAPS_MINFLINEAR       |
2081                                 WINED3DPTFILTERCAPS_MINFPOINT        |
2082                                 WINED3DPTFILTERCAPS_MIPFLINEAR       |
2083                                 WINED3DPTFILTERCAPS_MIPFPOINT        |
2084                                 WINED3DPTFILTERCAPS_LINEAR           |
2085                                 WINED3DPTFILTERCAPS_LINEARMIPLINEAR  |
2086                                 WINED3DPTFILTERCAPS_LINEARMIPNEAREST |
2087                                 WINED3DPTFILTERCAPS_MIPLINEAR        |
2088                                 WINED3DPTFILTERCAPS_MIPNEAREST       |
2089                                 WINED3DPTFILTERCAPS_NEAREST;
2090
2091     if (GL_SUPPORT(EXT_TEXTURE_FILTER_ANISOTROPIC)) {
2092         *pCaps->TextureFilterCaps |= WINED3DPTFILTERCAPS_MAGFANISOTROPIC |
2093                                      WINED3DPTFILTERCAPS_MINFANISOTROPIC;
2094     }
2095
2096     if (GL_SUPPORT(ARB_TEXTURE_CUBE_MAP)) {
2097         *pCaps->CubeTextureFilterCaps = 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
2110         if (GL_SUPPORT(EXT_TEXTURE_FILTER_ANISOTROPIC)) {
2111             *pCaps->CubeTextureFilterCaps |= WINED3DPTFILTERCAPS_MAGFANISOTROPIC |
2112                                             WINED3DPTFILTERCAPS_MINFANISOTROPIC;
2113         }
2114     } else
2115         *pCaps->CubeTextureFilterCaps = 0;
2116
2117     if (GL_SUPPORT(EXT_TEXTURE3D)) {
2118         *pCaps->VolumeTextureFilterCaps = WINED3DPTFILTERCAPS_MAGFLINEAR       |
2119                                           WINED3DPTFILTERCAPS_MAGFPOINT        |
2120                                           WINED3DPTFILTERCAPS_MINFLINEAR       |
2121                                           WINED3DPTFILTERCAPS_MINFPOINT        |
2122                                           WINED3DPTFILTERCAPS_MIPFLINEAR       |
2123                                           WINED3DPTFILTERCAPS_MIPFPOINT        |
2124                                           WINED3DPTFILTERCAPS_LINEAR           |
2125                                           WINED3DPTFILTERCAPS_LINEARMIPLINEAR  |
2126                                           WINED3DPTFILTERCAPS_LINEARMIPNEAREST |
2127                                           WINED3DPTFILTERCAPS_MIPLINEAR        |
2128                                           WINED3DPTFILTERCAPS_MIPNEAREST       |
2129                                           WINED3DPTFILTERCAPS_NEAREST;
2130     } else
2131         *pCaps->VolumeTextureFilterCaps = 0;
2132
2133     *pCaps->TextureAddressCaps =  WINED3DPTADDRESSCAPS_INDEPENDENTUV |
2134                                   WINED3DPTADDRESSCAPS_CLAMP  |
2135                                   WINED3DPTADDRESSCAPS_WRAP;
2136
2137     if (GL_SUPPORT(ARB_TEXTURE_BORDER_CLAMP)) {
2138         *pCaps->TextureAddressCaps |= WINED3DPTADDRESSCAPS_BORDER;
2139     }
2140     if (GL_SUPPORT(ARB_TEXTURE_MIRRORED_REPEAT)) {
2141         *pCaps->TextureAddressCaps |= WINED3DPTADDRESSCAPS_MIRROR;
2142     }
2143     if (GL_SUPPORT(ATI_TEXTURE_MIRROR_ONCE)) {
2144         *pCaps->TextureAddressCaps |= WINED3DPTADDRESSCAPS_MIRRORONCE;
2145     }
2146
2147     if (GL_SUPPORT(EXT_TEXTURE3D)) {
2148         *pCaps->VolumeTextureAddressCaps =  WINED3DPTADDRESSCAPS_INDEPENDENTUV |
2149                                             WINED3DPTADDRESSCAPS_CLAMP  |
2150                                             WINED3DPTADDRESSCAPS_WRAP;
2151         if (GL_SUPPORT(ARB_TEXTURE_BORDER_CLAMP)) {
2152             *pCaps->VolumeTextureAddressCaps |= WINED3DPTADDRESSCAPS_BORDER;
2153         }
2154         if (GL_SUPPORT(ARB_TEXTURE_MIRRORED_REPEAT)) {
2155             *pCaps->VolumeTextureAddressCaps |= WINED3DPTADDRESSCAPS_MIRROR;
2156         }
2157         if (GL_SUPPORT(ATI_TEXTURE_MIRROR_ONCE)) {
2158             *pCaps->VolumeTextureAddressCaps |= WINED3DPTADDRESSCAPS_MIRRORONCE;
2159         }
2160     } else
2161         *pCaps->VolumeTextureAddressCaps = 0;
2162
2163     *pCaps->LineCaps = WINED3DLINECAPS_TEXTURE |
2164                        WINED3DLINECAPS_ZTEST;
2165                       /* FIXME: Add
2166                         WINED3DLINECAPS_BLEND
2167                         WINED3DLINECAPS_ALPHACMP
2168                         WINED3DLINECAPS_FOG */
2169
2170     *pCaps->MaxTextureWidth  = GL_LIMITS(texture_size);
2171     *pCaps->MaxTextureHeight = GL_LIMITS(texture_size);
2172
2173     if(GL_SUPPORT(EXT_TEXTURE3D))
2174         *pCaps->MaxVolumeExtent = GL_LIMITS(texture3d_size);
2175     else
2176         *pCaps->MaxVolumeExtent = 0;
2177
2178     *pCaps->MaxTextureRepeat = 32768;
2179     *pCaps->MaxTextureAspectRatio = GL_LIMITS(texture_size);
2180     *pCaps->MaxVertexW = 1.0;
2181
2182     *pCaps->GuardBandLeft = 0;
2183     *pCaps->GuardBandTop = 0;
2184     *pCaps->GuardBandRight = 0;
2185     *pCaps->GuardBandBottom = 0;
2186
2187     *pCaps->ExtentsAdjust = 0;
2188
2189     *pCaps->StencilCaps =  WINED3DSTENCILCAPS_DECRSAT |
2190                            WINED3DSTENCILCAPS_INCRSAT |
2191                            WINED3DSTENCILCAPS_INVERT  |
2192                            WINED3DSTENCILCAPS_KEEP    |
2193                            WINED3DSTENCILCAPS_REPLACE |
2194                            WINED3DSTENCILCAPS_ZERO;
2195     if (GL_SUPPORT(EXT_STENCIL_WRAP)) {
2196       *pCaps->StencilCaps |= WINED3DSTENCILCAPS_DECR  |
2197                              WINED3DSTENCILCAPS_INCR;
2198     }
2199     if ( This->dxVersion > 8 &&
2200         ( GL_SUPPORT(EXT_STENCIL_TWO_SIDE) ||
2201             GL_SUPPORT(ATI_SEPARATE_STENCIL) ) ) {
2202         *pCaps->StencilCaps |= WINED3DSTENCILCAPS_TWOSIDED;
2203     }
2204
2205     *pCaps->FVFCaps = WINED3DFVFCAPS_PSIZE | 0x0008; /* 8 texture coords */
2206
2207     *pCaps->TextureOpCaps =  WINED3DTEXOPCAPS_ADD         |
2208                              WINED3DTEXOPCAPS_ADDSIGNED   |
2209                              WINED3DTEXOPCAPS_ADDSIGNED2X |
2210                              WINED3DTEXOPCAPS_MODULATE    |
2211                              WINED3DTEXOPCAPS_MODULATE2X  |
2212                              WINED3DTEXOPCAPS_MODULATE4X  |
2213                              WINED3DTEXOPCAPS_SELECTARG1  |
2214                              WINED3DTEXOPCAPS_SELECTARG2  |
2215                              WINED3DTEXOPCAPS_DISABLE;
2216
2217     if (GL_SUPPORT(ARB_TEXTURE_ENV_COMBINE) ||
2218         GL_SUPPORT(EXT_TEXTURE_ENV_COMBINE) ||
2219         GL_SUPPORT(NV_TEXTURE_ENV_COMBINE4)) {
2220         *pCaps->TextureOpCaps |= WINED3DTEXOPCAPS_BLENDDIFFUSEALPHA |
2221                                 WINED3DTEXOPCAPS_BLENDTEXTUREALPHA  |
2222                                 WINED3DTEXOPCAPS_BLENDFACTORALPHA   |
2223                                 WINED3DTEXOPCAPS_BLENDCURRENTALPHA  |
2224                                 WINED3DTEXOPCAPS_LERP               |
2225                                 WINED3DTEXOPCAPS_SUBTRACT;
2226     }
2227     if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3) ||
2228          GL_SUPPORT(NV_TEXTURE_ENV_COMBINE4)) {
2229         *pCaps->TextureOpCaps |= WINED3DTEXOPCAPS_ADDSMOOTH             |
2230                                 WINED3DTEXOPCAPS_MULTIPLYADD            |
2231                                 WINED3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR |
2232                                 WINED3DTEXOPCAPS_MODULATECOLOR_ADDALPHA |
2233                                 WINED3DTEXOPCAPS_BLENDTEXTUREALPHAPM;
2234     }
2235     if (GL_SUPPORT(ARB_TEXTURE_ENV_DOT3))
2236         *pCaps->TextureOpCaps |= WINED3DTEXOPCAPS_DOTPRODUCT3;
2237
2238     if (GL_SUPPORT(NV_REGISTER_COMBINERS)) {
2239         *pCaps->TextureOpCaps |= WINED3DTEXOPCAPS_MODULATEINVALPHA_ADDCOLOR |
2240                                  WINED3DTEXOPCAPS_MODULATEINVCOLOR_ADDALPHA;
2241     }
2242
2243     if(GL_SUPPORT(ATI_ENVMAP_BUMPMAP)) {
2244         *pCaps->TextureOpCaps |= WINED3DTEXOPCAPS_BUMPENVMAP;
2245     } else if(GL_SUPPORT(NV_TEXTURE_SHADER2)) {
2246         /* Bump mapping is supported already in NV_TEXTURE_SHADER, but that extension does
2247          * not support 3D textures. This asks for trouble if an app uses both bump mapping
2248          * and 3D textures. It also allows us to keep the code simpler by having texture
2249          * shaders constantly enabled.
2250          */
2251         *pCaps->TextureOpCaps |= WINED3DTEXOPCAPS_BUMPENVMAP;
2252         /* TODO: Luminance bump map? */
2253     }
2254 #if 0
2255     /* FIXME: Add
2256     *pCaps->TextureOpCaps |= WINED3DTEXOPCAPS_BUMPENVMAPLUMINANCE
2257                              WINED3DTEXOPCAPS_PREMODULATE */
2258 #endif
2259
2260     *pCaps->MaxTextureBlendStages   = GL_LIMITS(texture_stages);
2261     *pCaps->MaxSimultaneousTextures = GL_LIMITS(textures);
2262     *pCaps->MaxUserClipPlanes       = GL_LIMITS(clipplanes);
2263     *pCaps->MaxActiveLights         = GL_LIMITS(lights);
2264
2265     *pCaps->MaxVertexBlendMatrices      = GL_LIMITS(blends);
2266     *pCaps->MaxVertexBlendMatrixIndex   = 0;
2267
2268     *pCaps->MaxAnisotropy   = GL_LIMITS(anisotropy);
2269     *pCaps->MaxPointSize    = GL_LIMITS(pointsize);
2270
2271
2272     *pCaps->VertexProcessingCaps = WINED3DVTXPCAPS_DIRECTIONALLIGHTS |
2273                                    WINED3DVTXPCAPS_MATERIALSOURCE7   |
2274                                    WINED3DVTXPCAPS_POSITIONALLIGHTS  |
2275                                    WINED3DVTXPCAPS_LOCALVIEWER       |
2276                                    WINED3DVTXPCAPS_VERTEXFOG         |
2277                                    WINED3DVTXPCAPS_TEXGEN;
2278                                   /* FIXME: Add 
2279                                      D3DVTXPCAPS_TWEENING, D3DVTXPCAPS_TEXGEN_SPHEREMAP */
2280
2281     *pCaps->MaxPrimitiveCount   = 0xFFFFF; /* For now set 2^20-1 which is used by most >=Geforce3/Radeon8500 cards */
2282     *pCaps->MaxVertexIndex      = 0xFFFFF;
2283     *pCaps->MaxStreams          = MAX_STREAMS;
2284     *pCaps->MaxStreamStride     = 1024;
2285
2286     if (vs_selected_mode == SHADER_GLSL) {
2287         /* Nvidia Geforce6/7 or Ati R4xx/R5xx cards with GLSL support, support VS 3.0 but older Nvidia/Ati
2288            models with GLSL support only support 2.0. In case of nvidia we can detect VS 2.0 support using
2289            vs_nv_version which is based on NV_vertex_program. For Ati cards there's no easy way, so for
2290            now only support 2.0/3.0 detection on Nvidia GeforceFX cards and default to 3.0 for everything else */
2291         if(This->gl_info.vs_nv_version == VS_VERSION_20)
2292             *pCaps->VertexShaderVersion = WINED3DVS_VERSION(2,0);
2293         else
2294             *pCaps->VertexShaderVersion = WINED3DVS_VERSION(3,0);
2295         TRACE_(d3d_caps)("Hardware vertex shader version 3.0 enabled (GLSL)\n");
2296     } else if (vs_selected_mode == SHADER_ARB) {
2297         *pCaps->VertexShaderVersion = WINED3DVS_VERSION(1,1);
2298         TRACE_(d3d_caps)("Hardware vertex shader version 1.1 enabled (ARB_PROGRAM)\n");
2299     } else {
2300         *pCaps->VertexShaderVersion  = 0;
2301         TRACE_(d3d_caps)("Vertex shader functionality not available\n");
2302     }
2303
2304     *pCaps->MaxVertexShaderConst = GL_LIMITS(vshader_constantsF);
2305
2306     if (ps_selected_mode == SHADER_GLSL) {
2307         /* See the comment about VS2.0/VS3.0 detection as we do the same here but then based on NV_fragment_program
2308            in case of GeforceFX cards. */
2309         if(This->gl_info.ps_nv_version == PS_VERSION_20)
2310             *pCaps->PixelShaderVersion = WINED3DPS_VERSION(2,0);
2311         else
2312             *pCaps->PixelShaderVersion = WINED3DPS_VERSION(3,0);
2313         /* FIXME: The following line is card dependent. -1.0 to 1.0 is a safe default clamp range for now */
2314         *pCaps->PixelShader1xMaxValue = 1.0;
2315         TRACE_(d3d_caps)("Hardware pixel shader version 3.0 enabled (GLSL)\n");
2316     } else if (ps_selected_mode == SHADER_ARB) {
2317         *pCaps->PixelShaderVersion    = WINED3DPS_VERSION(1,4);
2318         *pCaps->PixelShader1xMaxValue = 1.0;
2319         TRACE_(d3d_caps)("Hardware pixel shader version 1.4 enabled (ARB_PROGRAM)\n");
2320     } else {
2321         *pCaps->PixelShaderVersion    = 0;
2322         *pCaps->PixelShader1xMaxValue = 0.0;
2323         TRACE_(d3d_caps)("Pixel shader functionality not available\n");
2324     }
2325
2326     /* ------------------------------------------------
2327        The following fields apply to d3d9 only
2328        ------------------------------------------------ */
2329     if (This->dxVersion > 8) {
2330         /* d3d9.dll sets D3DDEVCAPS2_CAN_STRETCHRECT_FROM_TEXTURES here because StretchRects is implemented in d3d9 */
2331         *pCaps->DevCaps2                          = WINED3DDEVCAPS2_STREAMOFFSET;
2332         /* TODO: VS3.0 needs at least D3DDEVCAPS2_VERTEXELEMENTSCANSHARESTREAMOFFSET */
2333         *pCaps->MaxNpatchTessellationLevel        = 0;
2334         *pCaps->MasterAdapterOrdinal              = 0;
2335         *pCaps->AdapterOrdinalInGroup             = 0;
2336         *pCaps->NumberOfAdaptersInGroup           = 1;
2337
2338         if(*pCaps->VertexShaderVersion >= WINED3DVS_VERSION(2,0)) {
2339             /* OpenGL supports all the formats below, perhaps not always
2340              * without conversion, but it supports them.
2341              * Further GLSL doesn't seem to have an official unsigned type so
2342              * don't advertise it yet as I'm not sure how we handle it.
2343              * We might need to add some clamping in the shader engine to
2344              * support it.
2345              * TODO: WINED3DDTCAPS_USHORT2N, WINED3DDTCAPS_USHORT4N, WINED3DDTCAPS_UDEC3, WINED3DDTCAPS_DEC3N */
2346             *pCaps->DeclTypes = WINED3DDTCAPS_UBYTE4    |
2347                                 WINED3DDTCAPS_UBYTE4N   |
2348                                 WINED3DDTCAPS_SHORT2N   |
2349                                 WINED3DDTCAPS_SHORT4N   |
2350                                 WINED3DDTCAPS_FLOAT16_2 |
2351                                 WINED3DDTCAPS_FLOAT16_4;
2352
2353         } else
2354             *pCaps->DeclTypes                         = 0;
2355
2356         *pCaps->NumSimultaneousRTs = GL_LIMITS(buffers);
2357
2358             
2359         *pCaps->StretchRectFilterCaps             = WINED3DPTFILTERCAPS_MINFPOINT  |
2360                                                     WINED3DPTFILTERCAPS_MAGFPOINT  |
2361                                                     WINED3DPTFILTERCAPS_MINFLINEAR |
2362                                                     WINED3DPTFILTERCAPS_MAGFLINEAR;
2363         *pCaps->VertexTextureFilterCaps           = 0;
2364         
2365         if(*pCaps->VertexShaderVersion == WINED3DVS_VERSION(3,0)) {
2366             /* Where possible set the caps based on OpenGL extensions and if they aren't set (in case of software rendering)
2367                use the VS 3.0 from MSDN or else if there's OpenGL spec use a hardcoded value minimum VS3.0 value. */
2368             *pCaps->VS20Caps.Caps                     = WINED3DVS20CAPS_PREDICATION;
2369             *pCaps->VS20Caps.DynamicFlowControlDepth  = WINED3DVS20_MAX_DYNAMICFLOWCONTROLDEPTH; /* VS 3.0 requires MAX_DYNAMICFLOWCONTROLDEPTH (24) */
2370             *pCaps->VS20Caps.NumTemps                 = max(32, This->gl_info.vs_arb_max_temps);
2371             *pCaps->VS20Caps.StaticFlowControlDepth   = WINED3DVS20_MAX_STATICFLOWCONTROLDEPTH ; /* level of nesting in loops / if-statements; VS 3.0 requires MAX (4) */
2372
2373             *pCaps->MaxVShaderInstructionsExecuted    = 65535; /* VS 3.0 needs at least 65535, some cards even use 2^32-1 */
2374             *pCaps->MaxVertexShader30InstructionSlots = max(512, This->gl_info.vs_arb_max_instructions);
2375         } else if(*pCaps->VertexShaderVersion == WINED3DVS_VERSION(2,0)) {
2376             *pCaps->VS20Caps.Caps                     = 0;
2377             *pCaps->VS20Caps.DynamicFlowControlDepth  = WINED3DVS20_MIN_DYNAMICFLOWCONTROLDEPTH;
2378             *pCaps->VS20Caps.NumTemps                 = max(12, This->gl_info.vs_arb_max_temps);
2379             *pCaps->VS20Caps.StaticFlowControlDepth   = 1;    
2380
2381             *pCaps->MaxVShaderInstructionsExecuted    = 65535;
2382             *pCaps->MaxVertexShader30InstructionSlots = 0;
2383         } else { /* VS 1.x */
2384             *pCaps->VS20Caps.Caps                     = 0;
2385             *pCaps->VS20Caps.DynamicFlowControlDepth  = 0;
2386             *pCaps->VS20Caps.NumTemps                 = 0;
2387             *pCaps->VS20Caps.StaticFlowControlDepth   = 0;    
2388
2389             *pCaps->MaxVShaderInstructionsExecuted    = 0;
2390             *pCaps->MaxVertexShader30InstructionSlots = 0;        
2391         }
2392
2393         if(*pCaps->PixelShaderVersion == WINED3DPS_VERSION(3,0)) {
2394             /* Where possible set the caps based on OpenGL extensions and if they aren't set (in case of software rendering)
2395                use the PS 3.0 from MSDN or else if there's OpenGL spec use a hardcoded value minimum PS 3.0 value. */
2396             
2397             /* 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 */
2398             *pCaps->PS20Caps.Caps                     = WINED3DPS20CAPS_ARBITRARYSWIZZLE     |
2399                                                         WINED3DPS20CAPS_GRADIENTINSTRUCTIONS |
2400                                                         WINED3DPS20CAPS_PREDICATION          |
2401                                                         WINED3DPS20CAPS_NODEPENDENTREADLIMIT |
2402                                                         WINED3DPS20CAPS_NOTEXINSTRUCTIONLIMIT;
2403             *pCaps->PS20Caps.DynamicFlowControlDepth  = WINED3DPS20_MAX_DYNAMICFLOWCONTROLDEPTH; /* PS 3.0 requires MAX_DYNAMICFLOWCONTROLDEPTH (24) */
2404             *pCaps->PS20Caps.NumTemps                 = max(32, This->gl_info.ps_arb_max_temps);
2405             *pCaps->PS20Caps.StaticFlowControlDepth   = WINED3DPS20_MAX_STATICFLOWCONTROLDEPTH; /* PS 3.0 requires MAX_STATICFLOWCONTROLDEPTH (4) */
2406             *pCaps->PS20Caps.NumInstructionSlots      = WINED3DPS20_MAX_NUMINSTRUCTIONSLOTS; /* PS 3.0 requires MAX_NUMINSTRUCTIONSLOTS (512) */
2407
2408             *pCaps->MaxPShaderInstructionsExecuted    = 65535;
2409             *pCaps->MaxPixelShader30InstructionSlots  = max(WINED3DMIN30SHADERINSTRUCTIONS, This->gl_info.ps_arb_max_instructions);
2410         } else if(*pCaps->PixelShaderVersion == WINED3DPS_VERSION(2,0)) {
2411             /* Below we assume PS2.0 specs, not extended 2.0a(GeforceFX)/2.0b(Radeon R3xx) ones */
2412             *pCaps->PS20Caps.Caps                     = 0;
2413             *pCaps->PS20Caps.DynamicFlowControlDepth  = 0; /* WINED3DVS20_MIN_DYNAMICFLOWCONTROLDEPTH = 0 */
2414             *pCaps->PS20Caps.NumTemps                 = max(12, This->gl_info.ps_arb_max_temps);
2415             *pCaps->PS20Caps.StaticFlowControlDepth   = WINED3DPS20_MIN_STATICFLOWCONTROLDEPTH; /* Minumum: 1 */
2416             *pCaps->PS20Caps.NumInstructionSlots      = WINED3DPS20_MIN_NUMINSTRUCTIONSLOTS; /* Minimum number (64 ALU + 32 Texture), a GeforceFX uses 512 */
2417
2418             *pCaps->MaxPShaderInstructionsExecuted    = 512; /* Minimum value, a GeforceFX uses 1024 */
2419             *pCaps->MaxPixelShader30InstructionSlots  = 0;
2420         } else { /* PS 1.x */
2421             *pCaps->PS20Caps.Caps                     = 0;
2422             *pCaps->PS20Caps.DynamicFlowControlDepth  = 0;
2423             *pCaps->PS20Caps.NumTemps                 = 0;
2424             *pCaps->PS20Caps.StaticFlowControlDepth   = 0;
2425             *pCaps->PS20Caps.NumInstructionSlots      = 0;
2426
2427             *pCaps->MaxPShaderInstructionsExecuted    = 0;
2428             *pCaps->MaxPixelShader30InstructionSlots  = 0;
2429         }
2430     }
2431
2432     return WINED3D_OK;
2433 }
2434
2435 static unsigned int glsl_program_key_hash(void *key) {
2436     glsl_program_key_t *k = (glsl_program_key_t *)key;
2437
2438     unsigned int hash = k->vshader | k->pshader << 16;
2439     hash += ~(hash << 15);
2440     hash ^=  (hash >> 10);
2441     hash +=  (hash << 3);
2442     hash ^=  (hash >> 6);
2443     hash += ~(hash << 11);
2444     hash ^=  (hash >> 16);
2445
2446     return hash;
2447 }
2448
2449 static BOOL glsl_program_key_compare(void *keya, void *keyb) {
2450     glsl_program_key_t *ka = (glsl_program_key_t *)keya;
2451     glsl_program_key_t *kb = (glsl_program_key_t *)keyb;
2452
2453     return ka->vshader == kb->vshader && ka->pshader == kb->pshader;
2454 }
2455
2456 /* Note due to structure differences between dx8 and dx9 D3DPRESENT_PARAMETERS,
2457    and fields being inserted in the middle, a new structure is used in place    */
2458 static HRESULT  WINAPI IWineD3DImpl_CreateDevice(IWineD3D *iface, UINT Adapter, WINED3DDEVTYPE DeviceType, HWND hFocusWindow,
2459                                            DWORD BehaviourFlags, IWineD3DDevice** ppReturnedDeviceInterface,
2460                                            IUnknown *parent) {
2461
2462     IWineD3DDeviceImpl *object  = NULL;
2463     IWineD3DImpl       *This    = (IWineD3DImpl *)iface;
2464     HDC hDC;
2465     HRESULT temp_result;
2466
2467     /* Validate the adapter number */
2468     if (Adapter >= IWineD3D_GetAdapterCount(iface)) {
2469         return WINED3DERR_INVALIDCALL;
2470     }
2471
2472     /* Create a WineD3DDevice object */
2473     object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IWineD3DDeviceImpl));
2474     *ppReturnedDeviceInterface = (IWineD3DDevice *)object;
2475     TRACE("Created WineD3DDevice object @ %p\n", object);
2476     if (NULL == object) {
2477       return WINED3DERR_OUTOFVIDEOMEMORY;
2478     }
2479
2480     /* Set up initial COM information */
2481     object->lpVtbl  = &IWineD3DDevice_Vtbl;
2482     object->ref     = 1;
2483     object->wineD3D = iface;
2484     IWineD3D_AddRef(object->wineD3D);
2485     object->parent  = parent;
2486
2487     /* Set the state up as invalid until the device is fully created */
2488     object->state   = WINED3DERR_DRIVERINTERNALERROR;
2489
2490     TRACE("(%p)->(Adptr:%d, DevType: %x, FocusHwnd: %p, BehFlags: %x, RetDevInt: %p)\n", This, Adapter, DeviceType,
2491           hFocusWindow, BehaviourFlags, ppReturnedDeviceInterface);
2492
2493     /* Save the creation parameters */
2494     object->createParms.AdapterOrdinal = Adapter;
2495     object->createParms.DeviceType     = DeviceType;
2496     object->createParms.hFocusWindow   = hFocusWindow;
2497     object->createParms.BehaviorFlags  = BehaviourFlags;
2498
2499     /* Initialize other useful values */
2500     object->adapterNo                    = Adapter;
2501     object->devType                      = DeviceType;
2502
2503     TRACE("(%p) : Creating stateblock\n", This);
2504     /* Creating the startup stateBlock - Note Special Case: 0 => Don't fill in yet! */
2505     if (WINED3D_OK != IWineD3DDevice_CreateStateBlock((IWineD3DDevice *)object,
2506                                       WINED3DSBT_INIT,
2507                                     (IWineD3DStateBlock **)&object->stateBlock,
2508                                     NULL)  || NULL == object->stateBlock) {   /* Note: No parent needed for initial internal stateblock */
2509         WARN("Failed to create stateblock\n");
2510         goto create_device_error;
2511     }
2512     TRACE("(%p) : Created stateblock (%p)\n", This, object->stateBlock);
2513     object->updateStateBlock = object->stateBlock;
2514     IWineD3DStateBlock_AddRef((IWineD3DStateBlock*)object->updateStateBlock);
2515     /* Setup surfaces for the backbuffer, frontbuffer and depthstencil buffer */
2516
2517     /* Setup some defaults for creating the implicit swapchain */
2518     ENTER_GL();
2519     /* FIXME: GL info should be per adapter */
2520     IWineD3DImpl_FillGLCaps(iface, IWineD3DImpl_GetAdapterDisplay(iface, Adapter));
2521     LEAVE_GL();
2522     select_shader_mode(&This->gl_info, DeviceType, &object->ps_selected_mode, &object->vs_selected_mode);
2523     if (object->ps_selected_mode == SHADER_GLSL || object->vs_selected_mode == SHADER_GLSL) {
2524         object->shader_backend = &glsl_shader_backend;
2525         object->glsl_program_lookup = hash_table_create(&glsl_program_key_hash, &glsl_program_key_compare);
2526     } else if (object->ps_selected_mode == SHADER_ARB || object->vs_selected_mode == SHADER_ARB) {
2527         object->shader_backend = &arb_program_shader_backend;
2528     } else {
2529         object->shader_backend = &none_shader_backend;
2530     }
2531
2532     /* This function should *not* be modifying GL caps
2533      * TODO: move the functionality where it belongs */
2534     select_shader_max_constants(object->ps_selected_mode, object->vs_selected_mode, &This->gl_info);
2535
2536     temp_result = allocate_shader_constants(object->updateStateBlock);
2537     if (WINED3D_OK != temp_result)
2538         return temp_result;
2539
2540     object->render_targets = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IWineD3DSurface *) * GL_LIMITS(buffers));
2541     object->fbo_color_attachments = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IWineD3DSurface *) * GL_LIMITS(buffers));
2542     object->draw_buffers = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(GLenum) * GL_LIMITS(buffers));
2543
2544     /* set the state of the device to valid */
2545     object->state = WINED3D_OK;
2546
2547     /* Get the initial screen setup for ddraw */
2548     object->ddraw_width = GetSystemMetrics(SM_CXSCREEN);
2549     object->ddraw_height = GetSystemMetrics(SM_CYSCREEN);
2550     hDC = GetDC(0);
2551     object->ddraw_format = pixelformat_for_depth(GetDeviceCaps(hDC, BITSPIXEL) * GetDeviceCaps(hDC, PLANES));
2552     ReleaseDC(0, hDC);
2553
2554     return WINED3D_OK;
2555 create_device_error:
2556
2557     /* Set the device state to error */
2558     object->state = WINED3DERR_DRIVERINTERNALERROR;
2559
2560     if (object->updateStateBlock != NULL) {
2561         IWineD3DStateBlock_Release((IWineD3DStateBlock *)object->updateStateBlock);
2562         object->updateStateBlock = NULL;
2563     }
2564     if (object->stateBlock != NULL) {
2565         IWineD3DStateBlock_Release((IWineD3DStateBlock *)object->stateBlock);
2566         object->stateBlock = NULL;
2567     }
2568     if (object->render_targets[0] != NULL) {
2569         IWineD3DSurface_Release(object->render_targets[0]);
2570         object->render_targets[0] = NULL;
2571     }
2572     if (object->stencilBufferTarget != NULL) {
2573         IWineD3DSurface_Release(object->stencilBufferTarget);
2574         object->stencilBufferTarget = NULL;
2575     }
2576     HeapFree(GetProcessHeap(), 0, object);
2577     *ppReturnedDeviceInterface = NULL;
2578     return WINED3DERR_INVALIDCALL;
2579
2580 }
2581
2582 static HRESULT WINAPI IWineD3DImpl_GetParent(IWineD3D *iface, IUnknown **pParent) {
2583     IWineD3DImpl *This = (IWineD3DImpl *)iface;
2584     IUnknown_AddRef(This->parent);
2585     *pParent = This->parent;
2586     return WINED3D_OK;
2587 }
2588
2589 ULONG WINAPI D3DCB_DefaultDestroySurface(IWineD3DSurface *pSurface) {
2590     IUnknown* surfaceParent;
2591     TRACE("(%p) call back\n", pSurface);
2592
2593     /* Now, release the parent, which will take care of cleaning up the surface for us */
2594     IWineD3DSurface_GetParent(pSurface, &surfaceParent);
2595     IUnknown_Release(surfaceParent);
2596     return IUnknown_Release(surfaceParent);
2597 }
2598
2599 ULONG WINAPI D3DCB_DefaultDestroyVolume(IWineD3DVolume *pVolume) {
2600     IUnknown* volumeParent;
2601     TRACE("(%p) call back\n", pVolume);
2602
2603     /* Now, release the parent, which will take care of cleaning up the volume for us */
2604     IWineD3DVolume_GetParent(pVolume, &volumeParent);
2605     IUnknown_Release(volumeParent);
2606     return IUnknown_Release(volumeParent);
2607 }
2608
2609 /**********************************************************
2610  * IWineD3D VTbl follows
2611  **********************************************************/
2612
2613 const IWineD3DVtbl IWineD3D_Vtbl =
2614 {
2615     /* IUnknown */
2616     IWineD3DImpl_QueryInterface,
2617     IWineD3DImpl_AddRef,
2618     IWineD3DImpl_Release,
2619     /* IWineD3D */
2620     IWineD3DImpl_GetParent,
2621     IWineD3DImpl_GetAdapterCount,
2622     IWineD3DImpl_RegisterSoftwareDevice,
2623     IWineD3DImpl_GetAdapterMonitor,
2624     IWineD3DImpl_GetAdapterModeCount,
2625     IWineD3DImpl_EnumAdapterModes,
2626     IWineD3DImpl_GetAdapterDisplayMode,
2627     IWineD3DImpl_GetAdapterIdentifier,
2628     IWineD3DImpl_CheckDeviceMultiSampleType,
2629     IWineD3DImpl_CheckDepthStencilMatch,
2630     IWineD3DImpl_CheckDeviceType,
2631     IWineD3DImpl_CheckDeviceFormat,
2632     IWineD3DImpl_CheckDeviceFormatConversion,
2633     IWineD3DImpl_GetDeviceCaps,
2634     IWineD3DImpl_CreateDevice
2635 };