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