wined3d: Move binding the texture and dirtifying the sampler to its own function...
[wine] / dlls / wined3d / directx.c
1 /*
2  * IWineD3D implementation
3  *
4  * Copyright 2002-2004 Jason Edmeades
5  * Copyright 2003-2004 Raphael Junqueira
6  * Copyright 2004 Christian Costa
7  * Copyright 2005 Oliver Stieber
8  *
9  * This library is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License as published by the Free Software Foundation; either
12  * version 2.1 of the License, or (at your option) any later version.
13  *
14  * This library is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with this library; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22  */
23
24 /* Compile time diagnostics: */
25
26 #ifndef DEBUG_SINGLE_MODE
27 /* Set to 1 to force only a single display mode to be exposed: */
28 #define DEBUG_SINGLE_MODE 0
29 #endif
30
31
32 #include "config.h"
33 #include <assert.h>
34 #include "wined3d_private.h"
35
36 WINE_DEFAULT_DEBUG_CHANNEL(d3d);
37 WINE_DECLARE_DEBUG_CHANNEL(d3d_caps);
38
39 /* Extension detection */
40 static const struct {
41     const char *extension_string;
42     GL_SupportedExt extension;
43     DWORD version;
44 } EXTENSION_MAP[] = {
45     /* APPLE */
46     {"GL_APPLE_client_storage",             APPLE_CLIENT_STORAGE,           0                           },
47     {"GL_APPLE_fence",                      APPLE_FENCE,                    0                           },
48     {"GL_APPLE_flush_render",               APPLE_FLUSH_RENDER,             0                           },
49     {"GL_APPLE_ycbcr_422",                  APPLE_YCBCR_422,                0                           },
50
51     /* ATI */
52     {"GL_ATI_separate_stencil",             ATI_SEPARATE_STENCIL,           0                           },
53     {"GL_ATI_texture_env_combine3",         ATI_TEXTURE_ENV_COMBINE3,       0                           },
54     {"GL_ATI_texture_mirror_once",          ATI_TEXTURE_MIRROR_ONCE,        0                           },
55     {"GL_ATI_envmap_bumpmap",               ATI_ENVMAP_BUMPMAP,             0                           },
56
57     /* ARB */
58     {"GL_ARB_draw_buffers",                 ARB_DRAW_BUFFERS,               0                           },
59     {"GL_ARB_fragment_program",             ARB_FRAGMENT_PROGRAM,           0                           },
60     {"GL_ARB_fragment_shader",              ARB_FRAGMENT_SHADER,            0                           },
61     {"GL_ARB_half_float_pixel",             ARB_HALF_FLOAT_PIXEL,           0                           },
62     {"GL_ARB_imaging",                      ARB_IMAGING,                    0                           },
63     {"GL_ARB_multisample",                  ARB_MULTISAMPLE,                0                           }, /* needs GLX_ARB_MULTISAMPLE as well */
64     {"GL_ARB_multitexture",                 ARB_MULTITEXTURE,               0                           },
65     {"GL_ARB_occlusion_query",              ARB_OCCLUSION_QUERY,            0                           },
66     {"GL_ARB_pixel_buffer_object",          ARB_PIXEL_BUFFER_OBJECT,        0                           },
67     {"GL_ARB_point_parameters",             ARB_POINT_PARAMETERS,           0                           },
68     {"GL_ARB_point_sprite",                 ARB_POINT_SPRITE,               0                           },
69     {"GL_ARB_texture_border_clamp",         ARB_TEXTURE_BORDER_CLAMP,       0                           },
70     {"GL_ARB_texture_compression",          ARB_TEXTURE_COMPRESSION,        0                           },
71     {"GL_ARB_texture_cube_map",             ARB_TEXTURE_CUBE_MAP,           0                           },
72     {"GL_ARB_texture_env_add",              ARB_TEXTURE_ENV_ADD,            0                           },
73     {"GL_ARB_texture_env_combine",          ARB_TEXTURE_ENV_COMBINE,        0                           },
74     {"GL_ARB_texture_env_dot3",             ARB_TEXTURE_ENV_DOT3,           0                           },
75     {"GL_ARB_texture_float",                ARB_TEXTURE_FLOAT,              0                           },
76     {"GL_ARB_texture_mirrored_repeat",      ARB_TEXTURE_MIRRORED_REPEAT,    0                           },
77     {"GL_ARB_texture_non_power_of_two",     ARB_TEXTURE_NON_POWER_OF_TWO,   0                           },
78     {"GL_ARB_texture_rectangle",            ARB_TEXTURE_RECTANGLE,          0                           },
79     {"GL_ARB_vertex_blend",                 ARB_VERTEX_BLEND,               0                           },
80     {"GL_ARB_vertex_buffer_object",         ARB_VERTEX_BUFFER_OBJECT,       0                           },
81     {"GL_ARB_vertex_program",               ARB_VERTEX_PROGRAM,             0                           },
82     {"GL_ARB_vertex_shader",                ARB_VERTEX_SHADER,              0                           },
83     {"GL_ARB_shader_objects",               ARB_SHADER_OBJECTS,             0                           },
84
85     /* EXT */
86     {"GL_EXT_blend_minmax",                 EXT_BLEND_MINMAX,               0                           },
87     {"GL_EXT_fog_coord",                    EXT_FOG_COORD,                  0                           },
88     {"GL_EXT_framebuffer_blit",             EXT_FRAMEBUFFER_BLIT,           0                           },
89     {"GL_EXT_framebuffer_object",           EXT_FRAMEBUFFER_OBJECT,         0                           },
90     {"GL_EXT_paletted_texture",             EXT_PALETTED_TEXTURE,           0                           },
91     {"GL_EXT_point_parameters",             EXT_POINT_PARAMETERS,           0                           },
92     {"GL_EXT_secondary_color",              EXT_SECONDARY_COLOR,            0                           },
93     {"GL_EXT_stencil_two_side",             EXT_STENCIL_TWO_SIDE,           0                           },
94     {"GL_EXT_stencil_wrap",                 EXT_STENCIL_WRAP,               0                           },
95     {"GL_EXT_texture3D",                    EXT_TEXTURE3D,                  MAKEDWORD_VERSION(1, 2)     },
96     {"GL_EXT_texture_compression_s3tc",     EXT_TEXTURE_COMPRESSION_S3TC,   0                           },
97     {"GL_EXT_texture_env_add",              EXT_TEXTURE_ENV_ADD,            0                           },
98     {"GL_EXT_texture_env_combine",          EXT_TEXTURE_ENV_COMBINE,        0                           },
99     {"GL_EXT_texture_env_dot3",             EXT_TEXTURE_ENV_DOT3,           0                           },
100     {"GL_EXT_texture_sRGB",                 EXT_TEXTURE_SRGB,               0                           },
101     {"GL_EXT_texture_filter_anisotropic",   EXT_TEXTURE_FILTER_ANISOTROPIC, 0                           },
102     {"GL_EXT_texture_lod",                  EXT_TEXTURE_LOD,                0                           },
103     {"GL_EXT_texture_lod_bias",             EXT_TEXTURE_LOD_BIAS,           0                           },
104     {"GL_EXT_vertex_shader",                EXT_VERTEX_SHADER,              0                           },
105     {"GL_EXT_vertex_weighting",             EXT_VERTEX_WEIGHTING,           0                           },
106
107     /* NV */
108     {"GL_NV_half_float",                    NV_HALF_FLOAT,                  0                           },
109     {"GL_NV_fence",                         NV_FENCE,                       0                           },
110     {"GL_NV_fog_distance",                  NV_FOG_DISTANCE,                0                           },
111     {"GL_NV_fragment_program",              NV_FRAGMENT_PROGRAM,            0                           },
112     {"GL_NV_fragment_program2",             NV_FRAGMENT_PROGRAM2,           0                           },
113     {"GL_NV_register_combiners",            NV_REGISTER_COMBINERS,          0                           },
114     {"GL_NV_register_combiners2",           NV_REGISTER_COMBINERS2,         0                           },
115     {"GL_NV_texgen_reflection",             NV_TEXGEN_REFLECTION,           0                           },
116     {"GL_NV_texture_env_combine4",          NV_TEXTURE_ENV_COMBINE4,        0                           },
117     {"GL_NV_texture_shader",                NV_TEXTURE_SHADER,              0                           },
118     {"GL_NV_texture_shader2",               NV_TEXTURE_SHADER2,             0                           },
119     {"GL_NV_texture_shader3",               NV_TEXTURE_SHADER3,             0                           },
120     {"GL_NV_occlusion_query",               NV_OCCLUSION_QUERY,             0                           },
121     {"GL_NV_vertex_program",                NV_VERTEX_PROGRAM,              0                           },
122     {"GL_NV_vertex_program1_1",             NV_VERTEX_PROGRAM1_1,           0                           },
123     {"GL_NV_vertex_program2",               NV_VERTEX_PROGRAM2,             0                           },
124     {"GL_NV_vertex_program3",               NV_VERTEX_PROGRAM3,             0                           },
125     {"GL_NV_depth_clamp",                   NV_DEPTH_CLAMP,                 0                           },
126
127     /* SGI */
128     {"GL_SGIS_generate_mipmap",             SGIS_GENERATE_MIPMAP,           0                           },
129 };
130
131 /**********************************************************
132  * Utility functions follow
133  **********************************************************/
134
135 /* Adapters */
136 static int numAdapters = 0;
137 static struct WineD3DAdapter Adapters[1];
138
139 /* lookup tables */
140 int minLookup[MAX_LOOKUPS];
141 int maxLookup[MAX_LOOKUPS];
142 DWORD *stateLookup[MAX_LOOKUPS];
143
144 DWORD minMipLookup[WINED3DTEXF_ANISOTROPIC + 1][WINED3DTEXF_LINEAR + 1];
145
146 /* drawStridedSlow attributes */
147 glAttribFunc position_funcs[WINED3DDECLTYPE_UNUSED];
148 glAttribFunc diffuse_funcs[WINED3DDECLTYPE_UNUSED];
149 glAttribFunc specular_funcs[WINED3DDECLTYPE_UNUSED];
150 glAttribFunc normal_funcs[WINED3DDECLTYPE_UNUSED];
151 glTexAttribFunc texcoord_funcs[WINED3DDECLTYPE_UNUSED];
152
153 /**
154  * Note: GL seems to trap if GetDeviceCaps is called before any HWND's created
155  * ie there is no GL Context - Get a default rendering context to enable the
156  * function query some info from GL
157  */
158
159 static int             wined3d_fake_gl_context_ref = 0;
160 static BOOL            wined3d_fake_gl_context_foreign;
161 static BOOL            wined3d_fake_gl_context_available = FALSE;
162 static HDC             wined3d_fake_gl_context_hdc = NULL;
163 static HWND            wined3d_fake_gl_context_hwnd = NULL;
164
165 static CRITICAL_SECTION wined3d_fake_gl_context_cs;
166 static CRITICAL_SECTION_DEBUG wined3d_fake_gl_context_cs_debug =
167 {
168     0, 0, &wined3d_fake_gl_context_cs,
169     { &wined3d_fake_gl_context_cs_debug.ProcessLocksList,
170       &wined3d_fake_gl_context_cs_debug.ProcessLocksList },
171     0, 0, { (DWORD_PTR)(__FILE__ ": wined3d_fake_gl_context_cs") }
172 };
173 static CRITICAL_SECTION wined3d_fake_gl_context_cs = { &wined3d_fake_gl_context_cs_debug, -1, 0, 0, 0, 0 };
174
175 static void WineD3D_ReleaseFakeGLContext(void) {
176     HGLRC glCtx;
177
178     EnterCriticalSection(&wined3d_fake_gl_context_cs);
179
180     if(!wined3d_fake_gl_context_available) {
181         TRACE_(d3d_caps)("context not available\n");
182         LeaveCriticalSection(&wined3d_fake_gl_context_cs);
183         return;
184     }
185
186     glCtx = pwglGetCurrentContext();
187
188     TRACE_(d3d_caps)("decrementing ref from %i\n", wined3d_fake_gl_context_ref);
189     if (0 == (--wined3d_fake_gl_context_ref) ) {
190         if(!wined3d_fake_gl_context_foreign && glCtx) {
191             TRACE_(d3d_caps)("destroying fake GL context\n");
192             pwglMakeCurrent(NULL, NULL);
193             pwglDeleteContext(glCtx);
194         }
195         if(wined3d_fake_gl_context_hdc)
196             ReleaseDC(wined3d_fake_gl_context_hwnd, wined3d_fake_gl_context_hdc);
197         wined3d_fake_gl_context_hdc = NULL; /* Make sure we don't think that it is still around */
198         if(wined3d_fake_gl_context_hwnd)
199             DestroyWindow(wined3d_fake_gl_context_hwnd);
200         wined3d_fake_gl_context_hwnd = NULL;
201         wined3d_fake_gl_context_available = FALSE;
202     }
203     assert(wined3d_fake_gl_context_ref >= 0);
204
205     LeaveCriticalSection(&wined3d_fake_gl_context_cs);
206 }
207
208 static BOOL WineD3D_CreateFakeGLContext(void) {
209     HGLRC glCtx = NULL;
210
211     EnterCriticalSection(&wined3d_fake_gl_context_cs);
212
213     TRACE("getting context...\n");
214     if(wined3d_fake_gl_context_ref > 0) goto ret;
215     assert(0 == wined3d_fake_gl_context_ref);
216
217     wined3d_fake_gl_context_foreign = TRUE;
218
219     glCtx = pwglGetCurrentContext();
220     if (!glCtx) {
221         PIXELFORMATDESCRIPTOR pfd;
222         int iPixelFormat;
223
224         wined3d_fake_gl_context_foreign = FALSE;
225
226         /* We need a fake window as a hdc retrieved using GetDC(0) can't be used for much GL purposes */
227         wined3d_fake_gl_context_hwnd = CreateWindowA("WineD3D_OpenGL", "WineD3D fake window", WS_OVERLAPPEDWINDOW,        10, 10, 10, 10, NULL, NULL, NULL, NULL);
228         if(!wined3d_fake_gl_context_hwnd) {
229             ERR("HWND creation failed!\n");
230             goto fail;
231         }
232         wined3d_fake_gl_context_hdc = GetDC(wined3d_fake_gl_context_hwnd);
233         if(!wined3d_fake_gl_context_hdc) {
234             ERR("GetDC failed!\n");
235             goto fail;
236         }
237
238         /* PixelFormat selection */
239         ZeroMemory(&pfd, sizeof(pfd));
240         pfd.nSize      = sizeof(pfd);
241         pfd.nVersion   = 1;
242         pfd.dwFlags    = PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER | PFD_DRAW_TO_WINDOW;/*PFD_GENERIC_ACCELERATED*/
243         pfd.iPixelType = PFD_TYPE_RGBA;
244         pfd.cColorBits = 32;
245         pfd.iLayerType = PFD_MAIN_PLANE;
246
247         iPixelFormat = ChoosePixelFormat(wined3d_fake_gl_context_hdc, &pfd);
248         if(!iPixelFormat) {
249             /* If this happens something is very wrong as ChoosePixelFormat barely fails */
250             ERR("Can't find a suitable iPixelFormat\n");
251             goto fail;
252         }
253         DescribePixelFormat(wined3d_fake_gl_context_hdc, iPixelFormat, sizeof(pfd), &pfd);
254         SetPixelFormat(wined3d_fake_gl_context_hdc, iPixelFormat, &pfd);
255
256         /* Create a GL context */
257         glCtx = pwglCreateContext(wined3d_fake_gl_context_hdc);
258         if (!glCtx) {
259             WARN_(d3d_caps)("Error creating default context for capabilities initialization\n");
260             goto fail;
261         }
262
263         /* Make it the current GL context */
264         if (!pwglMakeCurrent(wined3d_fake_gl_context_hdc, glCtx)) {
265             WARN_(d3d_caps)("Error setting default context as current for capabilities initialization\n");
266             goto fail;
267         }
268     }
269
270   ret:
271     TRACE("incrementing ref from %i\n", wined3d_fake_gl_context_ref);
272     wined3d_fake_gl_context_ref++;
273     wined3d_fake_gl_context_available = TRUE;
274     LeaveCriticalSection(&wined3d_fake_gl_context_cs);
275     return TRUE;
276   fail:
277     if(wined3d_fake_gl_context_hdc)
278         ReleaseDC(wined3d_fake_gl_context_hwnd, wined3d_fake_gl_context_hdc);
279     wined3d_fake_gl_context_hdc = NULL;
280     if(wined3d_fake_gl_context_hwnd)
281         DestroyWindow(wined3d_fake_gl_context_hwnd);
282     wined3d_fake_gl_context_hwnd = NULL;
283     if(glCtx) pwglDeleteContext(glCtx);
284     LeaveCriticalSection(&wined3d_fake_gl_context_cs);
285     return FALSE;
286 }
287
288 /* Adjust the amount of used texture memory */
289 long WineD3DAdapterChangeGLRam(IWineD3DDeviceImpl *D3DDevice, long glram){
290     UINT Adapter = D3DDevice->adapterNo;
291
292     Adapters[Adapter].UsedTextureRam += glram;
293     TRACE("Adjusted gl ram by %ld to %d\n", glram, Adapters[Adapter].UsedTextureRam);
294     return Adapters[Adapter].UsedTextureRam;
295 }
296
297 /**********************************************************
298  * IUnknown parts follows
299  **********************************************************/
300
301 static HRESULT WINAPI IWineD3DImpl_QueryInterface(IWineD3D *iface,REFIID riid,LPVOID *ppobj)
302 {
303     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
304
305     TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(riid),ppobj);
306     if (IsEqualGUID(riid, &IID_IUnknown)
307         || IsEqualGUID(riid, &IID_IWineD3DBase)
308         || IsEqualGUID(riid, &IID_IWineD3DDevice)) {
309         IUnknown_AddRef(iface);
310         *ppobj = This;
311         return S_OK;
312     }
313     *ppobj = NULL;
314     return E_NOINTERFACE;
315 }
316
317 static ULONG WINAPI IWineD3DImpl_AddRef(IWineD3D *iface) {
318     IWineD3DImpl *This = (IWineD3DImpl *)iface;
319     ULONG refCount = InterlockedIncrement(&This->ref);
320
321     TRACE("(%p) : AddRef increasing from %d\n", This, refCount - 1);
322     return refCount;
323 }
324
325 static ULONG WINAPI IWineD3DImpl_Release(IWineD3D *iface) {
326     IWineD3DImpl *This = (IWineD3DImpl *)iface;
327     ULONG ref;
328     TRACE("(%p) : Releasing from %d\n", This, This->ref);
329     ref = InterlockedDecrement(&This->ref);
330     if (ref == 0) {
331         HeapFree(GetProcessHeap(), 0, This);
332     }
333
334     return ref;
335 }
336
337 /* Set the shader type for this device, depending on the given capabilities,
338  * the device type, and the user preferences in wined3d_settings */
339
340 static void select_shader_mode(
341     WineD3D_GL_Info *gl_info,
342     WINED3DDEVTYPE DeviceType,
343     int* ps_selected,
344     int* vs_selected) {
345
346     if (wined3d_settings.vs_mode == VS_NONE) {
347         *vs_selected = SHADER_NONE;
348     } else if (gl_info->supported[ARB_VERTEX_SHADER] && wined3d_settings.glslRequested) {
349         /* Geforce4 cards support GLSL but for vertex shaders only. Further its reported GLSL caps are
350          * wrong. This combined with the fact that glsl won't offer more features or performance, use ARB
351          * shaders only on this card. */
352         if(gl_info->vs_nv_version && gl_info->vs_nv_version < VS_VERSION_20)
353             *vs_selected = SHADER_ARB;
354         else
355             *vs_selected = SHADER_GLSL;
356     } else if (gl_info->supported[ARB_VERTEX_PROGRAM]) {
357         *vs_selected = SHADER_ARB;
358     } else {
359         *vs_selected = SHADER_NONE;
360     }
361
362     if (wined3d_settings.ps_mode == PS_NONE) {
363         *ps_selected = SHADER_NONE;
364     } else if (gl_info->supported[ARB_FRAGMENT_SHADER] && wined3d_settings.glslRequested) {
365         *ps_selected = SHADER_GLSL;
366     } else if (gl_info->supported[ARB_FRAGMENT_PROGRAM]) {
367         *ps_selected = SHADER_ARB;
368     } else {
369         *ps_selected = SHADER_NONE;
370     }
371 }
372
373 /** Select the number of report maximum shader constants based on the selected shader modes */
374 static void select_shader_max_constants(
375     int ps_selected_mode,
376     int vs_selected_mode,
377     WineD3D_GL_Info *gl_info) {
378
379     switch (vs_selected_mode) {
380         case SHADER_GLSL:
381             /* Subtract the other potential uniforms from the max available (bools, ints, and 1 row of projection matrix) */
382             gl_info->max_vshader_constantsF = gl_info->vs_glsl_constantsF - (MAX_CONST_B / 4) - MAX_CONST_I - 1;
383             break;
384         case SHADER_ARB:
385             /* We have to subtract any other PARAMs that we might use in our shader programs.
386              * ATI seems to count 2 implicit PARAMs when we use fog and NVIDIA counts 1,
387              * and we reference one row of the PROJECTION matrix which counts as 1 PARAM. */
388             gl_info->max_vshader_constantsF = gl_info->vs_arb_constantsF - 3;
389             break;
390         default:
391             gl_info->max_vshader_constantsF = 0;
392             break;
393     }
394
395     switch (ps_selected_mode) {
396         case SHADER_GLSL:
397             /* Subtract the other potential uniforms from the max available (bools & ints), and 2 states for fog.
398              * In theory the texbem instruction may need one more shader constant too. But lets assume
399              * that a sm <= 1.3 shader does not need all the uniforms provided by a glsl-capable card,
400              * and lets not take away a uniform needlessly from all other shaders.
401              */
402             gl_info->max_pshader_constantsF = gl_info->ps_glsl_constantsF - (MAX_CONST_B / 4) - MAX_CONST_I - 2;
403             break;
404         case SHADER_ARB:
405             /* The arb shader only loads the bump mapping environment matrix into the shader if it finds
406              * a free constant to do that, so only reduce the number of available constants by 2 for the fog states.
407              */
408             gl_info->max_pshader_constantsF = gl_info->ps_arb_constantsF - 2;
409             break;
410         default:
411             gl_info->max_pshader_constantsF = 0;
412             break;
413     }
414 }
415
416 /**********************************************************
417  * IWineD3D parts follows
418  **********************************************************/
419
420 #define GLINFO_LOCATION (*gl_info)
421 static inline BOOL test_arb_vs_offset_limit(WineD3D_GL_Info *gl_info) {
422     GLuint prog;
423     BOOL ret = FALSE;
424     const char *testcode =
425         "!!ARBvp1.0\n"
426         "PARAM C[66] = { program.env[0..65] };\n"
427         "ADDRESS A0;"
428         "ARL A0.x, 0.0;\n"
429         "MOV result.position, C[A0.x + 65];\n"
430         "END\n";
431
432     while(glGetError());
433     GL_EXTCALL(glGenProgramsARB(1, &prog));
434     if(!prog) {
435         ERR("Failed to create an ARB offset limit test program\n");
436     }
437     GL_EXTCALL(glBindProgramARB(GL_VERTEX_PROGRAM_ARB, prog));
438     GL_EXTCALL(glProgramStringARB(GL_VERTEX_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB,
439                                   strlen(testcode), testcode));
440     if(glGetError() != 0) {
441         TRACE("OpenGL implementation does not allow indirect addressing offsets > 63\n");
442         TRACE("error: %s\n", debugstr_a((const char *)glGetString(GL_PROGRAM_ERROR_STRING_ARB)));
443         ret = TRUE;
444     } else TRACE("OpenGL implementation allows offsets > 63\n");
445
446     GL_EXTCALL(glBindProgramARB(GL_VERTEX_PROGRAM_ARB, 0));
447     GL_EXTCALL(glDeleteProgramsARB(1, &prog));
448     checkGLcall("ARB vp offset limit test cleanup\n");
449
450     return ret;
451 }
452
453 static DWORD ver_for_ext(GL_SupportedExt ext)
454 {
455     unsigned int i;
456     for (i = 0; i < (sizeof(EXTENSION_MAP) / sizeof(*EXTENSION_MAP)); ++i) {
457         if(EXTENSION_MAP[i].extension == ext) {
458             return EXTENSION_MAP[i].version;
459         }
460     }
461     return 0;
462 }
463
464 BOOL IWineD3DImpl_FillGLCaps(WineD3D_GL_Info *gl_info) {
465     const char *GL_Extensions    = NULL;
466     const char *WGL_Extensions   = NULL;
467     const char *gl_string        = NULL;
468     const char *gl_string_cursor = NULL;
469     GLint       gl_max;
470     GLfloat     gl_floatv[2];
471     int         major = 1, minor = 0;
472     BOOL        return_value = TRUE;
473     unsigned    i;
474     HDC         hdc;
475     unsigned int vidmem=0;
476
477     TRACE_(d3d_caps)("(%p)\n", gl_info);
478
479     ENTER_GL();
480
481     gl_string = (const char *) glGetString(GL_RENDERER);
482     if (NULL == gl_string)
483         gl_string = "None";
484     strcpy(gl_info->gl_renderer, gl_string);
485
486     gl_string = (const char *) glGetString(GL_VENDOR);
487     TRACE_(d3d_caps)("Filling vendor string %s\n", gl_string);
488     if (gl_string != NULL) {
489         /* Fill in the GL vendor */
490         if (strstr(gl_string, "NVIDIA")) {
491             gl_info->gl_vendor = VENDOR_NVIDIA;
492         } else if (strstr(gl_string, "ATI")) {
493             gl_info->gl_vendor = VENDOR_ATI;
494         } else if (strstr(gl_string, "Intel(R)") ||
495                    strstr(gl_info->gl_renderer, "Intel(R)") ||
496                    strstr(gl_string, "Intel Inc.")) {
497             gl_info->gl_vendor = VENDOR_INTEL;
498         } else if (strstr(gl_string, "Mesa")) {
499             gl_info->gl_vendor = VENDOR_MESA;
500         } else {
501             gl_info->gl_vendor = VENDOR_WINE;
502         }
503     } else {
504         gl_info->gl_vendor = VENDOR_WINE;
505     }
506
507
508     TRACE_(d3d_caps)("found GL_VENDOR (%s)->(0x%04x)\n", debugstr_a(gl_string), gl_info->gl_vendor);
509
510     /* Parse the GL_VERSION field into major and minor information */
511     gl_string = (const char *) glGetString(GL_VERSION);
512     if (gl_string != NULL) {
513
514         switch (gl_info->gl_vendor) {
515         case VENDOR_NVIDIA:
516             gl_string_cursor = strstr(gl_string, "NVIDIA");
517             if (!gl_string_cursor) {
518                 ERR_(d3d_caps)("Invalid nVidia version string: %s\n", debugstr_a(gl_string));
519                 break;
520             }
521
522             gl_string_cursor = strstr(gl_string_cursor, " ");
523             if (!gl_string_cursor) {
524                 ERR_(d3d_caps)("Invalid nVidia version string: %s\n", debugstr_a(gl_string));
525                 break;
526             }
527
528             while (*gl_string_cursor == ' ') {
529                 ++gl_string_cursor;
530             }
531
532             if (!*gl_string_cursor) {
533                 ERR_(d3d_caps)("Invalid nVidia version string: %s\n", debugstr_a(gl_string));
534                 break;
535             }
536
537             major = atoi(gl_string_cursor);
538             while (*gl_string_cursor <= '9' && *gl_string_cursor >= '0') {
539                 ++gl_string_cursor;
540             }
541
542             if (*gl_string_cursor++ != '.') {
543                 ERR_(d3d_caps)("Invalid nVidia version string: %s\n", debugstr_a(gl_string));
544                 break;
545             }
546
547             minor = atoi(gl_string_cursor);
548             minor = major*100+minor;
549             major = 10;
550
551             break;
552
553         case VENDOR_ATI:
554             major = minor = 0;
555             gl_string_cursor = strchr(gl_string, '-');
556             if (gl_string_cursor) {
557                 int error = 0;
558                 gl_string_cursor++;
559
560                 /* Check if version number is of the form x.y.z */
561                 if (*gl_string_cursor > '9' && *gl_string_cursor < '0')
562                     error = 1;
563                 if (!error && *(gl_string_cursor+2) > '9' && *(gl_string_cursor+2) < '0')
564                     error = 1;
565                 if (!error && *(gl_string_cursor+4) > '9' && *(gl_string_cursor+4) < '0')
566                     error = 1;
567                 if (!error && *(gl_string_cursor+1) != '.' && *(gl_string_cursor+3) != '.')
568                     error = 1;
569
570                 /* Mark version number as malformed */
571                 if (error)
572                     gl_string_cursor = 0;
573             }
574
575             if (!gl_string_cursor)
576                 WARN_(d3d_caps)("malformed GL_VERSION (%s)\n", debugstr_a(gl_string));
577             else {
578                 major = *gl_string_cursor - '0';
579                 minor = (*(gl_string_cursor+2) - '0') * 256 + (*(gl_string_cursor+4) - '0');
580             }
581             break;
582
583         case VENDOR_INTEL:
584             /* Apple and Mesa version strings look differently, but both provide intel drivers */
585             if(strstr(gl_string, "APPLE")) {
586                 /* [0-9]+.[0-9]+ APPLE-[0-9]+.[0.9]+.[0.9]+
587                  * We only need the first part, and use the APPLE as identification
588                  * "1.2 APPLE-1.4.56"
589                  */
590                 gl_string_cursor = gl_string;
591                 major = atoi(gl_string_cursor);
592                 while (*gl_string_cursor <= '9' && *gl_string_cursor >= '0') {
593                     ++gl_string_cursor;
594                 }
595
596                 if (*gl_string_cursor++ != '.') {
597                     ERR_(d3d_caps)("Invalid MacOS-Intel version string: %s\n", debugstr_a(gl_string));
598                     break;
599                 }
600
601                 minor = atoi(gl_string_cursor);
602                 break;
603             }
604
605         case VENDOR_MESA:
606             gl_string_cursor = strstr(gl_string, "Mesa");
607             gl_string_cursor = strstr(gl_string_cursor, " ");
608             while (*gl_string_cursor && ' ' == *gl_string_cursor) ++gl_string_cursor;
609             if (*gl_string_cursor) {
610                 char tmp[16];
611                 int cursor = 0;
612
613                 while (*gl_string_cursor <= '9' && *gl_string_cursor >= '0') {
614                     tmp[cursor++] = *gl_string_cursor;
615                     ++gl_string_cursor;
616                 }
617                 tmp[cursor] = 0;
618                 major = atoi(tmp);
619
620                 if (*gl_string_cursor != '.') WARN_(d3d_caps)("malformed GL_VERSION (%s)\n", debugstr_a(gl_string));
621                 ++gl_string_cursor;
622
623                 cursor = 0;
624                 while (*gl_string_cursor <= '9' && *gl_string_cursor >= '0') {
625                     tmp[cursor++] = *gl_string_cursor;
626                     ++gl_string_cursor;
627                 }
628                 tmp[cursor] = 0;
629                 minor = atoi(tmp);
630             }
631             break;
632
633         default:
634             major = 0;
635             minor = 9;
636         }
637         gl_info->gl_driver_version = MAKEDWORD_VERSION(major, minor);
638         TRACE_(d3d_caps)("found GL_VERSION  (%s)->%i.%i->(0x%08x)\n", debugstr_a(gl_string), major, minor, gl_info->gl_driver_version);
639     }
640
641     TRACE_(d3d_caps)("found GL_RENDERER (%s)->(0x%04x)\n", debugstr_a(gl_info->gl_renderer), gl_info->gl_card);
642
643     /*
644      * Initialize openGL extension related variables
645      *  with Default values
646      */
647     memset(&gl_info->supported, 0, sizeof(gl_info->supported));
648     gl_info->max_buffers        = 1;
649     gl_info->max_textures       = 1;
650     gl_info->max_texture_stages = 1;
651     gl_info->max_fragment_samplers = 1;
652     gl_info->max_vertex_samplers = 0;
653     gl_info->max_combined_samplers = 0;
654     gl_info->max_sampler_stages = 1;
655     gl_info->ps_arb_version = PS_VERSION_NOT_SUPPORTED;
656     gl_info->ps_arb_max_temps = 0;
657     gl_info->ps_arb_max_instructions = 0;
658     gl_info->vs_arb_version = VS_VERSION_NOT_SUPPORTED;
659     gl_info->vs_arb_max_temps = 0;
660     gl_info->vs_arb_max_instructions = 0;
661     gl_info->vs_nv_version  = VS_VERSION_NOT_SUPPORTED;
662     gl_info->vs_ati_version = VS_VERSION_NOT_SUPPORTED;
663     gl_info->vs_glsl_constantsF = 0;
664     gl_info->ps_glsl_constantsF = 0;
665     gl_info->vs_arb_constantsF = 0;
666     gl_info->ps_arb_constantsF = 0;
667
668     /* Retrieve opengl defaults */
669     glGetIntegerv(GL_MAX_CLIP_PLANES, &gl_max);
670     gl_info->max_clipplanes = min(WINED3DMAXUSERCLIPPLANES, gl_max);
671     TRACE_(d3d_caps)("ClipPlanes support - num Planes=%d\n", gl_max);
672
673     glGetIntegerv(GL_MAX_LIGHTS, &gl_max);
674     gl_info->max_lights = gl_max;
675     TRACE_(d3d_caps)("Lights support - max lights=%d\n", gl_max);
676
677     glGetIntegerv(GL_MAX_TEXTURE_SIZE, &gl_max);
678     gl_info->max_texture_size = gl_max;
679     TRACE_(d3d_caps)("Maximum texture size support - max texture size=%d\n", gl_max);
680
681     glGetFloatv(GL_POINT_SIZE_RANGE, gl_floatv);
682     gl_info->max_pointsizemin = gl_floatv[0];
683     gl_info->max_pointsize = gl_floatv[1];
684     TRACE_(d3d_caps)("Maximum point size support - max point size=%f\n", gl_floatv[1]);
685
686     glGetIntegerv(GL_AUX_BUFFERS, &gl_max);
687     gl_info->max_aux_buffers = gl_max;
688     TRACE_(d3d_caps)("Offscreen rendering support - number of aux buffers=%d\n", gl_max);
689
690     /* Parse the gl supported features, in theory enabling parts of our code appropriately */
691     GL_Extensions = (const char *) glGetString(GL_EXTENSIONS);
692     TRACE_(d3d_caps)("GL_Extensions reported:\n");
693
694     if (NULL == GL_Extensions) {
695         ERR("   GL_Extensions returns NULL\n");
696     } else {
697         while (*GL_Extensions != 0x00) {
698             const char *Start;
699             char        ThisExtn[256];
700             size_t      len;
701
702             while (isspace(*GL_Extensions)) GL_Extensions++;
703             Start = GL_Extensions;
704             while (!isspace(*GL_Extensions) && *GL_Extensions != 0x00) {
705                 GL_Extensions++;
706             }
707
708             len = GL_Extensions - Start;
709             if (len == 0 || len >= sizeof(ThisExtn))
710                 continue;
711
712             memcpy(ThisExtn, Start, len);
713             ThisExtn[len] = '\0';
714             TRACE_(d3d_caps)("- %s\n", ThisExtn);
715
716             for (i = 0; i < (sizeof(EXTENSION_MAP) / sizeof(*EXTENSION_MAP)); ++i) {
717                 if (!strcmp(ThisExtn, EXTENSION_MAP[i].extension_string)) {
718                     TRACE_(d3d_caps)(" FOUND: %s support\n", EXTENSION_MAP[i].extension_string);
719                     gl_info->supported[EXTENSION_MAP[i].extension] = TRUE;
720                     break;
721                 }
722             }
723         }
724         /* Now work out what GL support this card really has */
725 #define USE_GL_FUNC(type, pfn, ext, replace) { \
726             DWORD ver = ver_for_ext(ext); \
727             if(gl_info->supported[ext]) gl_info->pfn = (type) pwglGetProcAddress(#pfn); \
728             else if(ver && ver <= gl_info->gl_driver_version) gl_info->pfn = (type) pwglGetProcAddress(#replace); \
729             else gl_info->pfn = NULL; \
730         }
731         GL_EXT_FUNCS_GEN;
732 #undef USE_GL_FUNC
733
734 #define USE_GL_FUNC(type, pfn, ext, replace) gl_info->pfn = (type) pwglGetProcAddress(#pfn);
735         WGL_EXT_FUNCS_GEN;
736 #undef USE_GL_FUNC
737
738         /* Now mark all the extensions supported which are included in the opengl core version. Do this *after*
739          * loading the functions, otherwise the code above will load the extension entry points instead of the
740          * core functions, which may not work
741          */
742         for (i = 0; i < (sizeof(EXTENSION_MAP) / sizeof(*EXTENSION_MAP)); ++i) {
743             if (gl_info->supported[EXTENSION_MAP[i].extension] == FALSE &&
744                 EXTENSION_MAP[i].version <= gl_info->gl_driver_version && EXTENSION_MAP[i].version) {
745                 TRACE_(d3d_caps)(" GL CORE: %s support\n", EXTENSION_MAP[i].extension_string);
746                 gl_info->supported[EXTENSION_MAP[i].extension] = TRUE;
747             }
748         }
749
750         if (gl_info->supported[APPLE_FENCE]) {
751             /* GL_NV_fence and GL_APPLE_fence provide the same functionality basically.
752              * The apple extension interacts with some other apple exts. Disable the NV
753              * extension if the apple one is support to prevent confusion in other parts
754              * of the code
755              */
756             gl_info->supported[NV_FENCE] = FALSE;
757         }
758         if (gl_info->supported[ARB_TEXTURE_CUBE_MAP]) {
759             TRACE_(d3d_caps)(" IMPLIED: NVIDIA (NV) Texture Gen Reflection support\n");
760             gl_info->supported[NV_TEXGEN_REFLECTION] = TRUE;
761         }
762         if (gl_info->supported[NV_TEXTURE_SHADER2]) {
763             /* GL_ATI_envmap_bumpmap won't play nice with texture shaders, so disable it
764              * Won't occur in any real world situation though
765              */
766             gl_info->supported[ATI_ENVMAP_BUMPMAP] = FALSE;
767         }
768         if (gl_info->supported[ARB_DRAW_BUFFERS]) {
769             glGetIntegerv(GL_MAX_DRAW_BUFFERS_ARB, &gl_max);
770             gl_info->max_buffers = gl_max;
771             TRACE_(d3d_caps)("Max draw buffers: %u\n", gl_max);
772         }
773         if (gl_info->supported[ARB_MULTITEXTURE]) {
774             glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, &gl_max);
775             gl_info->max_textures = min(MAX_TEXTURES, gl_max);
776             TRACE_(d3d_caps)("Max textures: %d\n", gl_info->max_textures);
777
778             if (gl_info->supported[NV_REGISTER_COMBINERS]) {
779                 GLint tmp;
780                 glGetIntegerv(GL_MAX_GENERAL_COMBINERS_NV, &tmp);
781                 gl_info->max_texture_stages = min(MAX_TEXTURES, tmp);
782             } else {
783                 gl_info->max_texture_stages = min(MAX_TEXTURES, gl_max);
784             }
785             TRACE_(d3d_caps)("Max texture stages: %d\n", gl_info->max_texture_stages);
786
787             if (gl_info->supported[ARB_FRAGMENT_PROGRAM]) {
788                 GLint tmp;
789                 glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS_ARB, &tmp);
790                 gl_info->max_fragment_samplers = min(MAX_FRAGMENT_SAMPLERS, tmp);
791             } else {
792                 gl_info->max_fragment_samplers = max(gl_info->max_fragment_samplers, gl_max);
793             }
794             TRACE_(d3d_caps)("Max fragment samplers: %d\n", gl_info->max_fragment_samplers);
795
796             if (gl_info->supported[ARB_VERTEX_SHADER]) {
797                 GLint tmp;
798                 glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB, &tmp);
799                 gl_info->max_vertex_samplers = tmp;
800                 glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB, &tmp);
801                 gl_info->max_combined_samplers = tmp;
802
803                 /* Loading GLSL sampler uniforms is much simpler if we can assume that the sampler setup
804                  * is known at shader link time. In a vertex shader + pixel shader combination this isn't
805                  * an issue because then the sampler setup only depends on the two shaders. If a pixel
806                  * shader is used with fixed function vertex processing we're fine too because fixed function
807                  * vertex processing doesn't use any samplers. If fixed function fragment processing is
808                  * used we have to make sure that all vertex sampler setups are valid together with all
809                  * possible fixed function fragment processing setups. This is true if vsamplers + MAX_TEXTURES
810                  * <= max_samplers. This is true on all d3d9 cards that support vtf(gf 6 and gf7 cards).
811                  * dx9 radeon cards do not support vertex texture fetch. DX10 cards have 128 samplers, and
812                  * dx9 is limited to 8 fixed function texture stages and 4 vertex samplers. DX10 does not have
813                  * a fixed function pipeline anymore.
814                  *
815                  * So this is just a check to check that our assumption holds true. If not, write a warning
816                  * and reduce the number of vertex samplers or propably disable vertex texture fetch.
817                  */
818                 if(gl_info->max_vertex_samplers &&
819                    MAX_TEXTURES + gl_info->max_vertex_samplers > gl_info->max_combined_samplers) {
820                     FIXME("OpenGL implementation supports %u vertex samplers and %u total samplers\n",
821                           gl_info->max_vertex_samplers, gl_info->max_combined_samplers);
822                     FIXME("Expected vertex samplers + MAX_TEXTURES(=8) > combined_samplers\n");
823                     if( gl_info->max_combined_samplers > MAX_TEXTURES )
824                         gl_info->max_vertex_samplers =
825                             gl_info->max_combined_samplers - MAX_TEXTURES;
826                     else
827                         gl_info->max_vertex_samplers = 0;
828                 }
829             } else {
830                 gl_info->max_combined_samplers = gl_info->max_fragment_samplers;
831             }
832             TRACE_(d3d_caps)("Max vertex samplers: %u\n", gl_info->max_vertex_samplers);
833             TRACE_(d3d_caps)("Max combined samplers: %u\n", gl_info->max_combined_samplers);
834         }
835         if (gl_info->supported[ARB_VERTEX_BLEND]) {
836             glGetIntegerv(GL_MAX_VERTEX_UNITS_ARB, &gl_max);
837             gl_info->max_blends = gl_max;
838             TRACE_(d3d_caps)("Max blends: %u\n", gl_info->max_blends);
839         }
840         if (gl_info->supported[EXT_TEXTURE3D]) {
841             glGetIntegerv(GL_MAX_3D_TEXTURE_SIZE_EXT, &gl_max);
842             gl_info->max_texture3d_size = gl_max;
843             TRACE_(d3d_caps)("Max texture3D size: %d\n", gl_info->max_texture3d_size);
844         }
845         if (gl_info->supported[EXT_TEXTURE_FILTER_ANISOTROPIC]) {
846             glGetIntegerv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &gl_max);
847             gl_info->max_anisotropy = gl_max;
848             TRACE_(d3d_caps)("Max anisotropy: %d\n", gl_info->max_anisotropy);
849         }
850         if (gl_info->supported[ARB_FRAGMENT_PROGRAM]) {
851             gl_info->ps_arb_version = PS_VERSION_11;
852             GL_EXTCALL(glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_ENV_PARAMETERS_ARB, &gl_max));
853             gl_info->ps_arb_constantsF = gl_max;
854             TRACE_(d3d_caps)("Max ARB_FRAGMENT_PROGRAM float constants: %d\n", gl_info->ps_arb_constantsF);
855             GL_EXTCALL(glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB, &gl_max));
856             gl_info->ps_arb_max_temps = gl_max;
857             TRACE_(d3d_caps)("Max ARB_FRAGMENT_PROGRAM native temporaries: %d\n", gl_info->ps_arb_max_temps);
858             GL_EXTCALL(glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB, &gl_max));
859             gl_info->ps_arb_max_instructions = gl_max;
860             TRACE_(d3d_caps)("Max ARB_FRAGMENT_PROGRAM native instructions: %d\n", gl_info->ps_arb_max_instructions);
861         }
862         if (gl_info->supported[ARB_VERTEX_PROGRAM]) {
863             gl_info->vs_arb_version = VS_VERSION_11;
864             GL_EXTCALL(glGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_MAX_PROGRAM_ENV_PARAMETERS_ARB, &gl_max));
865             gl_info->vs_arb_constantsF = gl_max;
866             TRACE_(d3d_caps)("Max ARB_VERTEX_PROGRAM float constants: %d\n", gl_info->vs_arb_constantsF);
867             GL_EXTCALL(glGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB, &gl_max));
868             gl_info->vs_arb_max_temps = gl_max;
869             TRACE_(d3d_caps)("Max ARB_VERTEX_PROGRAM native temporaries: %d\n", gl_info->vs_arb_max_temps);
870             GL_EXTCALL(glGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB, &gl_max));
871             gl_info->vs_arb_max_instructions = gl_max;
872             TRACE_(d3d_caps)("Max ARB_VERTEX_PROGRAM native instructions: %d\n", gl_info->vs_arb_max_instructions);
873
874             gl_info->arb_vs_offset_limit = test_arb_vs_offset_limit(gl_info);
875         }
876         if (gl_info->supported[ARB_VERTEX_SHADER]) {
877             glGetIntegerv(GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB, &gl_max);
878             gl_info->vs_glsl_constantsF = gl_max / 4;
879             TRACE_(d3d_caps)("Max ARB_VERTEX_SHADER float constants: %u\n", gl_info->vs_glsl_constantsF);
880         }
881         if (gl_info->supported[ARB_FRAGMENT_SHADER]) {
882             glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB, &gl_max);
883             gl_info->ps_glsl_constantsF = gl_max / 4;
884             TRACE_(d3d_caps)("Max ARB_FRAGMENT_SHADER float constants: %u\n", gl_info->ps_glsl_constantsF);
885             glGetIntegerv(GL_MAX_VARYING_FLOATS_ARB, &gl_max);
886             gl_info->max_glsl_varyings = gl_max;
887             TRACE_(d3d_caps)("Max GLSL varyings: %u (%u 4 component varyings)\n", gl_max, gl_max / 4);
888         }
889         if (gl_info->supported[EXT_VERTEX_SHADER]) {
890             gl_info->vs_ati_version = VS_VERSION_11;
891         }
892         if (gl_info->supported[NV_VERTEX_PROGRAM3]) {
893             gl_info->vs_nv_version = VS_VERSION_30;
894         } else if (gl_info->supported[NV_VERTEX_PROGRAM2]) {
895             gl_info->vs_nv_version = VS_VERSION_20;
896         } else if (gl_info->supported[NV_VERTEX_PROGRAM1_1]) {
897             gl_info->vs_nv_version = VS_VERSION_11;
898         } else if (gl_info->supported[NV_VERTEX_PROGRAM]) {
899             gl_info->vs_nv_version = VS_VERSION_10;
900         }
901         if (gl_info->supported[NV_FRAGMENT_PROGRAM2]) {
902             gl_info->ps_nv_version = PS_VERSION_30;
903         } else if (gl_info->supported[NV_FRAGMENT_PROGRAM]) {
904             gl_info->ps_nv_version = PS_VERSION_20;
905         }
906         if (gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO]) {
907             /* If we have full NP2 texture support, disable GL_ARB_texture_rectangle because we will never use it.
908              * This saves a few redundant glDisable calls
909              */
910             gl_info->supported[ARB_TEXTURE_RECTANGLE] = FALSE;
911         }
912
913     }
914     checkGLcall("extension detection\n");
915
916     /* In some cases the number of texture stages can be larger than the number
917      * of samplers. The GF4 for example can use only 2 samplers (no fragment
918      * shaders), but 8 texture stages (register combiners). */
919     gl_info->max_sampler_stages = max(gl_info->max_fragment_samplers, gl_info->max_texture_stages);
920
921     /* We can only use ORM_FBO when the hardware supports it. */
922     if (wined3d_settings.offscreen_rendering_mode == ORM_FBO && !gl_info->supported[EXT_FRAMEBUFFER_OBJECT]) {
923         WARN_(d3d_caps)("GL_EXT_framebuffer_object not supported, falling back to PBuffer offscreen rendering mode.\n");
924         wined3d_settings.offscreen_rendering_mode = ORM_PBUFFER;
925     }
926
927     /* MRTs are currently only supported when FBOs are used. */
928     if (wined3d_settings.offscreen_rendering_mode != ORM_FBO) {
929         gl_info->max_buffers = 1;
930     }
931
932     /* Below is a list of Nvidia and ATI GPUs. Both vendors have dozens of different GPUs with roughly the same
933      * features. In most cases GPUs from a certain family differ in clockspeeds, the amount of video memory and
934      * in case of the latest videocards in the number of pixel/vertex pipelines.
935      *
936      * A Direct3D device object contains the PCI id (vendor + device) of the videocard which is used for
937      * rendering. Various games use this information to get a rough estimation of the features of the card
938      * and some might use it for enabling 3d effects only on certain types of videocards. In some cases
939      * games might even use it to work around bugs which happen on certain videocards/driver combinations.
940      * The problem is that OpenGL only exposes a rendering string containing the name of the videocard and
941      * not the PCI id.
942      *
943      * Various games depend on the PCI id, so somehow we need to provide one. A simple option is to parse
944      * the renderer string and translate this to the right PCI id. This is a lot of work because there are more
945      * than 200 GPUs just for Nvidia. Various cards share the same renderer string, so the amount of code might
946      * be 'small' but there are quite a number of exceptions which would make this a pain to maintain.
947      * Another way would be to query the PCI id from the operating system (assuming this is the videocard which
948      * is used for rendering which is not always the case). This would work but it is not very portable. Second
949      * it would not work well in, let's say, a remote X situation in which the amount of 3d features which can be used
950      * is limited.
951      *
952      * As said most games only use the PCI id to get an indication of the capabilities of the card.
953      * It doesn't really matter if the given id is the correct one if we return the id of a card with
954      * similar 3d features.
955      *
956      * The code below checks the OpenGL capabilities of a videocard and matches that to a certain level of
957      * Direct3D functionality. Once a card passes the Direct3D9 check, we know that the card (in case of Nvidia)
958      * is at least a GeforceFX. To give a better estimate we do a basic check on the renderer string but if that
959      * won't pass we return a default card. This way is better than maintaining a full card database as even
960      * without a full database we can return a card with similar features. Second the size of the database
961      * can be made quite small because when you know what type of 3d functionality a card has, you know to which
962      * GPU family the GPU must belong. Because of this you only have to check a small part of the renderer string
963      * to distinguishes between different models from that family.
964      *
965      * The code also selects a default amount of video memory which we will use for an estimation of the amount
966      * of free texture memory. In case of real D3D the amount of texture memory includes video memory and system
967      * memory (to be specific AGP memory or in case of PCIE TurboCache/HyperMemory). We don't know how much
968      * system memory can be addressed by the system but we can make a reasonable estimation about the amount of
969      * video memory. If the value is slightly wrong it doesn't matter as we didn't include AGP-like memory which
970      * makes the amount of addressable memory higher and second OpenGL isn't that critical it moves to system
971      * memory behind our backs if really needed.
972      * Note that the amout of video memory can be overruled using a registry setting.
973      */
974     switch (gl_info->gl_vendor) {
975         case VENDOR_NVIDIA:
976             /* Both the GeforceFX, 6xxx and 7xxx series support D3D9. The last two types have more
977              * shader capabilities, so we use the shader capabilities to distinguish between FX and 6xxx/7xxx.
978              */
979             if(WINE_D3D9_CAPABLE(gl_info) && (gl_info->vs_nv_version == VS_VERSION_30)) {
980                 /* Geforce8 - highend */
981                 if (strstr(gl_info->gl_renderer, "8800")) {
982                     gl_info->gl_card = CARD_NVIDIA_GEFORCE_8800GTS;
983                     vidmem = 320; /* The 8800GTS uses 320MB, a 8800GTX can have 768MB */
984                 }
985                 /* Geforce8 - midend mobile */
986                 else if(strstr(gl_info->gl_renderer, "8600 M")) {
987                     gl_info->gl_card = CARD_NVIDIA_GEFORCE_8600MGT;
988                     vidmem = 512;
989                 }
990                 /* Geforce8 - midend */
991                 else if(strstr(gl_info->gl_renderer, "8600") ||
992                         strstr(gl_info->gl_renderer, "8700"))
993                 {
994                     gl_info->gl_card = CARD_NVIDIA_GEFORCE_8600GT;
995                     vidmem = 256;
996                 }
997                 /* Geforce8 - lowend */
998                 else if(strstr(gl_info->gl_renderer, "8300") ||
999                         strstr(gl_info->gl_renderer, "8400") ||
1000                         strstr(gl_info->gl_renderer, "8500"))
1001                 {
1002                     gl_info->gl_card = CARD_NVIDIA_GEFORCE_8300GS;
1003                     vidmem = 128; /* 128-256MB for a 8300, 256-512MB for a 8400 */
1004                 }
1005                 /* Geforce7 - highend */
1006                 else if(strstr(gl_info->gl_renderer, "7800") ||
1007                         strstr(gl_info->gl_renderer, "7900") ||
1008                         strstr(gl_info->gl_renderer, "7950") ||
1009                         strstr(gl_info->gl_renderer, "Quadro FX 4") ||
1010                         strstr(gl_info->gl_renderer, "Quadro FX 5"))
1011                 {
1012                     gl_info->gl_card = CARD_NVIDIA_GEFORCE_7800GT;
1013                     vidmem = 256; /* A 7800GT uses 256MB while highend 7900 cards can use 512MB */
1014                 }
1015                 /* Geforce7 midend */
1016                 else if(strstr(gl_info->gl_renderer, "7600") ||
1017                         strstr(gl_info->gl_renderer, "7700")) {
1018                     gl_info->gl_card = CARD_NVIDIA_GEFORCE_7600;
1019                     vidmem = 256; /* The 7600 uses 256-512MB */
1020                 /* Geforce7 lower medium */
1021                 } else if(strstr(gl_info->gl_renderer, "7400")) {
1022                     gl_info->gl_card = CARD_NVIDIA_GEFORCE_7400;
1023                     vidmem = 256; /* The 7400 uses 256-512MB */
1024                 }
1025                 /* Geforce6 highend */
1026                 else if(strstr(gl_info->gl_renderer, "6800"))
1027                 {
1028                     gl_info->gl_card = CARD_NVIDIA_GEFORCE_6800;
1029                     vidmem = 128; /* The 6800 uses 128-256MB, the 7600 uses 256-512MB */
1030                 }
1031                 /* Geforce6 - midend */
1032                 else if(strstr(gl_info->gl_renderer, "6600") ||
1033                         strstr(gl_info->gl_renderer, "6610") ||
1034                         strstr(gl_info->gl_renderer, "6700"))
1035                 {
1036                     gl_info->gl_card = CARD_NVIDIA_GEFORCE_6600GT;
1037                     vidmem = 128; /* A 6600GT has 128-256MB */
1038                 }
1039                 /* Geforce6/7 lowend */
1040                 else {
1041                     gl_info->gl_card = CARD_NVIDIA_GEFORCE_6200; /* Geforce 6100/6150/6200/7300/7400/7500 */
1042                     vidmem = 64; /* */
1043                 }
1044             } else if(WINE_D3D9_CAPABLE(gl_info)) {
1045                 /* GeforceFX - highend */
1046                 if (strstr(gl_info->gl_renderer, "5800") ||
1047                     strstr(gl_info->gl_renderer, "5900") ||
1048                     strstr(gl_info->gl_renderer, "5950") ||
1049                     strstr(gl_info->gl_renderer, "Quadro FX"))
1050                 {
1051                     gl_info->gl_card = CARD_NVIDIA_GEFORCEFX_5800;
1052                     vidmem = 256; /* 5800-5900 cards use 256MB */
1053                 }
1054                 /* GeforceFX - midend */
1055                 else if(strstr(gl_info->gl_renderer, "5600") ||
1056                         strstr(gl_info->gl_renderer, "5650") ||
1057                         strstr(gl_info->gl_renderer, "5700") ||
1058                         strstr(gl_info->gl_renderer, "5750"))
1059                 {
1060                     gl_info->gl_card = CARD_NVIDIA_GEFORCEFX_5600;
1061                     vidmem = 128; /* A 5600 uses 128-256MB */
1062                 }
1063                 /* GeforceFX - lowend */
1064                 else {
1065                     gl_info->gl_card = CARD_NVIDIA_GEFORCEFX_5200; /* GeforceFX 5100/5200/5250/5300/5500 */
1066                     vidmem = 64; /* Normal FX5200 cards use 64-256MB; laptop (non-standard) can have less */
1067                 }
1068             } else if(WINE_D3D8_CAPABLE(gl_info)) {
1069                 if (strstr(gl_info->gl_renderer, "GeForce4 Ti") || strstr(gl_info->gl_renderer, "Quadro4")) {
1070                     gl_info->gl_card = CARD_NVIDIA_GEFORCE4_TI4200; /* Geforce4 Ti4200/Ti4400/Ti4600/Ti4800, Quadro4 */
1071                     vidmem = 64; /* Geforce4 Ti cards have 64-128MB */
1072                 }
1073                 else {
1074                     gl_info->gl_card = CARD_NVIDIA_GEFORCE3; /* Geforce3 standard/Ti200/Ti500, Quadro DCC */
1075                     vidmem = 64; /* Geforce3 cards have 64-128MB */
1076                 }
1077             } else if(WINE_D3D7_CAPABLE(gl_info)) {
1078                 if (strstr(gl_info->gl_renderer, "GeForce4 MX")) {
1079                     gl_info->gl_card = CARD_NVIDIA_GEFORCE4_MX; /* MX420/MX440/MX460/MX4000 */
1080                     vidmem = 64; /* Most Geforce4MX GPUs have at least 64MB of memory, some early models had 32MB but most have 64MB or even 128MB */
1081                 }
1082                 else if(strstr(gl_info->gl_renderer, "GeForce2 MX") || strstr(gl_info->gl_renderer, "Quadro2 MXR")) {
1083                     gl_info->gl_card = CARD_NVIDIA_GEFORCE2_MX; /* Geforce2 standard/MX100/MX200/MX400, Quadro2 MXR */
1084                     vidmem = 32; /* Geforce2MX GPUs have 32-64MB of video memory */
1085                 }
1086                 else if(strstr(gl_info->gl_renderer, "GeForce2") || strstr(gl_info->gl_renderer, "Quadro2")) {
1087                     gl_info->gl_card = CARD_NVIDIA_GEFORCE2; /* Geforce2 GTS/Pro/Ti/Ultra, Quadro2 */
1088                     vidmem = 32; /* Geforce2 GPUs have 32-64MB of video memory */
1089                 }
1090                 else {
1091                     gl_info->gl_card = CARD_NVIDIA_GEFORCE; /* Geforce 256/DDR, Quadro */
1092                     vidmem = 32; /* Most Geforce1 cards have 32MB, there are also some rare 16 and 64MB (Dell) models */
1093                 }
1094             } else {
1095                 if (strstr(gl_info->gl_renderer, "TNT2")) {
1096                     gl_info->gl_card = CARD_NVIDIA_RIVA_TNT2; /* Riva TNT2 standard/M64/Pro/Ultra */
1097                     vidmem = 32; /* Most TNT2 boards have 32MB, though there are 16MB boards too */
1098                 }
1099                 else {
1100                     gl_info->gl_card = CARD_NVIDIA_RIVA_TNT; /* Riva TNT, Vanta */
1101                     vidmem = 16; /* Most TNT boards have 16MB, some rare models have 8MB */
1102                 }
1103             }
1104             break;
1105         case VENDOR_ATI:
1106             if(WINE_D3D9_CAPABLE(gl_info)) {
1107                 /* Radeon R6xx HD2900 - highend */
1108                 if (strstr(gl_info->gl_renderer, "HD 2900")) {
1109                     gl_info->gl_card = CARD_ATI_RADEON_HD2900;
1110                     vidmem = 512; /* HD2900 uses 512-1024MB */
1111                 }
1112                 /* Radeon R6xx HD2600- midend */
1113                 else if (strstr(gl_info->gl_renderer, "HD 2600")) {
1114                     gl_info->gl_card = CARD_ATI_RADEON_HD2600;
1115                     vidmem = 256; /* HD2600 uses 256-512MB */
1116                 }
1117                 /* Radeon R6xx HD2300/HD2400 - lowend */
1118                 else if (strstr(gl_info->gl_renderer, "HD 2300") ||
1119                          strstr(gl_info->gl_renderer, "HD 2400"))
1120                 {
1121                     gl_info->gl_card = CARD_ATI_RADEON_HD2300;
1122                     vidmem = 128; /* HD2300 uses at least 128MB, HD2400 uses 256MB */
1123                 }
1124                 /* Radeon R5xx */
1125                 else if (strstr(gl_info->gl_renderer, "X1600") ||
1126                          strstr(gl_info->gl_renderer, "X1650") ||
1127                          strstr(gl_info->gl_renderer, "X1800") ||
1128                          strstr(gl_info->gl_renderer, "X1900") ||
1129                          strstr(gl_info->gl_renderer, "X1950"))
1130                 {
1131                     gl_info->gl_card = CARD_ATI_RADEON_X1600;
1132                     vidmem = 128; /* X1600 uses 128-256MB, >=X1800 uses 256MB */
1133                 }
1134                 /* Radeon R4xx + X1300/X1400/X1450/X1550/X2300 (lowend R5xx) */
1135                 else if(strstr(gl_info->gl_renderer, "X700") ||
1136                         strstr(gl_info->gl_renderer, "X800") ||
1137                         strstr(gl_info->gl_renderer, "X850") ||
1138                         strstr(gl_info->gl_renderer, "X1300") ||
1139                         strstr(gl_info->gl_renderer, "X1400") ||
1140                         strstr(gl_info->gl_renderer, "X1450") ||
1141                         strstr(gl_info->gl_renderer, "X1550"))
1142                 {
1143                     gl_info->gl_card = CARD_ATI_RADEON_X700;
1144                     vidmem = 128; /* x700/x8*0 use 128-256MB, >=x1300 128-512MB */
1145                 }
1146                 /* Radeon R3xx */ 
1147                 else {
1148                     gl_info->gl_card = CARD_ATI_RADEON_9500; /* Radeon 9500/9550/9600/9700/9800/X300/X550/X600 */
1149                     vidmem = 64; /* Radeon 9500 uses 64MB, higher models use up to 256MB */
1150                 }
1151             } else if(WINE_D3D8_CAPABLE(gl_info)) {
1152                 gl_info->gl_card = CARD_ATI_RADEON_8500; /* Radeon 8500/9000/9100/9200/9300 */
1153                 vidmem = 64; /* 8500/9000 cards use mostly 64MB, though there are 32MB and 128MB models */
1154             } else if(WINE_D3D7_CAPABLE(gl_info)) {
1155                 gl_info->gl_card = CARD_ATI_RADEON_7200; /* Radeon 7000/7100/7200/7500 */
1156                 vidmem = 32; /* There are models with up to 64MB */
1157             } else {
1158                 gl_info->gl_card = CARD_ATI_RAGE_128PRO;
1159                 vidmem = 16; /* There are 16-32MB models */
1160             }
1161             break;
1162         case VENDOR_INTEL:
1163             if (strstr(gl_info->gl_renderer, "GMA 950")) {
1164                 /* MacOS calls the card GMA 950, but everywhere else the PCI ID is named 945GM */
1165                 gl_info->gl_card = CARD_INTEL_I945GM;
1166                 vidmem = 64;
1167             } else if (strstr(gl_info->gl_renderer, "915GM")) {
1168                 gl_info->gl_card = CARD_INTEL_I915GM;
1169             } else if (strstr(gl_info->gl_renderer, "915G")) {
1170                 gl_info->gl_card = CARD_INTEL_I915G;
1171             } else if (strstr(gl_info->gl_renderer, "865G")) {
1172                 gl_info->gl_card = CARD_INTEL_I865G;
1173             } else if (strstr(gl_info->gl_renderer, "855G")) {
1174                 gl_info->gl_card = CARD_INTEL_I855G;
1175             } else if (strstr(gl_info->gl_renderer, "830G")) {
1176                 gl_info->gl_card = CARD_INTEL_I830G;
1177             } else {
1178                 gl_info->gl_card = CARD_INTEL_I915G;
1179             }
1180             break;
1181         case VENDOR_MESA:
1182         case VENDOR_WINE:
1183         default:
1184             /* Default to generic Nvidia hardware based on the supported OpenGL extensions. The choice 
1185              * for Nvidia was because the hardware and drivers they make are of good quality. This makes
1186              * them a good generic choice.
1187              */
1188             gl_info->gl_vendor = VENDOR_NVIDIA;
1189             if(WINE_D3D9_CAPABLE(gl_info))
1190                 gl_info->gl_card = CARD_NVIDIA_GEFORCEFX_5600;
1191             else if(WINE_D3D8_CAPABLE(gl_info))
1192                 gl_info->gl_card = CARD_NVIDIA_GEFORCE3;
1193             else if(WINE_D3D7_CAPABLE(gl_info))
1194                 gl_info->gl_card = CARD_NVIDIA_GEFORCE;
1195             else if(WINE_D3D6_CAPABLE(gl_info))
1196                 gl_info->gl_card = CARD_NVIDIA_RIVA_TNT;
1197             else
1198                 gl_info->gl_card = CARD_NVIDIA_RIVA_128;
1199     }
1200     TRACE_(d3d_caps)("FOUND (fake) card: 0x%x (vendor id), 0x%x (device id)\n", gl_info->gl_vendor, gl_info->gl_card);
1201
1202     /* If we have an estimate use it, else default to 64MB;  */
1203     if(vidmem)
1204         gl_info->vidmem = vidmem*1024*1024; /* convert from MBs to bytes */
1205     else
1206         gl_info->vidmem = WINE_DEFAULT_VIDMEM;
1207
1208     /* Load all the lookup tables
1209     TODO: It may be a good idea to make minLookup and maxLookup const and populate them in wined3d_private.h where they are declared */
1210     minLookup[WINELOOKUP_WARPPARAM] = WINED3DTADDRESS_WRAP;
1211     maxLookup[WINELOOKUP_WARPPARAM] = WINED3DTADDRESS_MIRRORONCE;
1212
1213     minLookup[WINELOOKUP_MAGFILTER] = WINED3DTEXF_NONE;
1214     maxLookup[WINELOOKUP_MAGFILTER] = WINED3DTEXF_ANISOTROPIC;
1215
1216
1217     for (i = 0; i < MAX_LOOKUPS; i++) {
1218         stateLookup[i] = HeapAlloc(GetProcessHeap(), 0, sizeof(*stateLookup[i]) * (1 + maxLookup[i] - minLookup[i]) );
1219     }
1220
1221     stateLookup[WINELOOKUP_WARPPARAM][WINED3DTADDRESS_WRAP   - minLookup[WINELOOKUP_WARPPARAM]] = GL_REPEAT;
1222     stateLookup[WINELOOKUP_WARPPARAM][WINED3DTADDRESS_CLAMP  - minLookup[WINELOOKUP_WARPPARAM]] = GL_CLAMP_TO_EDGE;
1223     stateLookup[WINELOOKUP_WARPPARAM][WINED3DTADDRESS_BORDER - minLookup[WINELOOKUP_WARPPARAM]] =
1224              gl_info->supported[ARB_TEXTURE_BORDER_CLAMP] ? GL_CLAMP_TO_BORDER_ARB : GL_REPEAT;
1225     stateLookup[WINELOOKUP_WARPPARAM][WINED3DTADDRESS_BORDER - minLookup[WINELOOKUP_WARPPARAM]] =
1226              gl_info->supported[ARB_TEXTURE_BORDER_CLAMP] ? GL_CLAMP_TO_BORDER_ARB : GL_REPEAT;
1227     stateLookup[WINELOOKUP_WARPPARAM][WINED3DTADDRESS_MIRROR - minLookup[WINELOOKUP_WARPPARAM]] =
1228              gl_info->supported[ARB_TEXTURE_MIRRORED_REPEAT] ? GL_MIRRORED_REPEAT_ARB : GL_REPEAT;
1229     stateLookup[WINELOOKUP_WARPPARAM][WINED3DTADDRESS_MIRRORONCE - minLookup[WINELOOKUP_WARPPARAM]] =
1230              gl_info->supported[ATI_TEXTURE_MIRROR_ONCE] ? GL_MIRROR_CLAMP_TO_EDGE_ATI : GL_REPEAT;
1231
1232     stateLookup[WINELOOKUP_MAGFILTER][WINED3DTEXF_NONE        - minLookup[WINELOOKUP_MAGFILTER]]  = GL_NEAREST;
1233     stateLookup[WINELOOKUP_MAGFILTER][WINED3DTEXF_POINT       - minLookup[WINELOOKUP_MAGFILTER]] = GL_NEAREST;
1234     stateLookup[WINELOOKUP_MAGFILTER][WINED3DTEXF_LINEAR      - minLookup[WINELOOKUP_MAGFILTER]] = GL_LINEAR;
1235     stateLookup[WINELOOKUP_MAGFILTER][WINED3DTEXF_ANISOTROPIC - minLookup[WINELOOKUP_MAGFILTER]] =
1236              gl_info->supported[EXT_TEXTURE_FILTER_ANISOTROPIC] ? GL_LINEAR : GL_NEAREST;
1237
1238
1239     minMipLookup[WINED3DTEXF_NONE][WINED3DTEXF_NONE]     = GL_LINEAR;
1240     minMipLookup[WINED3DTEXF_NONE][WINED3DTEXF_POINT]    = GL_LINEAR;
1241     minMipLookup[WINED3DTEXF_NONE][WINED3DTEXF_LINEAR]   = GL_LINEAR;
1242     minMipLookup[WINED3DTEXF_POINT][WINED3DTEXF_NONE]    = GL_NEAREST;
1243     minMipLookup[WINED3DTEXF_POINT][WINED3DTEXF_POINT]   = GL_NEAREST_MIPMAP_NEAREST;
1244     minMipLookup[WINED3DTEXF_POINT][WINED3DTEXF_LINEAR]  = GL_NEAREST_MIPMAP_LINEAR;
1245     minMipLookup[WINED3DTEXF_LINEAR][WINED3DTEXF_NONE]   = GL_LINEAR;
1246     minMipLookup[WINED3DTEXF_LINEAR][WINED3DTEXF_POINT]  = GL_LINEAR_MIPMAP_NEAREST;
1247     minMipLookup[WINED3DTEXF_LINEAR][WINED3DTEXF_LINEAR] = GL_LINEAR_MIPMAP_LINEAR;
1248     minMipLookup[WINED3DTEXF_ANISOTROPIC][WINED3DTEXF_NONE]   = gl_info->supported[EXT_TEXTURE_FILTER_ANISOTROPIC] ?
1249     GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR;
1250     minMipLookup[WINED3DTEXF_ANISOTROPIC][WINED3DTEXF_POINT]  = gl_info->supported[EXT_TEXTURE_FILTER_ANISOTROPIC] ? GL_LINEAR_MIPMAP_NEAREST : GL_LINEAR;
1251     minMipLookup[WINED3DTEXF_ANISOTROPIC][WINED3DTEXF_LINEAR] = gl_info->supported[EXT_TEXTURE_FILTER_ANISOTROPIC] ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR;
1252
1253 /* TODO: config lookups */
1254
1255     /* Make sure there's an active HDC else the WGL extensions will fail */
1256     hdc = pwglGetCurrentDC();
1257     if (hdc) {
1258         WGL_Extensions = GL_EXTCALL(wglGetExtensionsStringARB(hdc));
1259         TRACE_(d3d_caps)("WGL_Extensions reported:\n");
1260
1261         if (NULL == WGL_Extensions) {
1262             ERR("   WGL_Extensions returns NULL\n");
1263         } else {
1264             while (*WGL_Extensions != 0x00) {
1265                 const char *Start;
1266                 char ThisExtn[256];
1267                 size_t len;
1268
1269                 while (isspace(*WGL_Extensions)) WGL_Extensions++;
1270                 Start = WGL_Extensions;
1271                 while (!isspace(*WGL_Extensions) && *WGL_Extensions != 0x00) {
1272                     WGL_Extensions++;
1273                 }
1274
1275                 len = WGL_Extensions - Start;
1276                 if (len == 0 || len >= sizeof(ThisExtn))
1277                     continue;
1278
1279                 memcpy(ThisExtn, Start, len);
1280                 ThisExtn[len] = '\0';
1281                 TRACE_(d3d_caps)("- %s\n", ThisExtn);
1282
1283                 if (!strcmp(ThisExtn, "WGL_ARB_pbuffer")) {
1284                     gl_info->supported[WGL_ARB_PBUFFER] = TRUE;
1285                     TRACE_(d3d_caps)("FOUND: WGL_ARB_pbuffer support\n");
1286                 }
1287             }
1288         }
1289     }
1290     LEAVE_GL();
1291
1292     return return_value;
1293 }
1294 #undef GLINFO_LOCATION
1295
1296 /**********************************************************
1297  * IWineD3D implementation follows
1298  **********************************************************/
1299
1300 static UINT     WINAPI IWineD3DImpl_GetAdapterCount (IWineD3D *iface) {
1301     IWineD3DImpl *This = (IWineD3DImpl *)iface;
1302
1303     TRACE_(d3d_caps)("(%p): Reporting %d adapters\n", This, numAdapters);
1304     return numAdapters;
1305 }
1306
1307 static HRESULT  WINAPI IWineD3DImpl_RegisterSoftwareDevice(IWineD3D *iface, void* pInitializeFunction) {
1308     IWineD3DImpl *This = (IWineD3DImpl *)iface;
1309     FIXME("(%p)->(%p): stub\n", This, pInitializeFunction);
1310     return WINED3D_OK;
1311 }
1312
1313 static HMONITOR WINAPI IWineD3DImpl_GetAdapterMonitor(IWineD3D *iface, UINT Adapter) {
1314     IWineD3DImpl *This = (IWineD3DImpl *)iface;
1315
1316     if (Adapter >= IWineD3DImpl_GetAdapterCount(iface)) {
1317         return NULL;
1318     }
1319
1320     TRACE_(d3d_caps)("(%p)->(%d)\n", This, Adapter);
1321     return MonitorFromPoint(Adapters[Adapter].monitorPoint, MONITOR_DEFAULTTOPRIMARY);
1322 }
1323
1324 /* FIXME: GetAdapterModeCount and EnumAdapterModes currently only returns modes
1325      of the same bpp but different resolutions                                  */
1326
1327 /* Note: dx9 supplies a format. Calls from d3d8 supply WINED3DFMT_UNKNOWN */
1328 static UINT     WINAPI IWineD3DImpl_GetAdapterModeCount(IWineD3D *iface, UINT Adapter, WINED3DFORMAT Format) {
1329     IWineD3DImpl *This = (IWineD3DImpl *)iface;
1330     TRACE_(d3d_caps)("(%p}->(Adapter: %d, Format: %s)\n", This, Adapter, debug_d3dformat(Format));
1331
1332     if (Adapter >= IWineD3D_GetAdapterCount(iface)) {
1333         return 0;
1334     }
1335
1336     /* TODO: Store modes per adapter and read it from the adapter structure */
1337     if (Adapter == 0) { /* Display */
1338         int i = 0;
1339         int j = 0;
1340
1341         if (!DEBUG_SINGLE_MODE) {
1342             DEVMODEW DevModeW;
1343
1344             ZeroMemory(&DevModeW, sizeof(DevModeW));
1345             DevModeW.dmSize = sizeof(DevModeW);
1346             while (EnumDisplaySettingsExW(NULL, j, &DevModeW, 0)) {
1347                 j++;
1348                 switch (Format)
1349                 {
1350                     case WINED3DFMT_UNKNOWN:
1351                         /* This is for D3D8, do not enumerate P8 here */
1352                         if (DevModeW.dmBitsPerPel == 32 ||
1353                             DevModeW.dmBitsPerPel == 16) i++;
1354                         break;
1355                     case WINED3DFMT_X8R8G8B8:
1356                         if (DevModeW.dmBitsPerPel == 32) i++;
1357                         break;
1358                     case WINED3DFMT_R5G6B5:
1359                         if (DevModeW.dmBitsPerPel == 16) i++;
1360                         break;
1361                     case WINED3DFMT_P8:
1362                         if (DevModeW.dmBitsPerPel == 8) i++;
1363                         break;
1364                     default:
1365                         /* Skip other modes as they do not match the requested format */
1366                         break;
1367                 }
1368             }
1369         } else {
1370             i = 1;
1371             j = 1;
1372         }
1373
1374         TRACE_(d3d_caps)("(%p}->(Adapter: %d) => %d (out of %d)\n", This, Adapter, i, j);
1375         return i;
1376     } else {
1377         FIXME_(d3d_caps)("Adapter not primary display\n");
1378     }
1379     return 0;
1380 }
1381
1382 /* Note: dx9 supplies a format. Calls from d3d8 supply WINED3DFMT_UNKNOWN */
1383 static HRESULT WINAPI IWineD3DImpl_EnumAdapterModes(IWineD3D *iface, UINT Adapter, WINED3DFORMAT Format, UINT Mode, WINED3DDISPLAYMODE* pMode) {
1384     IWineD3DImpl *This = (IWineD3DImpl *)iface;
1385     TRACE_(d3d_caps)("(%p}->(Adapter:%d, mode:%d, pMode:%p, format:%s)\n", This, Adapter, Mode, pMode, debug_d3dformat(Format));
1386
1387     /* Validate the parameters as much as possible */
1388     if (NULL == pMode ||
1389         Adapter >= IWineD3DImpl_GetAdapterCount(iface) ||
1390         Mode    >= IWineD3DImpl_GetAdapterModeCount(iface, Adapter, Format)) {
1391         return WINED3DERR_INVALIDCALL;
1392     }
1393
1394     /* TODO: Store modes per adapter and read it from the adapter structure */
1395     if (Adapter == 0 && !DEBUG_SINGLE_MODE) { /* Display */
1396         DEVMODEW DevModeW;
1397         int ModeIdx = 0;
1398         int i = 0;
1399         int j = 0;
1400
1401         ZeroMemory(&DevModeW, sizeof(DevModeW));
1402         DevModeW.dmSize = sizeof(DevModeW);
1403
1404         /* If we are filtering to a specific format (D3D9), then need to skip
1405            all unrelated modes, but if mode is irrelevant (D3D8), then we can
1406            just count through the ones with valid bit depths */
1407         while ((i<=Mode) && EnumDisplaySettingsExW(NULL, j++, &DevModeW, 0)) {
1408             switch (Format)
1409             {
1410                 case WINED3DFMT_UNKNOWN:
1411                     /* This is D3D8. Do not enumerate P8 here */
1412                     if (DevModeW.dmBitsPerPel == 32 ||
1413                         DevModeW.dmBitsPerPel == 16) i++;
1414                     break;
1415                 case WINED3DFMT_X8R8G8B8:
1416                     if (DevModeW.dmBitsPerPel == 32) i++;
1417                     break;
1418                 case WINED3DFMT_R5G6B5:
1419                     if (DevModeW.dmBitsPerPel == 16) i++;
1420                     break;
1421                 case WINED3DFMT_P8:
1422                     if (DevModeW.dmBitsPerPel == 8) i++;
1423                     break;
1424                 default:
1425                     /* Modes that don't match what we support can get an early-out */
1426                     TRACE_(d3d_caps)("Searching for %s, returning D3DERR_INVALIDCALL\n", debug_d3dformat(Format));
1427                     return WINED3DERR_INVALIDCALL;
1428             }
1429         }
1430
1431         if (i == 0) {
1432             TRACE_(d3d_caps)("No modes found for format (%x - %s)\n", Format, debug_d3dformat(Format));
1433             return WINED3DERR_INVALIDCALL;
1434         }
1435         ModeIdx = j - 1;
1436
1437         /* Now get the display mode via the calculated index */
1438         if (EnumDisplaySettingsExW(NULL, ModeIdx, &DevModeW, 0)) {
1439             pMode->Width        = DevModeW.dmPelsWidth;
1440             pMode->Height       = DevModeW.dmPelsHeight;
1441             pMode->RefreshRate  = WINED3DADAPTER_DEFAULT;
1442             if (DevModeW.dmFields & DM_DISPLAYFREQUENCY)
1443                 pMode->RefreshRate = DevModeW.dmDisplayFrequency;
1444
1445             if (Format == WINED3DFMT_UNKNOWN) {
1446                 pMode->Format = pixelformat_for_depth(DevModeW.dmBitsPerPel);
1447             } else {
1448                 pMode->Format = Format;
1449             }
1450         } else {
1451             TRACE_(d3d_caps)("Requested mode out of range %d\n", Mode);
1452             return WINED3DERR_INVALIDCALL;
1453         }
1454
1455         TRACE_(d3d_caps)("W %d H %d rr %d fmt (%x - %s) bpp %u\n", pMode->Width, pMode->Height,
1456                 pMode->RefreshRate, pMode->Format, debug_d3dformat(pMode->Format),
1457                 DevModeW.dmBitsPerPel);
1458
1459     } else if (DEBUG_SINGLE_MODE) {
1460         /* Return one setting of the format requested */
1461         if (Mode > 0) return WINED3DERR_INVALIDCALL;
1462         pMode->Width        = 800;
1463         pMode->Height       = 600;
1464         pMode->RefreshRate  = 60;
1465         pMode->Format       = (Format == WINED3DFMT_UNKNOWN) ? WINED3DFMT_X8R8G8B8 : Format;
1466     } else {
1467         FIXME_(d3d_caps)("Adapter not primary display\n");
1468     }
1469
1470     return WINED3D_OK;
1471 }
1472
1473 static HRESULT WINAPI IWineD3DImpl_GetAdapterDisplayMode(IWineD3D *iface, UINT Adapter, WINED3DDISPLAYMODE* pMode) {
1474     IWineD3DImpl *This = (IWineD3DImpl *)iface;
1475     TRACE_(d3d_caps)("(%p}->(Adapter: %d, pMode: %p)\n", This, Adapter, pMode);
1476
1477     if (NULL == pMode ||
1478         Adapter >= IWineD3D_GetAdapterCount(iface)) {
1479         return WINED3DERR_INVALIDCALL;
1480     }
1481
1482     if (Adapter == 0) { /* Display */
1483         int bpp = 0;
1484         DEVMODEW DevModeW;
1485
1486         ZeroMemory(&DevModeW, sizeof(DevModeW));
1487         DevModeW.dmSize = sizeof(DevModeW);
1488
1489         EnumDisplaySettingsExW(NULL, ENUM_CURRENT_SETTINGS, &DevModeW, 0);
1490         pMode->Width        = DevModeW.dmPelsWidth;
1491         pMode->Height       = DevModeW.dmPelsHeight;
1492         bpp                 = DevModeW.dmBitsPerPel;
1493         pMode->RefreshRate  = WINED3DADAPTER_DEFAULT;
1494         if (DevModeW.dmFields&DM_DISPLAYFREQUENCY)
1495         {
1496             pMode->RefreshRate = DevModeW.dmDisplayFrequency;
1497         }
1498
1499         pMode->Format = pixelformat_for_depth(bpp);
1500     } else {
1501         FIXME_(d3d_caps)("Adapter not primary display\n");
1502     }
1503
1504     TRACE_(d3d_caps)("returning w:%d, h:%d, ref:%d, fmt:%s\n", pMode->Width,
1505           pMode->Height, pMode->RefreshRate, debug_d3dformat(pMode->Format));
1506     return WINED3D_OK;
1507 }
1508
1509 /* NOTE: due to structure differences between dx8 and dx9 D3DADAPTER_IDENTIFIER,
1510    and fields being inserted in the middle, a new structure is used in place    */
1511 static HRESULT WINAPI IWineD3DImpl_GetAdapterIdentifier(IWineD3D *iface, UINT Adapter, DWORD Flags,
1512                                                    WINED3DADAPTER_IDENTIFIER* pIdentifier) {
1513     IWineD3DImpl *This = (IWineD3DImpl *)iface;
1514
1515     TRACE_(d3d_caps)("(%p}->(Adapter: %d, Flags: %x, pId=%p)\n", This, Adapter, Flags, pIdentifier);
1516
1517     if (Adapter >= IWineD3D_GetAdapterCount(iface)) {
1518         return WINED3DERR_INVALIDCALL;
1519     }
1520
1521     /* Return the information requested */
1522     TRACE_(d3d_caps)("device/Vendor Name and Version detection using FillGLCaps\n");
1523     strcpy(pIdentifier->Driver, Adapters[Adapter].driver);
1524     strcpy(pIdentifier->Description, Adapters[Adapter].description);
1525
1526     /* Note dx8 doesn't supply a DeviceName */
1527     if (NULL != pIdentifier->DeviceName) strcpy(pIdentifier->DeviceName, "\\\\.\\DISPLAY"); /* FIXME: May depend on desktop? */
1528     /* Current Windows drivers have versions like 6.14.... (some older have an earlier version) */
1529     pIdentifier->DriverVersion->u.HighPart = MAKEDWORD_VERSION(6, 14);
1530     pIdentifier->DriverVersion->u.LowPart = Adapters[Adapter].gl_info.gl_driver_version;
1531     *(pIdentifier->VendorId) = Adapters[Adapter].gl_info.gl_vendor;
1532     *(pIdentifier->DeviceId) = Adapters[Adapter].gl_info.gl_card;
1533     *(pIdentifier->SubSysId) = 0;
1534     *(pIdentifier->Revision) = 0;
1535
1536     /*FIXME: memcpy(&pIdentifier->DeviceIdentifier, ??, sizeof(??GUID)); */
1537     if (Flags & WINED3DENUM_NO_WHQL_LEVEL) {
1538         *(pIdentifier->WHQLLevel) = 0;
1539     } else {
1540         *(pIdentifier->WHQLLevel) = 1;
1541     }
1542
1543     return WINED3D_OK;
1544 }
1545
1546 static BOOL IWineD3DImpl_IsPixelFormatCompatibleWithRenderFmt(const WineD3D_PixelFormat *cfg, WINED3DFORMAT Format) {
1547     short redSize, greenSize, blueSize, alphaSize, colorBits;
1548
1549     if(!cfg)
1550         return FALSE;
1551
1552     if(!getColorBits(Format, &redSize, &greenSize, &blueSize, &alphaSize, &colorBits)) {
1553         ERR("Unable to check compatibility for Format=%s\n", debug_d3dformat(Format));
1554         return FALSE;
1555     }
1556
1557     if(cfg->redSize < redSize)
1558         return FALSE;
1559
1560     if(cfg->greenSize < greenSize)
1561         return FALSE;
1562
1563     if(cfg->blueSize < blueSize)
1564         return FALSE;
1565
1566     if(cfg->alphaSize < alphaSize)
1567         return FALSE;
1568
1569     return TRUE;
1570 }
1571
1572 static BOOL IWineD3DImpl_IsPixelFormatCompatibleWithDepthFmt(const WineD3D_PixelFormat *cfg, WINED3DFORMAT Format) {
1573     short depthSize, stencilSize;
1574
1575     if(!cfg)
1576         return FALSE;
1577
1578     if(!getDepthStencilBits(Format, &depthSize, &stencilSize)) {
1579         ERR("Unable to check compatibility for Format=%s\n", debug_d3dformat(Format));
1580         return FALSE;
1581     }
1582
1583     if(cfg->depthSize < depthSize)
1584         return FALSE;
1585
1586     if(cfg->stencilSize < stencilSize)
1587         return FALSE;
1588
1589     return TRUE;
1590 }
1591
1592 static HRESULT WINAPI IWineD3DImpl_CheckDepthStencilMatch(IWineD3D *iface, UINT Adapter, WINED3DDEVTYPE DeviceType,
1593                                                    WINED3DFORMAT AdapterFormat,
1594                                                    WINED3DFORMAT RenderTargetFormat,
1595                                                    WINED3DFORMAT DepthStencilFormat) {
1596     IWineD3DImpl *This = (IWineD3DImpl *)iface;
1597     int nCfgs;
1598     WineD3D_PixelFormat *cfgs;
1599     int it;
1600
1601     WARN_(d3d_caps)("(%p)-> (STUB) (Adptr:%d, DevType:(%x,%s), AdptFmt:(%x,%s), RendrTgtFmt:(%x,%s), DepthStencilFmt:(%x,%s))\n",
1602            This, Adapter,
1603            DeviceType, debug_d3ddevicetype(DeviceType),
1604            AdapterFormat, debug_d3dformat(AdapterFormat),
1605            RenderTargetFormat, debug_d3dformat(RenderTargetFormat),
1606            DepthStencilFormat, debug_d3dformat(DepthStencilFormat));
1607
1608     if (Adapter >= IWineD3D_GetAdapterCount(iface)) {
1609         TRACE("(%p) Failed: Atapter (%u) higher than supported adapters (%u) returning WINED3DERR_INVALIDCALL\n", This, Adapter, IWineD3D_GetAdapterCount(iface));
1610         return WINED3DERR_INVALIDCALL;
1611     }
1612
1613     cfgs = Adapters[Adapter].cfgs;
1614     nCfgs = Adapters[Adapter].nCfgs;
1615     for (it = 0; it < nCfgs; ++it) {
1616         if (IWineD3DImpl_IsPixelFormatCompatibleWithRenderFmt(&cfgs[it], RenderTargetFormat)) {
1617             if (IWineD3DImpl_IsPixelFormatCompatibleWithDepthFmt(&cfgs[it], DepthStencilFormat)) {
1618                 TRACE_(d3d_caps)("(%p) : Formats matched\n", This);
1619                 return WINED3D_OK;
1620             }
1621         }
1622     }
1623     WARN_(d3d_caps)("unsupported format pair: %s and %s\n", debug_d3dformat(RenderTargetFormat), debug_d3dformat(DepthStencilFormat));
1624
1625     return WINED3DERR_NOTAVAILABLE;
1626 }
1627
1628 static HRESULT WINAPI IWineD3DImpl_CheckDeviceMultiSampleType(IWineD3D *iface, UINT Adapter, WINED3DDEVTYPE DeviceType, 
1629                                                        WINED3DFORMAT SurfaceFormat,
1630                                                        BOOL Windowed, WINED3DMULTISAMPLE_TYPE MultiSampleType, DWORD*   pQualityLevels) {
1631
1632     IWineD3DImpl *This = (IWineD3DImpl *)iface;
1633     TRACE_(d3d_caps)("(%p)-> (STUB) (Adptr:%d, DevType:(%x,%s), SurfFmt:(%x,%s), Win?%d, MultiSamp:%x, pQual:%p)\n",
1634           This,
1635           Adapter,
1636           DeviceType, debug_d3ddevicetype(DeviceType),
1637           SurfaceFormat, debug_d3dformat(SurfaceFormat),
1638           Windowed,
1639           MultiSampleType,
1640           pQualityLevels);
1641
1642     if (Adapter >= IWineD3D_GetAdapterCount(iface)) {
1643         return WINED3DERR_INVALIDCALL;
1644     }
1645
1646     /* TODO: Store in Adapter structure */
1647     if (pQualityLevels != NULL) {
1648         static int s_single_shot = 0;
1649         if (!s_single_shot) {
1650             FIXME("Quality levels unsupported at present\n");
1651             s_single_shot = 1;
1652         }
1653         *pQualityLevels = 1; /* Guess at a value! */
1654     }
1655
1656     if (WINED3DMULTISAMPLE_NONE == MultiSampleType) return WINED3D_OK;
1657     return WINED3DERR_NOTAVAILABLE;
1658 }
1659
1660 static HRESULT WINAPI IWineD3DImpl_CheckDeviceType(IWineD3D *iface, UINT Adapter, WINED3DDEVTYPE CheckType,
1661                                             WINED3DFORMAT DisplayFormat, WINED3DFORMAT BackBufferFormat, BOOL Windowed) {
1662
1663     IWineD3DImpl *This = (IWineD3DImpl *)iface;
1664     int nCfgs = 0;
1665     WineD3D_PixelFormat *cfgs;
1666     int it;
1667     HRESULT hr = WINED3DERR_NOTAVAILABLE;
1668
1669     TRACE_(d3d_caps)("(%p)-> (STUB) (Adptr:%d, CheckType:(%x,%s), DispFmt:(%x,%s), BackBuf:(%x,%s), Win?%d): stub\n",
1670           This,
1671           Adapter,
1672           CheckType, debug_d3ddevicetype(CheckType),
1673           DisplayFormat, debug_d3dformat(DisplayFormat),
1674           BackBufferFormat, debug_d3dformat(BackBufferFormat),
1675           Windowed);
1676
1677     if (Adapter >= IWineD3D_GetAdapterCount(iface)) {
1678         WARN_(d3d_caps)("Adapter >= IWineD3D_GetAdapterCount(iface), returning WINED3DERR_INVALIDCALL\n");
1679         return WINED3DERR_INVALIDCALL;
1680     }
1681
1682     cfgs = Adapters[Adapter].cfgs;
1683     nCfgs = Adapters[Adapter].nCfgs;
1684     for (it = 0; it < nCfgs; ++it) {
1685         if (IWineD3DImpl_IsPixelFormatCompatibleWithRenderFmt(&cfgs[it], DisplayFormat)) {
1686             hr = WINED3D_OK;
1687             TRACE_(d3d_caps)("OK\n");
1688             break ;
1689         }
1690     }
1691
1692     if(hr != WINED3D_OK)
1693         ERR("unsupported format %s\n", debug_d3dformat(DisplayFormat));
1694
1695     if(hr != WINED3D_OK)
1696         TRACE_(d3d_caps)("returning something different from WINED3D_OK\n");
1697
1698     return hr;
1699 }
1700
1701 #define GLINFO_LOCATION Adapters[Adapter].gl_info
1702 static HRESULT WINAPI IWineD3DImpl_CheckDeviceFormat(IWineD3D *iface, UINT Adapter, WINED3DDEVTYPE DeviceType, 
1703                                               WINED3DFORMAT AdapterFormat, DWORD Usage, WINED3DRESOURCETYPE RType, WINED3DFORMAT CheckFormat) {
1704     IWineD3DImpl *This = (IWineD3DImpl *)iface;
1705     TRACE_(d3d_caps)("(%p)-> (STUB) (Adptr:%d, DevType:(%u,%s), AdptFmt:(%u,%s), Use:(%u,%s,%s), ResTyp:(%x,%s), CheckFmt:(%u,%s))\n",
1706           This,
1707           Adapter,
1708           DeviceType, debug_d3ddevicetype(DeviceType),
1709           AdapterFormat, debug_d3dformat(AdapterFormat),
1710           Usage, debug_d3dusage(Usage), debug_d3dusagequery(Usage),
1711           RType, debug_d3dresourcetype(RType),
1712           CheckFormat, debug_d3dformat(CheckFormat));
1713
1714     if (Adapter >= IWineD3D_GetAdapterCount(iface)) {
1715         return WINED3DERR_INVALIDCALL;
1716     }
1717
1718     if (Usage & WINED3DUSAGE_QUERY_FILTER) {
1719         switch (CheckFormat) {
1720             /* Filtering not supported */
1721             case WINED3DFMT_R32F:
1722             case WINED3DFMT_A32B32G32R32F:
1723                 TRACE_(d3d_caps)("[FAILED]\n");
1724                 return WINED3DERR_NOTAVAILABLE;
1725             default:
1726                 break;
1727         }
1728     }
1729
1730     if (Usage & WINED3DUSAGE_AUTOGENMIPMAP) {
1731         if(!GL_SUPPORT(SGIS_GENERATE_MIPMAP)) {
1732             TRACE_(d3d_caps)("[FAILED] - No mipmap generation support\n");
1733             return WINED3DERR_NOTAVAILABLE;
1734         }
1735     }
1736
1737     if(RType == WINED3DRTYPE_VOLUMETEXTURE) {
1738         if(!GL_SUPPORT(EXT_TEXTURE3D)) {
1739             TRACE_(d3d_caps)("[FAILED] - No volume texture support\n");
1740             return WINED3DERR_NOTAVAILABLE;
1741         }
1742         /* Filter formats that need conversion; For one part, this conversion is unimplemented,
1743          * and volume textures are huge, so it would be a big performance hit. Unless we hit an
1744          * app needing one of those formats, don't advertize them to avoid leading apps into
1745          * temptation. The windows drivers don't support most of those formats on volumes anyway,
1746          * except of R32F.
1747          */
1748         switch(CheckFormat) {
1749             case WINED3DFMT_P8:
1750             case WINED3DFMT_A4L4:
1751             case WINED3DFMT_R32F:
1752             case WINED3DFMT_R16F:
1753             case WINED3DFMT_X8L8V8U8:
1754             case WINED3DFMT_L6V5U5:
1755             case WINED3DFMT_G16R16:
1756                 TRACE_(d3d_caps)("[FAILED] - No converted formats on volumes\n");
1757                 return WINED3DERR_NOTAVAILABLE;
1758
1759             case WINED3DFMT_Q8W8V8U8:
1760             case WINED3DFMT_V16U16:
1761             if(!GL_SUPPORT(NV_TEXTURE_SHADER)) {
1762                 TRACE_(d3d_caps)("[FAILED] - No converted formats on volumes\n");
1763                 return WINED3DERR_NOTAVAILABLE;
1764             }
1765             break;
1766
1767             case WINED3DFMT_V8U8:
1768             if(!GL_SUPPORT(NV_TEXTURE_SHADER) || !GL_SUPPORT(ATI_ENVMAP_BUMPMAP)) {
1769                 TRACE_(d3d_caps)("[FAILED] - No converted formats on volumes\n");
1770                 return WINED3DERR_NOTAVAILABLE;
1771             }
1772             break;
1773
1774             case WINED3DFMT_DXT1:
1775             case WINED3DFMT_DXT2:
1776             case WINED3DFMT_DXT3:
1777             case WINED3DFMT_DXT4:
1778             case WINED3DFMT_DXT5:
1779                 /* The GL_EXT_texture_compression_s3tc spec requires that loading an s3tc
1780                  * compressed texture results in an error. While the D3D refrast does
1781                  * support s3tc volumes, at least the nvidia windows driver does not, so
1782                  * we're free not to support this format.
1783                  */
1784                 TRACE_(d3d_caps)("[FAILED] - DXTn does not support 3D textures\n");
1785                 return WINED3DERR_NOTAVAILABLE;
1786
1787             default:
1788                 /* Do nothing, continue with checking the format below */
1789                 break;
1790         }
1791     }
1792     /* TODO: Check support against more of the WINED3DUSAGE_QUERY_* constants
1793      * See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/directx9_c/IDirect3D9__CheckDeviceFormat.asp
1794      * and http://msdn.microsoft.com/library/default.asp?url=/library/en-us/directx9_c/D3DUSAGE_QUERY.asp */
1795     if (Usage & WINED3DUSAGE_QUERY_VERTEXTEXTURE) {
1796         if (!GL_LIMITS(vertex_samplers)) {
1797             TRACE_(d3d_caps)("[FAILED]\n");
1798             return WINED3DERR_NOTAVAILABLE;
1799         }
1800
1801         switch (CheckFormat) {
1802             case WINED3DFMT_A32B32G32R32F:
1803                 if (!GL_SUPPORT(ARB_TEXTURE_FLOAT)) {
1804                     TRACE_(d3d_caps)("[FAILED]\n");
1805                     return WINED3DERR_NOTAVAILABLE;
1806                 }
1807                 TRACE_(d3d_caps)("[OK]\n");
1808                 return WINED3D_OK;
1809
1810             default:
1811                 TRACE_(d3d_caps)("[FAILED]\n");
1812                 return WINED3DERR_NOTAVAILABLE;
1813         }
1814     }
1815
1816     if(Usage & WINED3DUSAGE_DEPTHSTENCIL) {
1817         switch (CheckFormat) {
1818             /* In theory we could do all formats, just fetch them accordingly should the buffer be locked.
1819              * Windows supports only those 3, and enumerating the other formats confuses applications
1820              */
1821             case WINED3DFMT_D24S8:
1822             case WINED3DFMT_D24X8:
1823             case WINED3DFMT_D16:
1824                 TRACE_(d3d_caps)("[OK]\n");
1825                 return WINED3D_OK;
1826             case WINED3DFMT_D16_LOCKABLE:
1827             case WINED3DFMT_D24FS8:
1828             case WINED3DFMT_D32F_LOCKABLE:
1829             case WINED3DFMT_D24X4S4:
1830             case WINED3DFMT_D15S1:
1831             case WINED3DFMT_D32:
1832                 TRACE_(d3d_caps)("[FAILED]. Disabled because not enumerated on windows\n");
1833                 return WINED3DERR_NOTAVAILABLE;
1834             default:
1835                 TRACE_(d3d_caps)("[FAILED]\n");
1836                 return WINED3DERR_NOTAVAILABLE;
1837         }
1838     } else if(Usage & WINED3DUSAGE_RENDERTARGET) {
1839         switch (CheckFormat) {
1840             case WINED3DFMT_R8G8B8:
1841             case WINED3DFMT_A8R8G8B8:
1842             case WINED3DFMT_X8R8G8B8:
1843             case WINED3DFMT_R5G6B5:
1844             case WINED3DFMT_X1R5G5B5:
1845             case WINED3DFMT_A1R5G5B5:
1846             case WINED3DFMT_A4R4G4B4:
1847             case WINED3DFMT_R3G3B2:
1848             case WINED3DFMT_X4R4G4B4:
1849             case WINED3DFMT_A8B8G8R8:
1850             case WINED3DFMT_X8B8G8R8:
1851             case WINED3DFMT_P8:
1852             case WINED3DFMT_G16R16:
1853                 TRACE_(d3d_caps)("[OK]\n");
1854                 return WINED3D_OK;
1855             case WINED3DFMT_R16F:
1856             case WINED3DFMT_A16B16G16R16F:
1857                 if (!GL_SUPPORT(ARB_HALF_FLOAT_PIXEL) || !GL_SUPPORT(ARB_TEXTURE_FLOAT)) {
1858                     TRACE_(d3d_caps)("[FAILED]\n");
1859                     return WINED3DERR_NOTAVAILABLE;
1860                 }
1861                 TRACE_(d3d_caps)("[OK]\n");
1862                 return WINED3D_OK;
1863             case WINED3DFMT_A32B32G32R32F:
1864                if (!GL_SUPPORT(ARB_TEXTURE_FLOAT)) {
1865                     TRACE_(d3d_caps)("[FAILED]\n");
1866                     return WINED3DERR_NOTAVAILABLE;
1867                 }
1868                 TRACE_(d3d_caps)("[OK]\n");
1869                 return WINED3D_OK;
1870             default:
1871                 TRACE_(d3d_caps)("[FAILED]\n");
1872                 return WINED3DERR_NOTAVAILABLE;
1873         }
1874     } else if(Usage & WINED3DUSAGE_QUERY_LEGACYBUMPMAP) {
1875         if(GL_SUPPORT(NV_REGISTER_COMBINERS) && GL_SUPPORT(NV_TEXTURE_SHADER2)) {
1876             switch (CheckFormat) {
1877                 case WINED3DFMT_V8U8:
1878                     TRACE_(d3d_caps)("[OK]\n");
1879                     return WINED3D_OK;
1880                 /* TODO: Other bump map formats */
1881                 default:
1882                     TRACE_(d3d_caps)("[FAILED]\n");
1883                     return WINED3DERR_NOTAVAILABLE;
1884             }
1885         }
1886         if(GL_SUPPORT(ATI_ENVMAP_BUMPMAP)) {
1887             switch (CheckFormat) {
1888                 case WINED3DFMT_V8U8:
1889                     TRACE_(d3d_caps)("[OK]\n");
1890                     return WINED3D_OK;
1891                 default:
1892                     TRACE_(d3d_caps)("[FAILED]\n");
1893                     return WINED3DERR_NOTAVAILABLE;
1894             }
1895         }
1896         TRACE_(d3d_caps)("[FAILED]\n");
1897         return WINED3DERR_NOTAVAILABLE;
1898     }
1899
1900     if (GL_SUPPORT(EXT_TEXTURE_COMPRESSION_S3TC)) {
1901         switch (CheckFormat) {
1902         case WINED3DFMT_DXT1:
1903         case WINED3DFMT_DXT2:
1904         case WINED3DFMT_DXT3:
1905         case WINED3DFMT_DXT4:
1906         case WINED3DFMT_DXT5:
1907           TRACE_(d3d_caps)("[OK]\n");
1908           return WINED3D_OK;
1909         default:
1910             break; /* Avoid compiler warnings */
1911         }
1912     }
1913
1914     /* Check for supported sRGB formats (Texture loading and framebuffer) */
1915     if (GL_SUPPORT(EXT_TEXTURE_SRGB) && (Usage & WINED3DUSAGE_QUERY_SRGBREAD)) {
1916         switch (CheckFormat) {
1917             case WINED3DFMT_A8R8G8B8:
1918             case WINED3DFMT_X8R8G8B8:
1919             case WINED3DFMT_A4R4G4B4:
1920             case WINED3DFMT_L8:
1921             case WINED3DFMT_A8L8:
1922             case WINED3DFMT_DXT1:
1923             case WINED3DFMT_DXT2:
1924             case WINED3DFMT_DXT3:
1925             case WINED3DFMT_DXT4:
1926             case WINED3DFMT_DXT5:
1927                 TRACE_(d3d_caps)("[OK]\n");
1928                 return WINED3D_OK;
1929
1930             default:
1931                 TRACE_(d3d_caps)("[FAILED] Gamma texture format %s not supported.\n", debug_d3dformat(CheckFormat));
1932                 return WINED3DERR_NOTAVAILABLE;
1933         }
1934     }
1935
1936     if (GL_SUPPORT(ARB_TEXTURE_FLOAT)) {
1937
1938         BOOL half_pixel_support = GL_SUPPORT(ARB_HALF_FLOAT_PIXEL);
1939
1940         switch (CheckFormat) {
1941             case WINED3DFMT_R16F:
1942             case WINED3DFMT_A16B16G16R16F:
1943                 if (!half_pixel_support) break;
1944             case WINED3DFMT_R32F:
1945             case WINED3DFMT_A32B32G32R32F:
1946                 TRACE_(d3d_caps)("[OK]\n");
1947                 return WINED3D_OK;
1948             default:
1949                 break; /* Avoid compiler warnings */
1950         }
1951     }
1952
1953     /* This format is nothing special and it is supported perfectly.
1954      * However, ati and nvidia driver on windows do not mark this format as
1955      * supported (tested with the dxCapsViewer) and pretending to
1956      * support this format uncovers a bug in Battlefield 1942 (fonts are missing)
1957      * So do the same as Windows drivers and pretend not to support it on dx8 and 9
1958      * Enable it on dx7. It will need additional checking on dx10 when we support it.
1959      */
1960     if(This->dxVersion > 7 && CheckFormat == WINED3DFMT_R8G8B8) {
1961         TRACE_(d3d_caps)("[FAILED]\n");
1962         return WINED3DERR_NOTAVAILABLE;
1963     }
1964
1965     switch (CheckFormat) {
1966
1967         /*****
1968          *  supported: RGB(A) formats
1969          */
1970         case WINED3DFMT_R8G8B8: /* Enable for dx7, blacklisted for 8 and 9 above */
1971         case WINED3DFMT_A8R8G8B8:
1972         case WINED3DFMT_X8R8G8B8:
1973         case WINED3DFMT_R5G6B5:
1974         case WINED3DFMT_X1R5G5B5:
1975         case WINED3DFMT_A1R5G5B5:
1976         case WINED3DFMT_A4R4G4B4:
1977         case WINED3DFMT_R3G3B2:
1978         case WINED3DFMT_A8:
1979         case WINED3DFMT_X4R4G4B4:
1980         case WINED3DFMT_A8B8G8R8:
1981         case WINED3DFMT_X8B8G8R8:
1982         case WINED3DFMT_A2R10G10B10:
1983         case WINED3DFMT_A2B10G10R10:
1984         case WINED3DFMT_G16R16:
1985             TRACE_(d3d_caps)("[OK]\n");
1986             return WINED3D_OK;
1987
1988         /*****
1989          *  supported: Palettized
1990          */
1991         case WINED3DFMT_P8:
1992             TRACE_(d3d_caps)("[OK]\n");
1993             return WINED3D_OK;
1994
1995         /*****
1996          *  Supported: (Alpha)-Luminance
1997          */
1998         case WINED3DFMT_L8:
1999         case WINED3DFMT_A8L8:
2000         case WINED3DFMT_A4L4:
2001             TRACE_(d3d_caps)("[OK]\n");
2002             return WINED3D_OK;
2003
2004         /*****
2005          *  Not supported everywhere(depends on GL_ATI_envmap_bumpmap or
2006          *  GL_NV_texture_shader), but advertized to make apps happy.
2007          *  Enable some because games often fail when they are not available
2008          *  and are still playable even without bump mapping
2009          */
2010         case WINED3DFMT_V8U8:
2011         case WINED3DFMT_V16U16:
2012         case WINED3DFMT_L6V5U5:
2013         case WINED3DFMT_X8L8V8U8:
2014         case WINED3DFMT_Q8W8V8U8:
2015             WARN_(d3d_caps)("[Not supported, but pretended to do]\n");
2016             return WINED3D_OK;
2017
2018         /* Those are not advertized by the nvidia windows driver, and not
2019          * supported natively by GL_NV_texture_shader or GL_ATI_envmap_bumpmap.
2020          * WINED3DFMT_A2W10V10U10 could be loaded into shaders using the unsigned
2021          * ARGB format if needed
2022          */
2023         case WINED3DFMT_W11V11U10:
2024         case WINED3DFMT_A2W10V10U10:
2025             WARN_(d3d_caps)("[FAILED]\n");
2026             return WINED3DERR_NOTAVAILABLE;
2027
2028         /*****
2029          *  DXTN Formats: Handled above
2030          * WINED3DFMT_DXT1
2031          * WINED3DFMT_DXT2
2032          * WINED3DFMT_DXT3
2033          * WINED3DFMT_DXT4
2034          * WINED3DFMT_DXT5
2035          */
2036
2037         /*****
2038          *  Odd formats - not supported
2039          */
2040         case WINED3DFMT_VERTEXDATA:
2041         case WINED3DFMT_INDEX16:
2042         case WINED3DFMT_INDEX32:
2043         case WINED3DFMT_Q16W16V16U16:
2044             TRACE_(d3d_caps)("[FAILED]\n"); /* Enable when implemented */
2045             return WINED3DERR_NOTAVAILABLE;
2046
2047         /*****
2048          *  Float formats: Not supported right now
2049          */
2050         case WINED3DFMT_G16R16F:
2051         case WINED3DFMT_G32R32F:
2052         case WINED3DFMT_CxV8U8:
2053             TRACE_(d3d_caps)("[FAILED]\n"); /* Enable when implemented */
2054             return WINED3DERR_NOTAVAILABLE;
2055
2056             /* Not supported */
2057         case WINED3DFMT_A16B16G16R16:
2058         case WINED3DFMT_A8R3G3B2:
2059             TRACE_(d3d_caps)("[FAILED]\n"); /* Enable when implemented */
2060             return WINED3DERR_NOTAVAILABLE;
2061
2062         /* ATI instancing hack: Although ATI cards do not support Shader Model 3.0, they support
2063          * instancing. To query if the card supports instancing CheckDeviceFormat with the special format
2064          * MAKEFOURCC('I','N','S','T') is used. Should a (broken) app check for this provide a proper return value.
2065          * We can do instancing with all shader versions, but we need vertex shaders.
2066          *
2067          * Additionally applications have to set the D3DRS_POINTSIZE render state to MAKEFOURCC('I','N','S','T') once
2068          * to enable instancing. WineD3D doesn't need that and just ignores it.
2069          *
2070          * With Shader Model 3.0 capable cards Instancing 'just works' in Windows.
2071          */
2072         case WINEMAKEFOURCC('I','N','S','T'):
2073             TRACE("ATI Instancing check hack\n");
2074             if(GL_SUPPORT(ARB_VERTEX_PROGRAM) || GL_SUPPORT(ARB_VERTEX_SHADER)) {
2075                 TRACE_(d3d_caps)("[OK]\n");
2076                 return WINED3D_OK;
2077             } else {
2078                 TRACE_(d3d_caps)("[FAILED]\n");
2079                 return WINED3DERR_NOTAVAILABLE;
2080             }
2081
2082         default:
2083             break;
2084     }
2085
2086     TRACE_(d3d_caps)("[FAILED]\n");
2087     return WINED3DERR_NOTAVAILABLE;
2088 }
2089
2090 static HRESULT  WINAPI IWineD3DImpl_CheckDeviceFormatConversion(IWineD3D *iface, UINT Adapter, WINED3DDEVTYPE DeviceType,
2091                                                           WINED3DFORMAT SourceFormat, WINED3DFORMAT TargetFormat) {
2092     IWineD3DImpl *This = (IWineD3DImpl *)iface;
2093
2094     FIXME_(d3d_caps)("(%p)-> (STUB) (Adptr:%d, DevType:(%u,%s), SrcFmt:(%u,%s), TgtFmt:(%u,%s))\n",
2095           This,
2096           Adapter,
2097           DeviceType, debug_d3ddevicetype(DeviceType),
2098           SourceFormat, debug_d3dformat(SourceFormat),
2099           TargetFormat, debug_d3dformat(TargetFormat));
2100     return WINED3D_OK;
2101 }
2102
2103 /* Note: d3d8 passes in a pointer to a D3DCAPS8 structure, which is a true
2104       subset of a D3DCAPS9 structure. However, it has to come via a void *
2105       as the d3d8 interface cannot import the d3d9 header                  */
2106 static HRESULT WINAPI IWineD3DImpl_GetDeviceCaps(IWineD3D *iface, UINT Adapter, WINED3DDEVTYPE DeviceType, WINED3DCAPS* pCaps) {
2107
2108     IWineD3DImpl    *This = (IWineD3DImpl *)iface;
2109     int vs_selected_mode;
2110     int ps_selected_mode;
2111
2112     TRACE_(d3d_caps)("(%p)->(Adptr:%d, DevType: %x, pCaps: %p)\n", This, Adapter, DeviceType, pCaps);
2113
2114     if (Adapter >= IWineD3D_GetAdapterCount(iface)) {
2115         return WINED3DERR_INVALIDCALL;
2116     }
2117
2118     select_shader_mode(&Adapters[Adapter].gl_info, DeviceType, &ps_selected_mode, &vs_selected_mode);
2119
2120     /* This function should *not* be modifying GL caps
2121      * TODO: move the functionality where it belongs */
2122     select_shader_max_constants(ps_selected_mode, vs_selected_mode, &Adapters[Adapter].gl_info);
2123
2124     /* ------------------------------------------------
2125        The following fields apply to both d3d8 and d3d9
2126        ------------------------------------------------ */
2127     *pCaps->DeviceType              = (DeviceType == WINED3DDEVTYPE_HAL) ? WINED3DDEVTYPE_HAL : WINED3DDEVTYPE_REF;  /* Not quite true, but use h/w supported by opengl I suppose */
2128     *pCaps->AdapterOrdinal          = Adapter;
2129
2130     *pCaps->Caps                    = 0;
2131     *pCaps->Caps2                   = WINED3DCAPS2_CANRENDERWINDOWED |
2132                                       WINED3DCAPS2_FULLSCREENGAMMA |
2133                                       WINED3DCAPS2_DYNAMICTEXTURES;
2134     if(GL_SUPPORT(SGIS_GENERATE_MIPMAP)) {
2135         *pCaps->Caps2 |= WINED3DCAPS2_CANAUTOGENMIPMAP;
2136     }
2137     *pCaps->Caps3                   = WINED3DCAPS3_ALPHA_FULLSCREEN_FLIP_OR_DISCARD;
2138     *pCaps->PresentationIntervals   = WINED3DPRESENT_INTERVAL_IMMEDIATE  |
2139                                       WINED3DPRESENT_INTERVAL_ONE;
2140
2141     *pCaps->CursorCaps              = WINED3DCURSORCAPS_COLOR            |
2142                                       WINED3DCURSORCAPS_LOWRES;
2143
2144     *pCaps->DevCaps                 = WINED3DDEVCAPS_FLOATTLVERTEX       |
2145                                       WINED3DDEVCAPS_EXECUTESYSTEMMEMORY |
2146                                       WINED3DDEVCAPS_TLVERTEXSYSTEMMEMORY|
2147                                       WINED3DDEVCAPS_TLVERTEXVIDEOMEMORY |
2148                                       WINED3DDEVCAPS_DRAWPRIMTLVERTEX    |
2149                                       WINED3DDEVCAPS_HWTRANSFORMANDLIGHT |
2150                                       WINED3DDEVCAPS_EXECUTEVIDEOMEMORY  |
2151                                       WINED3DDEVCAPS_PUREDEVICE          |
2152                                       WINED3DDEVCAPS_HWRASTERIZATION     |
2153                                       WINED3DDEVCAPS_TEXTUREVIDEOMEMORY  |
2154                                       WINED3DDEVCAPS_TEXTURESYSTEMMEMORY |
2155                                       WINED3DDEVCAPS_CANRENDERAFTERFLIP  |
2156                                       WINED3DDEVCAPS_DRAWPRIMITIVES2     |
2157                                       WINED3DDEVCAPS_DRAWPRIMITIVES2EX   |
2158                                       WINED3DDEVCAPS_RTPATCHES;
2159
2160     *pCaps->PrimitiveMiscCaps       = WINED3DPMISCCAPS_CULLNONE              |
2161                                       WINED3DPMISCCAPS_CULLCCW               |
2162                                       WINED3DPMISCCAPS_CULLCW                |
2163                                       WINED3DPMISCCAPS_COLORWRITEENABLE      |
2164                                       WINED3DPMISCCAPS_CLIPTLVERTS           |
2165                                       WINED3DPMISCCAPS_CLIPPLANESCALEDPOINTS |
2166                                       WINED3DPMISCCAPS_MASKZ                 |
2167                                       WINED3DPMISCCAPS_BLENDOP;
2168                                     /* TODO:
2169                                         WINED3DPMISCCAPS_NULLREFERENCE
2170                                         WINED3DPMISCCAPS_INDEPENDENTWRITEMASKS
2171                                         WINED3DPMISCCAPS_FOGANDSPECULARALPHA
2172                                         WINED3DPMISCCAPS_SEPARATEALPHABLEND
2173                                         WINED3DPMISCCAPS_MRTINDEPENDENTBITDEPTHS
2174                                         WINED3DPMISCCAPS_MRTPOSTPIXELSHADERBLENDING
2175                                         WINED3DPMISCCAPS_FOGVERTEXCLAMPED */
2176
2177 /* The caps below can be supported but aren't handled yet in utils.c 'd3dta_to_combiner_input', disable them until support is fixed */
2178 #if 0
2179     if (GL_SUPPORT(NV_REGISTER_COMBINERS))
2180         *pCaps->PrimitiveMiscCaps |=  WINED3DPMISCCAPS_TSSARGTEMP;
2181     if (GL_SUPPORT(NV_REGISTER_COMBINERS2))
2182         *pCaps->PrimitiveMiscCaps |=  WINED3DPMISCCAPS_PERSTAGECONSTANT;
2183 #endif
2184
2185     *pCaps->RasterCaps              = WINED3DPRASTERCAPS_DITHER    |
2186                                       WINED3DPRASTERCAPS_PAT       |
2187                                       WINED3DPRASTERCAPS_WFOG      |
2188                                       WINED3DPRASTERCAPS_ZFOG      |
2189                                       WINED3DPRASTERCAPS_FOGVERTEX |
2190                                       WINED3DPRASTERCAPS_FOGTABLE  |
2191                                       WINED3DPRASTERCAPS_STIPPLE   |
2192                                       WINED3DPRASTERCAPS_SUBPIXEL  |
2193                                       WINED3DPRASTERCAPS_ZTEST     |
2194                                       WINED3DPRASTERCAPS_SCISSORTEST   |
2195                                       WINED3DPRASTERCAPS_SLOPESCALEDEPTHBIAS |
2196                                       WINED3DPRASTERCAPS_DEPTHBIAS;
2197
2198     if (GL_SUPPORT(EXT_TEXTURE_FILTER_ANISOTROPIC)) {
2199       *pCaps->RasterCaps |= WINED3DPRASTERCAPS_ANISOTROPY    |
2200                             WINED3DPRASTERCAPS_ZBIAS         |
2201                             WINED3DPRASTERCAPS_MIPMAPLODBIAS;
2202     }
2203     if(GL_SUPPORT(NV_FOG_DISTANCE)) {
2204         *pCaps->RasterCaps         |= WINED3DPRASTERCAPS_FOGRANGE;
2205     }
2206                         /* FIXME Add:
2207                            WINED3DPRASTERCAPS_COLORPERSPECTIVE
2208                            WINED3DPRASTERCAPS_STRETCHBLTMULTISAMPLE
2209                            WINED3DPRASTERCAPS_ANTIALIASEDGES
2210                            WINED3DPRASTERCAPS_ZBUFFERLESSHSR
2211                            WINED3DPRASTERCAPS_WBUFFER */
2212
2213     *pCaps->ZCmpCaps = WINED3DPCMPCAPS_ALWAYS       |
2214                        WINED3DPCMPCAPS_EQUAL        |
2215                        WINED3DPCMPCAPS_GREATER      |
2216                        WINED3DPCMPCAPS_GREATEREQUAL |
2217                        WINED3DPCMPCAPS_LESS         |
2218                        WINED3DPCMPCAPS_LESSEQUAL    |
2219                        WINED3DPCMPCAPS_NEVER        |
2220                        WINED3DPCMPCAPS_NOTEQUAL;
2221
2222     *pCaps->SrcBlendCaps  = WINED3DPBLENDCAPS_BLENDFACTOR     |
2223                             WINED3DPBLENDCAPS_BOTHINVSRCALPHA |
2224                             WINED3DPBLENDCAPS_BOTHSRCALPHA    |
2225                             WINED3DPBLENDCAPS_DESTALPHA       |
2226                             WINED3DPBLENDCAPS_DESTCOLOR       |
2227                             WINED3DPBLENDCAPS_INVDESTALPHA    |
2228                             WINED3DPBLENDCAPS_INVDESTCOLOR    |
2229                             WINED3DPBLENDCAPS_INVSRCALPHA     |
2230                             WINED3DPBLENDCAPS_INVSRCCOLOR     |
2231                             WINED3DPBLENDCAPS_ONE             |
2232                             WINED3DPBLENDCAPS_SRCALPHA        |
2233                             WINED3DPBLENDCAPS_SRCALPHASAT     |
2234                             WINED3DPBLENDCAPS_SRCCOLOR        |
2235                             WINED3DPBLENDCAPS_ZERO;
2236
2237     *pCaps->DestBlendCaps = WINED3DPBLENDCAPS_BLENDFACTOR     |
2238                             WINED3DPBLENDCAPS_DESTALPHA       |
2239                             WINED3DPBLENDCAPS_DESTCOLOR       |
2240                             WINED3DPBLENDCAPS_INVDESTALPHA    |
2241                             WINED3DPBLENDCAPS_INVDESTCOLOR    |
2242                             WINED3DPBLENDCAPS_INVSRCALPHA     |
2243                             WINED3DPBLENDCAPS_INVSRCCOLOR     |
2244                             WINED3DPBLENDCAPS_ONE             |
2245                             WINED3DPBLENDCAPS_SRCALPHA        |
2246                             WINED3DPBLENDCAPS_SRCCOLOR        |
2247                             WINED3DPBLENDCAPS_ZERO;
2248     /* NOTE: WINED3DPBLENDCAPS_SRCALPHASAT is not supported as dest blend factor,
2249      * according to the glBlendFunc manpage
2250      *
2251      * WINED3DPBLENDCAPS_BOTHINVSRCALPHA and WINED3DPBLENDCAPS_BOTHSRCALPHA are
2252      * legacy settings for srcblend only
2253      */
2254
2255     *pCaps->AlphaCmpCaps = WINED3DPCMPCAPS_ALWAYS       |
2256                            WINED3DPCMPCAPS_EQUAL        |
2257                            WINED3DPCMPCAPS_GREATER      |
2258                            WINED3DPCMPCAPS_GREATEREQUAL |
2259                            WINED3DPCMPCAPS_LESS         |
2260                            WINED3DPCMPCAPS_LESSEQUAL    |
2261                            WINED3DPCMPCAPS_NEVER        |
2262                            WINED3DPCMPCAPS_NOTEQUAL;
2263
2264     *pCaps->ShadeCaps     = WINED3DPSHADECAPS_SPECULARGOURAUDRGB |
2265                             WINED3DPSHADECAPS_COLORGOURAUDRGB    |
2266                             WINED3DPSHADECAPS_ALPHAFLATBLEND     |
2267                             WINED3DPSHADECAPS_ALPHAGOURAUDBLEND  |
2268                             WINED3DPSHADECAPS_COLORFLATRGB       |
2269                             WINED3DPSHADECAPS_FOGFLAT            |
2270                             WINED3DPSHADECAPS_FOGGOURAUD         |
2271                             WINED3DPSHADECAPS_SPECULARFLATRGB;
2272
2273     *pCaps->TextureCaps =  WINED3DPTEXTURECAPS_ALPHA              |
2274                            WINED3DPTEXTURECAPS_ALPHAPALETTE       |
2275                            WINED3DPTEXTURECAPS_BORDER             |
2276                            WINED3DPTEXTURECAPS_MIPMAP             |
2277                            WINED3DPTEXTURECAPS_PROJECTED          |
2278                            WINED3DPTEXTURECAPS_PERSPECTIVE;
2279
2280     if( !GL_SUPPORT(ARB_TEXTURE_NON_POWER_OF_TWO)) {
2281         *pCaps->TextureCaps |= WINED3DPTEXTURECAPS_POW2 |
2282                                 WINED3DPTEXTURECAPS_NONPOW2CONDITIONAL;
2283     }
2284
2285     if( GL_SUPPORT(EXT_TEXTURE3D)) {
2286         *pCaps->TextureCaps |=  WINED3DPTEXTURECAPS_VOLUMEMAP      |
2287                                 WINED3DPTEXTURECAPS_MIPVOLUMEMAP   |
2288                                 WINED3DPTEXTURECAPS_VOLUMEMAP_POW2;
2289     }
2290
2291     if (GL_SUPPORT(ARB_TEXTURE_CUBE_MAP)) {
2292         *pCaps->TextureCaps |= WINED3DPTEXTURECAPS_CUBEMAP     |
2293                              WINED3DPTEXTURECAPS_MIPCUBEMAP    |
2294                              WINED3DPTEXTURECAPS_CUBEMAP_POW2;
2295
2296     }
2297
2298     *pCaps->TextureFilterCaps = WINED3DPTFILTERCAPS_MAGFLINEAR       |
2299                                 WINED3DPTFILTERCAPS_MAGFPOINT        |
2300                                 WINED3DPTFILTERCAPS_MINFLINEAR       |
2301                                 WINED3DPTFILTERCAPS_MINFPOINT        |
2302                                 WINED3DPTFILTERCAPS_MIPFLINEAR       |
2303                                 WINED3DPTFILTERCAPS_MIPFPOINT        |
2304                                 WINED3DPTFILTERCAPS_LINEAR           |
2305                                 WINED3DPTFILTERCAPS_LINEARMIPLINEAR  |
2306                                 WINED3DPTFILTERCAPS_LINEARMIPNEAREST |
2307                                 WINED3DPTFILTERCAPS_MIPLINEAR        |
2308                                 WINED3DPTFILTERCAPS_MIPNEAREST       |
2309                                 WINED3DPTFILTERCAPS_NEAREST;
2310
2311     if (GL_SUPPORT(EXT_TEXTURE_FILTER_ANISOTROPIC)) {
2312         *pCaps->TextureFilterCaps |= WINED3DPTFILTERCAPS_MAGFANISOTROPIC |
2313                                      WINED3DPTFILTERCAPS_MINFANISOTROPIC;
2314     }
2315
2316     if (GL_SUPPORT(ARB_TEXTURE_CUBE_MAP)) {
2317         *pCaps->CubeTextureFilterCaps = WINED3DPTFILTERCAPS_MAGFLINEAR       |
2318                                         WINED3DPTFILTERCAPS_MAGFPOINT        |
2319                                         WINED3DPTFILTERCAPS_MINFLINEAR       |
2320                                         WINED3DPTFILTERCAPS_MINFPOINT        |
2321                                         WINED3DPTFILTERCAPS_MIPFLINEAR       |
2322                                         WINED3DPTFILTERCAPS_MIPFPOINT        |
2323                                         WINED3DPTFILTERCAPS_LINEAR           |
2324                                         WINED3DPTFILTERCAPS_LINEARMIPLINEAR  |
2325                                         WINED3DPTFILTERCAPS_LINEARMIPNEAREST |
2326                                         WINED3DPTFILTERCAPS_MIPLINEAR        |
2327                                         WINED3DPTFILTERCAPS_MIPNEAREST       |
2328                                         WINED3DPTFILTERCAPS_NEAREST;
2329
2330         if (GL_SUPPORT(EXT_TEXTURE_FILTER_ANISOTROPIC)) {
2331             *pCaps->CubeTextureFilterCaps |= WINED3DPTFILTERCAPS_MAGFANISOTROPIC |
2332                                             WINED3DPTFILTERCAPS_MINFANISOTROPIC;
2333         }
2334     } else
2335         *pCaps->CubeTextureFilterCaps = 0;
2336
2337     if (GL_SUPPORT(EXT_TEXTURE3D)) {
2338         *pCaps->VolumeTextureFilterCaps = WINED3DPTFILTERCAPS_MAGFLINEAR       |
2339                                           WINED3DPTFILTERCAPS_MAGFPOINT        |
2340                                           WINED3DPTFILTERCAPS_MINFLINEAR       |
2341                                           WINED3DPTFILTERCAPS_MINFPOINT        |
2342                                           WINED3DPTFILTERCAPS_MIPFLINEAR       |
2343                                           WINED3DPTFILTERCAPS_MIPFPOINT        |
2344                                           WINED3DPTFILTERCAPS_LINEAR           |
2345                                           WINED3DPTFILTERCAPS_LINEARMIPLINEAR  |
2346                                           WINED3DPTFILTERCAPS_LINEARMIPNEAREST |
2347                                           WINED3DPTFILTERCAPS_MIPLINEAR        |
2348                                           WINED3DPTFILTERCAPS_MIPNEAREST       |
2349                                           WINED3DPTFILTERCAPS_NEAREST;
2350     } else
2351         *pCaps->VolumeTextureFilterCaps = 0;
2352
2353     *pCaps->TextureAddressCaps =  WINED3DPTADDRESSCAPS_INDEPENDENTUV |
2354                                   WINED3DPTADDRESSCAPS_CLAMP  |
2355                                   WINED3DPTADDRESSCAPS_WRAP;
2356
2357     if (GL_SUPPORT(ARB_TEXTURE_BORDER_CLAMP)) {
2358         *pCaps->TextureAddressCaps |= WINED3DPTADDRESSCAPS_BORDER;
2359     }
2360     if (GL_SUPPORT(ARB_TEXTURE_MIRRORED_REPEAT)) {
2361         *pCaps->TextureAddressCaps |= WINED3DPTADDRESSCAPS_MIRROR;
2362     }
2363     if (GL_SUPPORT(ATI_TEXTURE_MIRROR_ONCE)) {
2364         *pCaps->TextureAddressCaps |= WINED3DPTADDRESSCAPS_MIRRORONCE;
2365     }
2366
2367     if (GL_SUPPORT(EXT_TEXTURE3D)) {
2368         *pCaps->VolumeTextureAddressCaps =  WINED3DPTADDRESSCAPS_INDEPENDENTUV |
2369                                             WINED3DPTADDRESSCAPS_CLAMP  |
2370                                             WINED3DPTADDRESSCAPS_WRAP;
2371         if (GL_SUPPORT(ARB_TEXTURE_BORDER_CLAMP)) {
2372             *pCaps->VolumeTextureAddressCaps |= WINED3DPTADDRESSCAPS_BORDER;
2373         }
2374         if (GL_SUPPORT(ARB_TEXTURE_MIRRORED_REPEAT)) {
2375             *pCaps->VolumeTextureAddressCaps |= WINED3DPTADDRESSCAPS_MIRROR;
2376         }
2377         if (GL_SUPPORT(ATI_TEXTURE_MIRROR_ONCE)) {
2378             *pCaps->VolumeTextureAddressCaps |= WINED3DPTADDRESSCAPS_MIRRORONCE;
2379         }
2380     } else
2381         *pCaps->VolumeTextureAddressCaps = 0;
2382
2383     *pCaps->LineCaps = WINED3DLINECAPS_TEXTURE |
2384                        WINED3DLINECAPS_ZTEST;
2385                       /* FIXME: Add
2386                         WINED3DLINECAPS_BLEND
2387                         WINED3DLINECAPS_ALPHACMP
2388                         WINED3DLINECAPS_FOG */
2389
2390     *pCaps->MaxTextureWidth  = GL_LIMITS(texture_size);
2391     *pCaps->MaxTextureHeight = GL_LIMITS(texture_size);
2392
2393     if(GL_SUPPORT(EXT_TEXTURE3D))
2394         *pCaps->MaxVolumeExtent = GL_LIMITS(texture3d_size);
2395     else
2396         *pCaps->MaxVolumeExtent = 0;
2397
2398     *pCaps->MaxTextureRepeat = 32768;
2399     *pCaps->MaxTextureAspectRatio = GL_LIMITS(texture_size);
2400     *pCaps->MaxVertexW = 1.0;
2401
2402     *pCaps->GuardBandLeft = 0;
2403     *pCaps->GuardBandTop = 0;
2404     *pCaps->GuardBandRight = 0;
2405     *pCaps->GuardBandBottom = 0;
2406
2407     *pCaps->ExtentsAdjust = 0;
2408
2409     *pCaps->StencilCaps =  WINED3DSTENCILCAPS_DECRSAT |
2410                            WINED3DSTENCILCAPS_INCRSAT |
2411                            WINED3DSTENCILCAPS_INVERT  |
2412                            WINED3DSTENCILCAPS_KEEP    |
2413                            WINED3DSTENCILCAPS_REPLACE |
2414                            WINED3DSTENCILCAPS_ZERO;
2415     if (GL_SUPPORT(EXT_STENCIL_WRAP)) {
2416       *pCaps->StencilCaps |= WINED3DSTENCILCAPS_DECR  |
2417                              WINED3DSTENCILCAPS_INCR;
2418     }
2419     if ( This->dxVersion > 8 &&
2420         ( GL_SUPPORT(EXT_STENCIL_TWO_SIDE) ||
2421             GL_SUPPORT(ATI_SEPARATE_STENCIL) ) ) {
2422         *pCaps->StencilCaps |= WINED3DSTENCILCAPS_TWOSIDED;
2423     }
2424
2425     *pCaps->FVFCaps = WINED3DFVFCAPS_PSIZE | 0x0008; /* 8 texture coords */
2426
2427     *pCaps->TextureOpCaps =  WINED3DTEXOPCAPS_ADD         |
2428                              WINED3DTEXOPCAPS_ADDSIGNED   |
2429                              WINED3DTEXOPCAPS_ADDSIGNED2X |
2430                              WINED3DTEXOPCAPS_MODULATE    |
2431                              WINED3DTEXOPCAPS_MODULATE2X  |
2432                              WINED3DTEXOPCAPS_MODULATE4X  |
2433                              WINED3DTEXOPCAPS_SELECTARG1  |
2434                              WINED3DTEXOPCAPS_SELECTARG2  |
2435                              WINED3DTEXOPCAPS_DISABLE;
2436
2437     if (GL_SUPPORT(ARB_TEXTURE_ENV_COMBINE) ||
2438         GL_SUPPORT(EXT_TEXTURE_ENV_COMBINE) ||
2439         GL_SUPPORT(NV_TEXTURE_ENV_COMBINE4)) {
2440         *pCaps->TextureOpCaps |= WINED3DTEXOPCAPS_BLENDDIFFUSEALPHA |
2441                                 WINED3DTEXOPCAPS_BLENDTEXTUREALPHA  |
2442                                 WINED3DTEXOPCAPS_BLENDFACTORALPHA   |
2443                                 WINED3DTEXOPCAPS_BLENDCURRENTALPHA  |
2444                                 WINED3DTEXOPCAPS_LERP               |
2445                                 WINED3DTEXOPCAPS_SUBTRACT;
2446     }
2447     if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3) ||
2448          GL_SUPPORT(NV_TEXTURE_ENV_COMBINE4)) {
2449         *pCaps->TextureOpCaps |= WINED3DTEXOPCAPS_ADDSMOOTH             |
2450                                 WINED3DTEXOPCAPS_MULTIPLYADD            |
2451                                 WINED3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR |
2452                                 WINED3DTEXOPCAPS_MODULATECOLOR_ADDALPHA |
2453                                 WINED3DTEXOPCAPS_BLENDTEXTUREALPHAPM;
2454     }
2455     if (GL_SUPPORT(ARB_TEXTURE_ENV_DOT3))
2456         *pCaps->TextureOpCaps |= WINED3DTEXOPCAPS_DOTPRODUCT3;
2457
2458     if (GL_SUPPORT(NV_REGISTER_COMBINERS)) {
2459         *pCaps->TextureOpCaps |= WINED3DTEXOPCAPS_MODULATEINVALPHA_ADDCOLOR |
2460                                  WINED3DTEXOPCAPS_MODULATEINVCOLOR_ADDALPHA;
2461     }
2462
2463     if(GL_SUPPORT(ATI_ENVMAP_BUMPMAP)) {
2464         *pCaps->TextureOpCaps |= WINED3DTEXOPCAPS_BUMPENVMAP;
2465     } else if(GL_SUPPORT(NV_TEXTURE_SHADER2)) {
2466         /* Bump mapping is supported already in NV_TEXTURE_SHADER, but that extension does
2467          * not support 3D textures. This asks for trouble if an app uses both bump mapping
2468          * and 3D textures. It also allows us to keep the code simpler by having texture
2469          * shaders constantly enabled.
2470          */
2471         *pCaps->TextureOpCaps |= WINED3DTEXOPCAPS_BUMPENVMAP;
2472         /* TODO: Luminance bump map? */
2473     }
2474 #if 0
2475     /* FIXME: Add
2476     *pCaps->TextureOpCaps |= WINED3DTEXOPCAPS_BUMPENVMAPLUMINANCE
2477                              WINED3DTEXOPCAPS_PREMODULATE */
2478 #endif
2479
2480     *pCaps->MaxTextureBlendStages   = GL_LIMITS(texture_stages);
2481     *pCaps->MaxSimultaneousTextures = GL_LIMITS(textures);
2482     *pCaps->MaxUserClipPlanes       = GL_LIMITS(clipplanes);
2483     *pCaps->MaxActiveLights         = GL_LIMITS(lights);
2484
2485     *pCaps->MaxVertexBlendMatrices      = GL_LIMITS(blends);
2486     *pCaps->MaxVertexBlendMatrixIndex   = 0;
2487
2488     *pCaps->MaxAnisotropy   = GL_LIMITS(anisotropy);
2489     *pCaps->MaxPointSize    = GL_LIMITS(pointsize);
2490
2491
2492     *pCaps->VertexProcessingCaps = WINED3DVTXPCAPS_DIRECTIONALLIGHTS |
2493                                    WINED3DVTXPCAPS_MATERIALSOURCE7   |
2494                                    WINED3DVTXPCAPS_POSITIONALLIGHTS  |
2495                                    WINED3DVTXPCAPS_LOCALVIEWER       |
2496                                    WINED3DVTXPCAPS_VERTEXFOG         |
2497                                    WINED3DVTXPCAPS_TEXGEN;
2498                                   /* FIXME: Add 
2499                                      D3DVTXPCAPS_TWEENING, D3DVTXPCAPS_TEXGEN_SPHEREMAP */
2500
2501     *pCaps->MaxPrimitiveCount   = 0xFFFFF; /* For now set 2^20-1 which is used by most >=Geforce3/Radeon8500 cards */
2502     *pCaps->MaxVertexIndex      = 0xFFFFF;
2503     *pCaps->MaxStreams          = MAX_STREAMS;
2504     *pCaps->MaxStreamStride     = 1024;
2505
2506     if (vs_selected_mode == SHADER_GLSL) {
2507         /* Nvidia Geforce6/7 or Ati R4xx/R5xx cards with GLSL support, support VS 3.0 but older Nvidia/Ati
2508          * models with GLSL support only support 2.0. In case of nvidia we can detect VS 2.0 support using
2509          * vs_nv_version which is based on NV_vertex_program.
2510          * For Ati cards there's no way using glsl (it abstracts the lowlevel info away) and also not
2511          * using ARB_vertex_program. It is safe to assume that when a card supports pixel shader 2.0 it
2512          * supports vertex shader 2.0 too and the way around. We can detect ps2.0 using the maximum number
2513          * of native instructions, so use that here. For more info see the pixel shader versioning code below. */
2514         if((GLINFO_LOCATION.vs_nv_version == VS_VERSION_20) || (GLINFO_LOCATION.ps_arb_max_instructions <= 512))
2515             *pCaps->VertexShaderVersion = WINED3DVS_VERSION(2,0);
2516         else
2517             *pCaps->VertexShaderVersion = WINED3DVS_VERSION(3,0);
2518         TRACE_(d3d_caps)("Hardware vertex shader version %d.%d enabled (GLSL)\n", (*pCaps->VertexShaderVersion >> 8) & 0xff, *pCaps->VertexShaderVersion & 0xff);
2519     } else if (vs_selected_mode == SHADER_ARB) {
2520         *pCaps->VertexShaderVersion = WINED3DVS_VERSION(1,1);
2521         TRACE_(d3d_caps)("Hardware vertex shader version 1.1 enabled (ARB_PROGRAM)\n");
2522     } else {
2523         *pCaps->VertexShaderVersion  = 0;
2524         TRACE_(d3d_caps)("Vertex shader functionality not available\n");
2525     }
2526
2527     *pCaps->MaxVertexShaderConst = GL_LIMITS(vshader_constantsF);
2528
2529     if (ps_selected_mode == SHADER_GLSL) {
2530         /* Older DX9-class videocards (GeforceFX / Radeon >9500/X*00) only support pixel shader 2.0/2.0a/2.0b.
2531          * In OpenGL the extensions related to GLSL abstract lowlevel GL info away which is needed
2532          * to distinguish between 2.0 and 3.0 (and 2.0a/2.0b). In case of Nvidia we use their fragment
2533          * program extensions. On other hardware including ATI GL_ARB_fragment_program offers the info
2534          * in max native instructions. Intel and others also offer the info in this extension but they
2535          * don't support GLSL (at least on Windows).
2536          *
2537          * PS2.0 requires at least 96 instructions, 2.0a/2.0b go up to 512. Assume that if the number
2538          * of instructions is 512 or less we have to do with ps2.0 hardware.
2539          * NOTE: ps3.0 hardware requires 512 or more instructions but ati and nvidia offer 'enough' (1024 vs 4096) on their most basic ps3.0 hardware.
2540          */
2541         if((GLINFO_LOCATION.ps_nv_version == PS_VERSION_20) || (GLINFO_LOCATION.ps_arb_max_instructions <= 512))
2542             *pCaps->PixelShaderVersion = WINED3DPS_VERSION(2,0);
2543         else
2544             *pCaps->PixelShaderVersion = WINED3DPS_VERSION(3,0);
2545         /* FIXME: The following line is card dependent. -8.0 to 8.0 is the
2546          * Direct3D minimum requirement.
2547          *
2548          * Both GL_ARB_fragment_program and GLSL require a "maximum representable magnitude"
2549          * of colors to be 2^10, and 2^32 for other floats. Should we use 1024 here?
2550          *
2551          * The problem is that the refrast clamps temporary results in the shader to
2552          * [-MaxValue;+MaxValue]. If the card's max value is bigger than the one we advertize here,
2553          * then applications may miss the clamping behavior. On the other hand, if it is smaller,
2554          * the shader will generate incorrect results too. Unfortunately, GL deliberately doesn't
2555          * offer a way to query this.
2556          */
2557         *pCaps->PixelShader1xMaxValue = 8.0;
2558         TRACE_(d3d_caps)("Hardware pixel shader version %d.%d enabled (GLSL)\n", (*pCaps->PixelShaderVersion >> 8) & 0xff, *pCaps->PixelShaderVersion & 0xff);
2559     } else if (ps_selected_mode == SHADER_ARB) {
2560         *pCaps->PixelShaderVersion    = WINED3DPS_VERSION(1,4);
2561         *pCaps->PixelShader1xMaxValue = 8.0;
2562         TRACE_(d3d_caps)("Hardware pixel shader version 1.4 enabled (ARB_PROGRAM)\n");
2563     } else {
2564         *pCaps->PixelShaderVersion    = 0;
2565         *pCaps->PixelShader1xMaxValue = 0.0;
2566         TRACE_(d3d_caps)("Pixel shader functionality not available\n");
2567     }
2568
2569     /* ------------------------------------------------
2570        The following fields apply to d3d9 only
2571        ------------------------------------------------ */
2572     if (This->dxVersion > 8) {
2573         /* d3d9.dll sets D3DDEVCAPS2_CAN_STRETCHRECT_FROM_TEXTURES here because StretchRects is implemented in d3d9 */
2574         *pCaps->DevCaps2                          = WINED3DDEVCAPS2_STREAMOFFSET;
2575         /* TODO: VS3.0 needs at least D3DDEVCAPS2_VERTEXELEMENTSCANSHARESTREAMOFFSET */
2576         *pCaps->MaxNpatchTessellationLevel        = 0;
2577         *pCaps->MasterAdapterOrdinal              = 0;
2578         *pCaps->AdapterOrdinalInGroup             = 0;
2579         *pCaps->NumberOfAdaptersInGroup           = 1;
2580
2581         if(*pCaps->VertexShaderVersion >= WINED3DVS_VERSION(2,0)) {
2582             /* OpenGL supports all the formats below, perhaps not always
2583              * without conversion, but it supports them.
2584              * Further GLSL doesn't seem to have an official unsigned type so
2585              * don't advertise it yet as I'm not sure how we handle it.
2586              * We might need to add some clamping in the shader engine to
2587              * support it.
2588              * TODO: WINED3DDTCAPS_USHORT2N, WINED3DDTCAPS_USHORT4N, WINED3DDTCAPS_UDEC3, WINED3DDTCAPS_DEC3N */
2589             *pCaps->DeclTypes = WINED3DDTCAPS_UBYTE4    |
2590                                 WINED3DDTCAPS_UBYTE4N   |
2591                                 WINED3DDTCAPS_SHORT2N   |
2592                                 WINED3DDTCAPS_SHORT4N;
2593             if (GL_SUPPORT(NV_HALF_FLOAT)) {
2594                 *pCaps->DeclTypes |=
2595                                 WINED3DDTCAPS_FLOAT16_2 |
2596                                 WINED3DDTCAPS_FLOAT16_4;
2597             }
2598         } else
2599             *pCaps->DeclTypes                         = 0;
2600
2601         *pCaps->NumSimultaneousRTs = GL_LIMITS(buffers);
2602
2603             
2604         *pCaps->StretchRectFilterCaps             = WINED3DPTFILTERCAPS_MINFPOINT  |
2605                                                     WINED3DPTFILTERCAPS_MAGFPOINT  |
2606                                                     WINED3DPTFILTERCAPS_MINFLINEAR |
2607                                                     WINED3DPTFILTERCAPS_MAGFLINEAR;
2608         *pCaps->VertexTextureFilterCaps           = 0;
2609         
2610         if(*pCaps->VertexShaderVersion == WINED3DVS_VERSION(3,0)) {
2611             /* Where possible set the caps based on OpenGL extensions and if they aren't set (in case of software rendering)
2612                use the VS 3.0 from MSDN or else if there's OpenGL spec use a hardcoded value minimum VS3.0 value. */
2613             *pCaps->VS20Caps.Caps                     = WINED3DVS20CAPS_PREDICATION;
2614             *pCaps->VS20Caps.DynamicFlowControlDepth  = WINED3DVS20_MAX_DYNAMICFLOWCONTROLDEPTH; /* VS 3.0 requires MAX_DYNAMICFLOWCONTROLDEPTH (24) */
2615             *pCaps->VS20Caps.NumTemps                 = max(32, GLINFO_LOCATION.vs_arb_max_temps);
2616             *pCaps->VS20Caps.StaticFlowControlDepth   = WINED3DVS20_MAX_STATICFLOWCONTROLDEPTH ; /* level of nesting in loops / if-statements; VS 3.0 requires MAX (4) */
2617
2618             *pCaps->MaxVShaderInstructionsExecuted    = 65535; /* VS 3.0 needs at least 65535, some cards even use 2^32-1 */
2619             *pCaps->MaxVertexShader30InstructionSlots = max(512, GLINFO_LOCATION.vs_arb_max_instructions);
2620         } else if(*pCaps->VertexShaderVersion == WINED3DVS_VERSION(2,0)) {
2621             *pCaps->VS20Caps.Caps                     = 0;
2622             *pCaps->VS20Caps.DynamicFlowControlDepth  = WINED3DVS20_MIN_DYNAMICFLOWCONTROLDEPTH;
2623             *pCaps->VS20Caps.NumTemps                 = max(12, GLINFO_LOCATION.vs_arb_max_temps);
2624             *pCaps->VS20Caps.StaticFlowControlDepth   = 1;    
2625
2626             *pCaps->MaxVShaderInstructionsExecuted    = 65535;
2627             *pCaps->MaxVertexShader30InstructionSlots = 0;
2628         } else { /* VS 1.x */
2629             *pCaps->VS20Caps.Caps                     = 0;
2630             *pCaps->VS20Caps.DynamicFlowControlDepth  = 0;
2631             *pCaps->VS20Caps.NumTemps                 = 0;
2632             *pCaps->VS20Caps.StaticFlowControlDepth   = 0;    
2633
2634             *pCaps->MaxVShaderInstructionsExecuted    = 0;
2635             *pCaps->MaxVertexShader30InstructionSlots = 0;        
2636         }
2637
2638         if(*pCaps->PixelShaderVersion == WINED3DPS_VERSION(3,0)) {
2639             /* Where possible set the caps based on OpenGL extensions and if they aren't set (in case of software rendering)
2640                use the PS 3.0 from MSDN or else if there's OpenGL spec use a hardcoded value minimum PS 3.0 value. */
2641             
2642             /* 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 */
2643             *pCaps->PS20Caps.Caps                     = WINED3DPS20CAPS_ARBITRARYSWIZZLE     |
2644                                                         WINED3DPS20CAPS_GRADIENTINSTRUCTIONS |
2645                                                         WINED3DPS20CAPS_PREDICATION          |
2646                                                         WINED3DPS20CAPS_NODEPENDENTREADLIMIT |
2647                                                         WINED3DPS20CAPS_NOTEXINSTRUCTIONLIMIT;
2648             *pCaps->PS20Caps.DynamicFlowControlDepth  = WINED3DPS20_MAX_DYNAMICFLOWCONTROLDEPTH; /* PS 3.0 requires MAX_DYNAMICFLOWCONTROLDEPTH (24) */
2649             *pCaps->PS20Caps.NumTemps                 = max(32, GLINFO_LOCATION.ps_arb_max_temps);
2650             *pCaps->PS20Caps.StaticFlowControlDepth   = WINED3DPS20_MAX_STATICFLOWCONTROLDEPTH; /* PS 3.0 requires MAX_STATICFLOWCONTROLDEPTH (4) */
2651             *pCaps->PS20Caps.NumInstructionSlots      = WINED3DPS20_MAX_NUMINSTRUCTIONSLOTS; /* PS 3.0 requires MAX_NUMINSTRUCTIONSLOTS (512) */
2652
2653             *pCaps->MaxPShaderInstructionsExecuted    = 65535;
2654             *pCaps->MaxPixelShader30InstructionSlots  = max(WINED3DMIN30SHADERINSTRUCTIONS, GLINFO_LOCATION.ps_arb_max_instructions);
2655         } else if(*pCaps->PixelShaderVersion == WINED3DPS_VERSION(2,0)) {
2656             /* Below we assume PS2.0 specs, not extended 2.0a(GeforceFX)/2.0b(Radeon R3xx) ones */
2657             *pCaps->PS20Caps.Caps                     = 0;
2658             *pCaps->PS20Caps.DynamicFlowControlDepth  = 0; /* WINED3DVS20_MIN_DYNAMICFLOWCONTROLDEPTH = 0 */
2659             *pCaps->PS20Caps.NumTemps                 = max(12, GLINFO_LOCATION.ps_arb_max_temps);
2660             *pCaps->PS20Caps.StaticFlowControlDepth   = WINED3DPS20_MIN_STATICFLOWCONTROLDEPTH; /* Minumum: 1 */
2661             *pCaps->PS20Caps.NumInstructionSlots      = WINED3DPS20_MIN_NUMINSTRUCTIONSLOTS; /* Minimum number (64 ALU + 32 Texture), a GeforceFX uses 512 */
2662
2663             *pCaps->MaxPShaderInstructionsExecuted    = 512; /* Minimum value, a GeforceFX uses 1024 */
2664             *pCaps->MaxPixelShader30InstructionSlots  = 0;
2665         } else { /* PS 1.x */
2666             *pCaps->PS20Caps.Caps                     = 0;
2667             *pCaps->PS20Caps.DynamicFlowControlDepth  = 0;
2668             *pCaps->PS20Caps.NumTemps                 = 0;
2669             *pCaps->PS20Caps.StaticFlowControlDepth   = 0;
2670             *pCaps->PS20Caps.NumInstructionSlots      = 0;
2671
2672             *pCaps->MaxPShaderInstructionsExecuted    = 0;
2673             *pCaps->MaxPixelShader30InstructionSlots  = 0;
2674         }
2675     }
2676
2677     return WINED3D_OK;
2678 }
2679
2680 static unsigned int glsl_program_key_hash(void *key) {
2681     glsl_program_key_t *k = (glsl_program_key_t *)key;
2682
2683     unsigned int hash = k->vshader | k->pshader << 16;
2684     hash += ~(hash << 15);
2685     hash ^=  (hash >> 10);
2686     hash +=  (hash << 3);
2687     hash ^=  (hash >> 6);
2688     hash += ~(hash << 11);
2689     hash ^=  (hash >> 16);
2690
2691     return hash;
2692 }
2693
2694 static BOOL glsl_program_key_compare(void *keya, void *keyb) {
2695     glsl_program_key_t *ka = (glsl_program_key_t *)keya;
2696     glsl_program_key_t *kb = (glsl_program_key_t *)keyb;
2697
2698     return ka->vshader == kb->vshader && ka->pshader == kb->pshader;
2699 }
2700
2701 /* Note due to structure differences between dx8 and dx9 D3DPRESENT_PARAMETERS,
2702    and fields being inserted in the middle, a new structure is used in place    */
2703 static HRESULT  WINAPI IWineD3DImpl_CreateDevice(IWineD3D *iface, UINT Adapter, WINED3DDEVTYPE DeviceType, HWND hFocusWindow,
2704                                            DWORD BehaviourFlags, IWineD3DDevice** ppReturnedDeviceInterface,
2705                                            IUnknown *parent) {
2706
2707     IWineD3DDeviceImpl *object  = NULL;
2708     IWineD3DImpl       *This    = (IWineD3DImpl *)iface;
2709     WINED3DDISPLAYMODE  mode;
2710     int i;
2711
2712     /* Validate the adapter number. If no adapters are available(no GL), ignore the adapter
2713      * number and create a device without a 3D adapter for 2D only operation.
2714      */
2715     if (IWineD3D_GetAdapterCount(iface) && Adapter >= IWineD3D_GetAdapterCount(iface)) {
2716         return WINED3DERR_INVALIDCALL;
2717     }
2718
2719     /* Create a WineD3DDevice object */
2720     object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IWineD3DDeviceImpl));
2721     *ppReturnedDeviceInterface = (IWineD3DDevice *)object;
2722     TRACE("Created WineD3DDevice object @ %p\n", object);
2723     if (NULL == object) {
2724       return WINED3DERR_OUTOFVIDEOMEMORY;
2725     }
2726
2727     /* Set up initial COM information */
2728     object->lpVtbl  = &IWineD3DDevice_Vtbl;
2729     object->ref     = 1;
2730     object->wineD3D = iface;
2731     object->adapter = numAdapters ? &Adapters[Adapter] : NULL;
2732     IWineD3D_AddRef(object->wineD3D);
2733     object->parent  = parent;
2734     list_init(&object->resources);
2735
2736     if(This->dxVersion == 7) {
2737         object->surface_alignment = 8;
2738     } else {
2739         object->surface_alignment = 4;
2740     }
2741     object->posFixup[0] = 1.0; /* This is needed to get the x coord unmodified through a MAD */
2742
2743     /* Set the state up as invalid until the device is fully created */
2744     object->state   = WINED3DERR_DRIVERINTERNALERROR;
2745
2746     TRACE("(%p)->(Adptr:%d, DevType: %x, FocusHwnd: %p, BehFlags: %x, RetDevInt: %p)\n", This, Adapter, DeviceType,
2747           hFocusWindow, BehaviourFlags, ppReturnedDeviceInterface);
2748
2749     /* Save the creation parameters */
2750     object->createParms.AdapterOrdinal = Adapter;
2751     object->createParms.DeviceType     = DeviceType;
2752     object->createParms.hFocusWindow   = hFocusWindow;
2753     object->createParms.BehaviorFlags  = BehaviourFlags;
2754
2755     /* Initialize other useful values */
2756     object->adapterNo                    = Adapter;
2757     object->devType                      = DeviceType;
2758
2759     select_shader_mode(&GLINFO_LOCATION, DeviceType, &object->ps_selected_mode, &object->vs_selected_mode);
2760     if (object->ps_selected_mode == SHADER_GLSL || object->vs_selected_mode == SHADER_GLSL) {
2761         object->shader_backend = &glsl_shader_backend;
2762         object->glsl_program_lookup = hash_table_create(&glsl_program_key_hash, &glsl_program_key_compare);
2763     } else if (object->ps_selected_mode == SHADER_ARB || object->vs_selected_mode == SHADER_ARB) {
2764         object->shader_backend = &arb_program_shader_backend;
2765     } else {
2766         object->shader_backend = &none_shader_backend;
2767     }
2768
2769     /* set the state of the device to valid */
2770     object->state = WINED3D_OK;
2771
2772     /* Get the initial screen setup for ddraw */
2773     IWineD3DImpl_GetAdapterDisplayMode(iface, Adapter, &mode);
2774
2775     object->ddraw_width = mode.Width;
2776     object->ddraw_height = mode.Height;
2777     object->ddraw_format = mode.Format;
2778
2779     for(i = 0; i < PATCHMAP_SIZE; i++) {
2780         list_init(&object->patches[i]);
2781     }
2782     return WINED3D_OK;
2783 }
2784 #undef GLINFO_LOCATION
2785
2786 static HRESULT WINAPI IWineD3DImpl_GetParent(IWineD3D *iface, IUnknown **pParent) {
2787     IWineD3DImpl *This = (IWineD3DImpl *)iface;
2788     IUnknown_AddRef(This->parent);
2789     *pParent = This->parent;
2790     return WINED3D_OK;
2791 }
2792
2793 ULONG WINAPI D3DCB_DefaultDestroySurface(IWineD3DSurface *pSurface) {
2794     IUnknown* surfaceParent;
2795     TRACE("(%p) call back\n", pSurface);
2796
2797     /* Now, release the parent, which will take care of cleaning up the surface for us */
2798     IWineD3DSurface_GetParent(pSurface, &surfaceParent);
2799     IUnknown_Release(surfaceParent);
2800     return IUnknown_Release(surfaceParent);
2801 }
2802
2803 ULONG WINAPI D3DCB_DefaultDestroyVolume(IWineD3DVolume *pVolume) {
2804     IUnknown* volumeParent;
2805     TRACE("(%p) call back\n", pVolume);
2806
2807     /* Now, release the parent, which will take care of cleaning up the volume for us */
2808     IWineD3DVolume_GetParent(pVolume, &volumeParent);
2809     IUnknown_Release(volumeParent);
2810     return IUnknown_Release(volumeParent);
2811 }
2812
2813 static BOOL implementation_is_apple(WineD3D_GL_Info *gl_info) {
2814     /* MacOS has various specialities in the extensions it advertises. Some have to be loaded from
2815      * the opengl 1.2+ core, while other extensions are advertised, but software emulated. So try to
2816      * detect the Apple OpenGL implementation to apply some extension fixups afterwards.
2817      *
2818      * Detecting this isn't really easy. The vendor string doesn't mention Apple. Compile-time checks
2819      * aren't sufficient either because a Linux binary may display on a macos X server via remote X11.
2820      * So try to detect the GL implementation by looking at certain Apple extensions. Some extensions
2821      * like client storage might be supported on other implementations too, but GL_APPLE_flush_render
2822      * is specific to the Mac OS X window management, and GL_APPLE_ycbcr_422 is QuickTime specific. So
2823      * the chance that other implementations support them is rather small since Win32 QuickTime uses
2824      * DirectDraw, not OpenGL.
2825      */
2826     if(gl_info->supported[APPLE_FENCE] &&
2827        gl_info->supported[APPLE_CLIENT_STORAGE] &&
2828        gl_info->supported[APPLE_FLUSH_RENDER] &&
2829        gl_info->supported[APPLE_YCBCR_422]) {
2830         TRACE_(d3d_caps)("GL_APPLE_fence, GL_APPLE_client_storage, GL_APPLE_flush_render and GL_ycbcr_422 are supported\n");
2831         TRACE_(d3d_caps)("Activating MacOS fixups\n");
2832         return TRUE;
2833     } else {
2834         TRACE_(d3d_caps)("Apple extensions are not supported\n");
2835         TRACE_(d3d_caps)("Not activating MacOS fixups\n");
2836         return FALSE;
2837     }
2838 }
2839
2840 static void fixup_extensions(WineD3D_GL_Info *gl_info) {
2841     if(implementation_is_apple(gl_info)) {
2842         /* MacOS advertises more GLSL vertex shader uniforms than supported by the hardware, and if more are
2843          * used it falls back to software. While the compiler can detect if the shader uses all declared
2844          * uniforms, the optimization fails if the shader uses relative addressing. So any GLSL shader
2845          * using relative addressing falls back to software.
2846          *
2847          * ARB vp gives the correct amount of uniforms, so use it instead of GLSL
2848          */
2849         if(gl_info->vs_glsl_constantsF <= gl_info->vs_arb_constantsF) {
2850             FIXME("GLSL doesn't advertise more vertex shader uniforms than ARB. Driver fixup outdated?\n");
2851         } else {
2852             TRACE("Driver claims %u GLSL vs uniforms, replacing with %u ARB vp uniforms\n",
2853                   gl_info->vs_glsl_constantsF, gl_info->vs_arb_constantsF);
2854             gl_info->vs_glsl_constantsF = gl_info->vs_arb_constantsF;
2855         }
2856
2857         /* MacOS advertises GL_ARB_texture_non_power_of_two on ATI r500 and earlier cards, although
2858          * these cards only support GL_ARB_texture_rectangle(D3DPTEXTURECAPS_NONPOW2CONDITIONAL).
2859          * If real NP2 textures are used, the driver falls back to software. So remove the supported
2860          * flag for this extension
2861          */
2862         if(gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO] && gl_info->gl_vendor == VENDOR_ATI) {
2863             if(gl_info->gl_card == CARD_ATI_RADEON_X700 || gl_info->gl_card == CARD_ATI_RADEON_X1600 ||
2864                gl_info->gl_card == CARD_ATI_RADEON_9500 || gl_info->gl_card == CARD_ATI_RADEON_8500  ||
2865                gl_info->gl_card == CARD_ATI_RADEON_7200 || gl_info->gl_card == CARD_ATI_RAGE_128PRO) {
2866                 TRACE("GL_ARB_texture_non_power_of_two advertised on R500 or earlier card, removing\n");
2867                 gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO] = FALSE;
2868                 gl_info->supported[ARB_TEXTURE_RECTANGLE] = TRUE;
2869             }
2870         }
2871
2872         /* The Intel GPUs on MacOS set the .w register of texcoords to 0.0 by default, which causes problems
2873          * with fixed function fragment processing. Ideally this flag should be detected with a test shader
2874          * and opengl feedback mode, but some GL implementations(MacOS ATI at least, propably all macos ones)
2875          * do not like vertex shaders in feedback mode and return an error, even though it should be valid
2876          * according to the spec.
2877          *
2878          * We don't want to enable this on all cards, as it adds an extra instruction per texcoord used. This
2879          * makes the shader slower and eats instruction slots which should be available to the d3d app.
2880          */
2881         if(gl_info->gl_vendor == VENDOR_INTEL) {
2882             TRACE("Enabling vertex texture coord fixes in vertex shaders\n");
2883             gl_info->set_texcoord_w = TRUE;
2884         }
2885     }
2886 }
2887
2888 void invalid_func(void *data) {
2889     ERR("Invalid vertex attribute function called\n");
2890     DebugBreak();
2891 }
2892
2893 #define GLINFO_LOCATION (Adapters[0].gl_info)
2894
2895 /* Helper functions for providing vertex data to opengl. The arrays are initialized based on
2896  * the extension detection and are used in drawStridedSlow
2897  */
2898 static void position_d3dcolor(void *data) {
2899     DWORD pos = *((DWORD *) data);
2900
2901     FIXME("Add a test for fixed function position from d3dcolor type\n");
2902     glVertex4s(D3DCOLOR_B_R(pos),
2903                D3DCOLOR_B_G(pos),
2904                D3DCOLOR_B_B(pos),
2905                D3DCOLOR_B_A(pos));
2906 }
2907 static void position_float4(void *data) {
2908     GLfloat *pos = (float *) data;
2909
2910     if (pos[3] < eps && pos[3] > -eps)
2911         glVertex3fv(pos);
2912     else {
2913         float w = 1.0 / pos[3];
2914
2915         glVertex4f(pos[0] * w, pos[1] * w, pos[2] * w, w);
2916     }
2917 }
2918
2919 static void diffuse_d3dcolor(void *data) {
2920     DWORD diffuseColor = *((DWORD *) data);
2921
2922     glColor4ub(D3DCOLOR_B_R(diffuseColor),
2923                D3DCOLOR_B_G(diffuseColor),
2924                D3DCOLOR_B_B(diffuseColor),
2925                D3DCOLOR_B_A(diffuseColor));
2926 }
2927
2928 static void specular_d3dcolor(void *data) {
2929     DWORD specularColor = *((DWORD *) data);
2930
2931     GL_EXTCALL(glSecondaryColor3ubEXT)(D3DCOLOR_B_R(specularColor),
2932                                        D3DCOLOR_B_G(specularColor),
2933                                        D3DCOLOR_B_B(specularColor));
2934 }
2935 static void warn_no_specular_func(void *data) {
2936     WARN("GL_EXT_secondary_color not supported\n");
2937 }
2938
2939 void fillGLAttribFuncs(WineD3D_GL_Info *gl_info) {
2940     position_funcs[WINED3DDECLTYPE_FLOAT1]      = (void *) invalid_func;
2941     position_funcs[WINED3DDECLTYPE_FLOAT2]      = (void *) invalid_func;
2942     position_funcs[WINED3DDECLTYPE_FLOAT3]      = (void *) glVertex3fv;
2943     position_funcs[WINED3DDECLTYPE_FLOAT4]      = (void *) position_float4;
2944     position_funcs[WINED3DDECLTYPE_D3DCOLOR]    = (void *) position_d3dcolor;
2945     position_funcs[WINED3DDECLTYPE_UBYTE4]      = (void *) invalid_func;
2946     position_funcs[WINED3DDECLTYPE_SHORT2]      = (void *) invalid_func;
2947     position_funcs[WINED3DDECLTYPE_SHORT4]      = (void *) glVertex2sv;
2948     position_funcs[WINED3DDECLTYPE_UBYTE4N]     = (void *) invalid_func;
2949     position_funcs[WINED3DDECLTYPE_SHORT2N]     = (void *) invalid_func;
2950     position_funcs[WINED3DDECLTYPE_SHORT4N]     = (void *) invalid_func;
2951     position_funcs[WINED3DDECLTYPE_USHORT2N]    = (void *) invalid_func;
2952     position_funcs[WINED3DDECLTYPE_USHORT4N]    = (void *) invalid_func;
2953     position_funcs[WINED3DDECLTYPE_UDEC3]       = (void *) invalid_func;
2954     position_funcs[WINED3DDECLTYPE_DEC3N]       = (void *) invalid_func;
2955     position_funcs[WINED3DDECLTYPE_FLOAT16_2]   = (void *) invalid_func;
2956     position_funcs[WINED3DDECLTYPE_FLOAT16_4]   = (void *) invalid_func;
2957
2958     diffuse_funcs[WINED3DDECLTYPE_FLOAT1]       = (void *) invalid_func;
2959     diffuse_funcs[WINED3DDECLTYPE_FLOAT2]       = (void *) invalid_func;
2960     diffuse_funcs[WINED3DDECLTYPE_FLOAT3]       = (void *) glColor3fv;
2961     diffuse_funcs[WINED3DDECLTYPE_FLOAT4]       = (void *) glColor4fv;
2962     diffuse_funcs[WINED3DDECLTYPE_D3DCOLOR]     = (void *) diffuse_d3dcolor;
2963     diffuse_funcs[WINED3DDECLTYPE_UBYTE4]       = (void *) invalid_func;
2964     diffuse_funcs[WINED3DDECLTYPE_SHORT2]       = (void *) invalid_func;
2965     diffuse_funcs[WINED3DDECLTYPE_SHORT4]       = (void *) invalid_func;
2966     diffuse_funcs[WINED3DDECLTYPE_UBYTE4N]      = (void *) glColor4ubv;
2967     diffuse_funcs[WINED3DDECLTYPE_SHORT2N]      = (void *) invalid_func;
2968     diffuse_funcs[WINED3DDECLTYPE_SHORT4N]      = (void *) glColor4sv;
2969     diffuse_funcs[WINED3DDECLTYPE_USHORT2N]     = (void *) invalid_func;
2970     diffuse_funcs[WINED3DDECLTYPE_USHORT4N]     = (void *) glColor4usv;
2971     diffuse_funcs[WINED3DDECLTYPE_UDEC3]        = (void *) invalid_func;
2972     diffuse_funcs[WINED3DDECLTYPE_DEC3N]        = (void *) invalid_func;
2973     diffuse_funcs[WINED3DDECLTYPE_FLOAT16_2]    = (void *) invalid_func;
2974     diffuse_funcs[WINED3DDECLTYPE_FLOAT16_4]    = (void *) invalid_func;
2975
2976     /* No 4 component entry points here */
2977     specular_funcs[WINED3DDECLTYPE_FLOAT1]      = (void *) invalid_func;
2978     specular_funcs[WINED3DDECLTYPE_FLOAT2]      = (void *) invalid_func;
2979     if(GL_SUPPORT(EXT_SECONDARY_COLOR)) {
2980         specular_funcs[WINED3DDECLTYPE_FLOAT3]      = (void *) GL_EXTCALL(glSecondaryColor3fvEXT);
2981     } else {
2982         specular_funcs[WINED3DDECLTYPE_FLOAT3]      = (void *) warn_no_specular_func;
2983     }
2984     specular_funcs[WINED3DDECLTYPE_FLOAT4]      = (void *) invalid_func;
2985     if(GL_SUPPORT(EXT_SECONDARY_COLOR)) {
2986         specular_funcs[WINED3DDECLTYPE_D3DCOLOR]    = (void *) specular_d3dcolor;
2987     } else {
2988         specular_funcs[WINED3DDECLTYPE_FLOAT3]      = (void *) warn_no_specular_func;
2989     }
2990     specular_funcs[WINED3DDECLTYPE_UBYTE4]      = (void *) invalid_func;
2991     specular_funcs[WINED3DDECLTYPE_SHORT2]      = (void *) invalid_func;
2992     specular_funcs[WINED3DDECLTYPE_SHORT4]      = (void *) invalid_func;
2993     specular_funcs[WINED3DDECLTYPE_UBYTE4N]     = (void *) invalid_func;
2994     specular_funcs[WINED3DDECLTYPE_SHORT2N]     = (void *) invalid_func;
2995     specular_funcs[WINED3DDECLTYPE_SHORT4N]     = (void *) invalid_func;
2996     specular_funcs[WINED3DDECLTYPE_USHORT2N]    = (void *) invalid_func;
2997     specular_funcs[WINED3DDECLTYPE_USHORT4N]    = (void *) invalid_func;
2998     specular_funcs[WINED3DDECLTYPE_UDEC3]       = (void *) invalid_func;
2999     specular_funcs[WINED3DDECLTYPE_DEC3N]       = (void *) invalid_func;
3000     specular_funcs[WINED3DDECLTYPE_FLOAT16_2]   = (void *) invalid_func;
3001     specular_funcs[WINED3DDECLTYPE_FLOAT16_4]   = (void *) invalid_func;
3002
3003     /* Only 3 component entry points here. Test how others behave. Float4 normals are used
3004      * by one of our tests, trying to pass it to the pixel shader, which fails on Windows.
3005      */
3006     normal_funcs[WINED3DDECLTYPE_FLOAT1]         = (void *) invalid_func;
3007     normal_funcs[WINED3DDECLTYPE_FLOAT2]         = (void *) invalid_func;
3008     normal_funcs[WINED3DDECLTYPE_FLOAT3]         = (void *) glNormal3fv;
3009     normal_funcs[WINED3DDECLTYPE_FLOAT4]         = (void *) glNormal3fv; /* Just ignore the 4th value */
3010     normal_funcs[WINED3DDECLTYPE_D3DCOLOR]       = (void *) invalid_func;
3011     normal_funcs[WINED3DDECLTYPE_UBYTE4]         = (void *) invalid_func;
3012     normal_funcs[WINED3DDECLTYPE_SHORT2]         = (void *) invalid_func;
3013     normal_funcs[WINED3DDECLTYPE_SHORT4]         = (void *) invalid_func;
3014     normal_funcs[WINED3DDECLTYPE_UBYTE4N]        = (void *) invalid_func;
3015     normal_funcs[WINED3DDECLTYPE_SHORT2N]        = (void *) invalid_func;
3016     normal_funcs[WINED3DDECLTYPE_SHORT4N]        = (void *) invalid_func;
3017     normal_funcs[WINED3DDECLTYPE_USHORT2N]       = (void *) invalid_func;
3018     normal_funcs[WINED3DDECLTYPE_USHORT4N]       = (void *) invalid_func;
3019     normal_funcs[WINED3DDECLTYPE_UDEC3]          = (void *) invalid_func;
3020     normal_funcs[WINED3DDECLTYPE_DEC3N]          = (void *) invalid_func;
3021     normal_funcs[WINED3DDECLTYPE_FLOAT16_2]      = (void *) invalid_func;
3022     normal_funcs[WINED3DDECLTYPE_FLOAT16_4]      = (void *) invalid_func;
3023 }
3024
3025 #define PUSH1(att)        attribs[nAttribs++] = (att);
3026 BOOL InitAdapters(void) {
3027     static HMODULE mod_gl;
3028     BOOL ret;
3029     int ps_selected_mode, vs_selected_mode;
3030
3031     /* No need to hold any lock. The calling library makes sure only one thread calls
3032      * wined3d simultaneously
3033      */
3034     if(numAdapters > 0) return TRUE;
3035
3036     TRACE("Initializing adapters\n");
3037
3038     if(!mod_gl) {
3039 #ifdef USE_WIN32_OPENGL
3040 #define USE_GL_FUNC(pfn) pfn = (void*)GetProcAddress(mod_gl, #pfn);
3041         mod_gl = LoadLibraryA("opengl32.dll");
3042         if(!mod_gl) {
3043             ERR("Can't load opengl32.dll!\n");
3044             return FALSE;
3045         }
3046 #else
3047 #define USE_GL_FUNC(pfn) pfn = (void*)pwglGetProcAddress(#pfn);
3048         /* To bypass the opengl32 thunks load wglGetProcAddress from gdi32 (glXGetProcAddress wrapper) instead of opengl32's */
3049         mod_gl = GetModuleHandleA("gdi32.dll");
3050 #endif
3051     }
3052
3053 /* Load WGL core functions from opengl32.dll */
3054 #define USE_WGL_FUNC(pfn) p##pfn = (void*)GetProcAddress(mod_gl, #pfn);
3055     WGL_FUNCS_GEN;
3056 #undef USE_WGL_FUNC
3057
3058     if(!pwglGetProcAddress) {
3059         ERR("Unable to load wglGetProcAddress!\n");
3060         return FALSE;
3061     }
3062
3063 /* Dynamically load all GL core functions */
3064     GL_FUNCS_GEN;
3065 #undef USE_GL_FUNC
3066
3067     /* For now only one default adapter */
3068     {
3069         int iPixelFormat;
3070         int attribs[8];
3071         int values[8];
3072         int nAttribs = 0;
3073         int res;
3074         WineD3D_PixelFormat *cfgs;
3075         int attribute;
3076         DISPLAY_DEVICEW DisplayDevice;
3077         HDC hdc;
3078
3079         TRACE("Initializing default adapter\n");
3080         Adapters[0].num = 0;
3081         Adapters[0].monitorPoint.x = -1;
3082         Adapters[0].monitorPoint.y = -1;
3083
3084         if (!WineD3D_CreateFakeGLContext()) {
3085             ERR("Failed to get a gl context for default adapter\n");
3086             HeapFree(GetProcessHeap(), 0, Adapters);
3087             WineD3D_ReleaseFakeGLContext();
3088             return FALSE;
3089         }
3090
3091         ret = IWineD3DImpl_FillGLCaps(&Adapters[0].gl_info);
3092         if(!ret) {
3093             ERR("Failed to initialize gl caps for default adapter\n");
3094             HeapFree(GetProcessHeap(), 0, Adapters);
3095             WineD3D_ReleaseFakeGLContext();
3096             return FALSE;
3097         }
3098         ret = initPixelFormats(&Adapters[0].gl_info);
3099         if(!ret) {
3100             ERR("Failed to init gl formats\n");
3101             HeapFree(GetProcessHeap(), 0, Adapters);
3102             WineD3D_ReleaseFakeGLContext();
3103             return FALSE;
3104         }
3105
3106         hdc = pwglGetCurrentDC();
3107         if(!hdc) {
3108             ERR("Failed to get gl HDC\n");
3109             HeapFree(GetProcessHeap(), 0, Adapters);
3110             WineD3D_ReleaseFakeGLContext();
3111             return FALSE;
3112         }
3113
3114         Adapters[0].driver = "Display";
3115         Adapters[0].description = "Direct3D HAL";
3116
3117         /* Use the VideoRamSize registry setting when set */
3118         if(wined3d_settings.emulated_textureram)
3119             Adapters[0].TextureRam = wined3d_settings.emulated_textureram;
3120         else
3121             Adapters[0].TextureRam = Adapters[0].gl_info.vidmem;
3122         Adapters[0].UsedTextureRam = 0;
3123         TRACE("Emulating %dMB of texture ram\n", Adapters[0].TextureRam/(1024*1024));
3124
3125         /* Initialize the Adapter's DeviceName which is required for ChangeDisplaySettings and friends */
3126         DisplayDevice.cb = sizeof(DisplayDevice);
3127         EnumDisplayDevicesW(NULL, 0 /* Adapter 0 = iDevNum 0 */, &DisplayDevice, 0);
3128         TRACE("DeviceName: %s\n", debugstr_w(DisplayDevice.DeviceName));
3129         strcpyW(Adapters[0].DeviceName, DisplayDevice.DeviceName);
3130
3131         attribute = WGL_NUMBER_PIXEL_FORMATS_ARB;
3132         GL_EXTCALL(wglGetPixelFormatAttribivARB(hdc, 0, 0, 1, &attribute, &Adapters[0].nCfgs));
3133
3134         Adapters[0].cfgs = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, Adapters[0].nCfgs *sizeof(WineD3D_PixelFormat));
3135         cfgs = Adapters[0].cfgs;
3136         PUSH1(WGL_RED_BITS_ARB)
3137         PUSH1(WGL_GREEN_BITS_ARB)
3138         PUSH1(WGL_BLUE_BITS_ARB)
3139         PUSH1(WGL_ALPHA_BITS_ARB)
3140         PUSH1(WGL_DEPTH_BITS_ARB)
3141         PUSH1(WGL_STENCIL_BITS_ARB)
3142
3143         for(iPixelFormat=1; iPixelFormat<=Adapters[0].nCfgs; iPixelFormat++) {
3144             res = GL_EXTCALL(wglGetPixelFormatAttribivARB(hdc, iPixelFormat, 0, nAttribs, attribs, values));
3145
3146             if(!res)
3147                 continue;
3148
3149             /* Cache the pixel format */
3150             cfgs->iPixelFormat = iPixelFormat;
3151             cfgs->redSize = values[0];
3152             cfgs->greenSize = values[1];
3153             cfgs->blueSize = values[2];
3154             cfgs->alphaSize = values[3];
3155             cfgs->depthSize = values[4];
3156             cfgs->stencilSize = values[5];
3157
3158             TRACE("iPixelFormat=%d, RGBA=%d/%d/%d/%d, depth=%d, stencil=%d\n", cfgs->iPixelFormat, cfgs->redSize, cfgs->greenSize, cfgs->blueSize, cfgs->alphaSize, cfgs->depthSize, cfgs->stencilSize);
3159             cfgs++;
3160         }
3161         WineD3D_ReleaseFakeGLContext();
3162
3163         fixup_extensions(&Adapters[0].gl_info);
3164
3165         select_shader_mode(&Adapters[0].gl_info, WINED3DDEVTYPE_HAL, &ps_selected_mode, &vs_selected_mode);
3166         select_shader_max_constants(ps_selected_mode, vs_selected_mode, &Adapters[0].gl_info);
3167         fillGLAttribFuncs(&Adapters[0].gl_info);
3168         init_type_lookup(&Adapters[0].gl_info);
3169     }
3170     numAdapters = 1;
3171     TRACE("%d adapters successfully initialized\n", numAdapters);
3172
3173     return TRUE;
3174 }
3175 #undef PUSH1
3176 #undef GLINFO_LOCATION
3177
3178 /**********************************************************
3179  * IWineD3D VTbl follows
3180  **********************************************************/
3181
3182 const IWineD3DVtbl IWineD3D_Vtbl =
3183 {
3184     /* IUnknown */
3185     IWineD3DImpl_QueryInterface,
3186     IWineD3DImpl_AddRef,
3187     IWineD3DImpl_Release,
3188     /* IWineD3D */
3189     IWineD3DImpl_GetParent,
3190     IWineD3DImpl_GetAdapterCount,
3191     IWineD3DImpl_RegisterSoftwareDevice,
3192     IWineD3DImpl_GetAdapterMonitor,
3193     IWineD3DImpl_GetAdapterModeCount,
3194     IWineD3DImpl_EnumAdapterModes,
3195     IWineD3DImpl_GetAdapterDisplayMode,
3196     IWineD3DImpl_GetAdapterIdentifier,
3197     IWineD3DImpl_CheckDeviceMultiSampleType,
3198     IWineD3DImpl_CheckDepthStencilMatch,
3199     IWineD3DImpl_CheckDeviceType,
3200     IWineD3DImpl_CheckDeviceFormat,
3201     IWineD3DImpl_CheckDeviceFormatConversion,
3202     IWineD3DImpl_GetDeviceCaps,
3203     IWineD3DImpl_CreateDevice
3204 };