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