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