- update wined3d/d3d8/d3d9 to Wine 1.1.15
[reactos.git] / reactos / dll / directx / wine / 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 * Copyright 2007-2008 Stefan Dösinger for CodeWeavers
9 *
10 * This library is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Lesser General Public
12 * License as published by the Free Software Foundation; either
13 * version 2.1 of the License, or (at your option) any later version.
14 *
15 * This library is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * Lesser General Public License for more details.
19 *
20 * You should have received a copy of the GNU Lesser General Public
21 * License along with this library; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
23 */
24
25 /* Compile time diagnostics: */
26
27 #ifndef DEBUG_SINGLE_MODE
28 /* Set to 1 to force only a single display mode to be exposed: */
29 #define DEBUG_SINGLE_MODE 0
30 #endif
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 /* The d3d device ID */
40 static const GUID IID_D3DDEVICE_D3DUID = { 0xaeb2cdd4, 0x6e41, 0x43ea, { 0x94,0x1c,0x83,0x61,0xcc,0x76,0x07,0x81 } };
41
42 /* Extension detection */
43 static const struct {
44 const char *extension_string;
45 GL_SupportedExt extension;
46 DWORD version;
47 } EXTENSION_MAP[] = {
48 /* APPLE */
49 {"GL_APPLE_client_storage", APPLE_CLIENT_STORAGE, 0 },
50 {"GL_APPLE_fence", APPLE_FENCE, 0 },
51 {"GL_APPLE_flush_render", APPLE_FLUSH_RENDER, 0 },
52 {"GL_APPLE_ycbcr_422", APPLE_YCBCR_422, 0 },
53 {"GL_APPLE_float_pixels", APPLE_FLOAT_PIXELS, 0 },
54
55 /* ATI */
56 {"GL_ATI_separate_stencil", ATI_SEPARATE_STENCIL, 0 },
57 {"GL_ATI_texture_env_combine3", ATI_TEXTURE_ENV_COMBINE3, 0 },
58 {"GL_ATI_texture_mirror_once", ATI_TEXTURE_MIRROR_ONCE, 0 },
59 {"GL_ATI_fragment_shader", ATI_FRAGMENT_SHADER, 0 },
60 {"GL_ATI_texture_compression_3dc", ATI_TEXTURE_COMPRESSION_3DC, 0 },
61
62 /* ARB */
63 {"GL_ARB_color_buffer_float", ARB_COLOR_BUFFER_FLOAT, 0 },
64 {"GL_ARB_draw_buffers", ARB_DRAW_BUFFERS, 0 },
65 {"GL_ARB_fragment_program", ARB_FRAGMENT_PROGRAM, 0 },
66 {"GL_ARB_fragment_shader", ARB_FRAGMENT_SHADER, 0 },
67 {"GL_ARB_half_float_pixel", ARB_HALF_FLOAT_PIXEL, 0 },
68 {"GL_ARB_imaging", ARB_IMAGING, 0 },
69 {"GL_ARB_multisample", ARB_MULTISAMPLE, 0 }, /* needs GLX_ARB_MULTISAMPLE as well */
70 {"GL_ARB_multitexture", ARB_MULTITEXTURE, 0 },
71 {"GL_ARB_occlusion_query", ARB_OCCLUSION_QUERY, 0 },
72 {"GL_ARB_pixel_buffer_object", ARB_PIXEL_BUFFER_OBJECT, 0 },
73 {"GL_ARB_point_parameters", ARB_POINT_PARAMETERS, 0 },
74 {"GL_ARB_point_sprite", ARB_POINT_SPRITE, 0 },
75 {"GL_ARB_texture_border_clamp", ARB_TEXTURE_BORDER_CLAMP, 0 },
76 {"GL_ARB_texture_compression", ARB_TEXTURE_COMPRESSION, 0 },
77 {"GL_ARB_texture_cube_map", ARB_TEXTURE_CUBE_MAP, 0 },
78 {"GL_ARB_texture_env_add", ARB_TEXTURE_ENV_ADD, 0 },
79 {"GL_ARB_texture_env_combine", ARB_TEXTURE_ENV_COMBINE, 0 },
80 {"GL_ARB_texture_env_dot3", ARB_TEXTURE_ENV_DOT3, 0 },
81 {"GL_ARB_texture_float", ARB_TEXTURE_FLOAT, 0 },
82 {"GL_ARB_texture_mirrored_repeat", ARB_TEXTURE_MIRRORED_REPEAT, 0 },
83 {"GL_ARB_texture_non_power_of_two", ARB_TEXTURE_NON_POWER_OF_TWO, MAKEDWORD_VERSION(2, 0) },
84 {"GL_ARB_texture_rectangle", ARB_TEXTURE_RECTANGLE, 0 },
85 {"GL_ARB_texture_rg", ARB_TEXTURE_RG, 0 },
86 {"GL_ARB_vertex_blend", ARB_VERTEX_BLEND, 0 },
87 {"GL_ARB_vertex_buffer_object", ARB_VERTEX_BUFFER_OBJECT, 0 },
88 {"GL_ARB_vertex_program", ARB_VERTEX_PROGRAM, 0 },
89 {"GL_ARB_vertex_shader", ARB_VERTEX_SHADER, 0 },
90 {"GL_ARB_shader_objects", ARB_SHADER_OBJECTS, 0 },
91
92 /* EXT */
93 {"GL_EXT_blend_color", EXT_BLEND_COLOR, 0 },
94 {"GL_EXT_blend_minmax", EXT_BLEND_MINMAX, 0 },
95 {"GL_EXT_blend_equation_separate", EXT_BLEND_EQUATION_SEPARATE, 0 },
96 {"GL_EXT_blend_func_separate", EXT_BLEND_FUNC_SEPARATE, 0 },
97 {"GL_EXT_fog_coord", EXT_FOG_COORD, 0 },
98 {"GL_EXT_framebuffer_blit", EXT_FRAMEBUFFER_BLIT, 0 },
99 {"GL_EXT_framebuffer_multisample", EXT_FRAMEBUFFER_MULTISAMPLE, 0 },
100 {"GL_EXT_framebuffer_object", EXT_FRAMEBUFFER_OBJECT, 0 },
101 {"GL_EXT_paletted_texture", EXT_PALETTED_TEXTURE, 0 },
102 {"GL_EXT_point_parameters", EXT_POINT_PARAMETERS, 0 },
103 {"GL_EXT_secondary_color", EXT_SECONDARY_COLOR, 0 },
104 {"GL_EXT_stencil_two_side", EXT_STENCIL_TWO_SIDE, 0 },
105 {"GL_EXT_stencil_wrap", EXT_STENCIL_WRAP, 0 },
106 {"GL_EXT_texture3D", EXT_TEXTURE3D, MAKEDWORD_VERSION(1, 2) },
107 {"GL_EXT_texture_compression_s3tc", EXT_TEXTURE_COMPRESSION_S3TC, 0 },
108 {"GL_EXT_texture_compression_rgtc", EXT_TEXTURE_COMPRESSION_RGTC, 0 },
109 {"GL_EXT_texture_env_add", EXT_TEXTURE_ENV_ADD, 0 },
110 {"GL_EXT_texture_env_combine", EXT_TEXTURE_ENV_COMBINE, 0 },
111 {"GL_EXT_texture_env_dot3", EXT_TEXTURE_ENV_DOT3, 0 },
112 {"GL_EXT_texture_sRGB", EXT_TEXTURE_SRGB, 0 },
113 {"GL_EXT_texture_swizzle", EXT_TEXTURE_SWIZZLE, 0 },
114 {"GL_EXT_texture_filter_anisotropic", EXT_TEXTURE_FILTER_ANISOTROPIC, 0 },
115 {"GL_EXT_texture_lod", EXT_TEXTURE_LOD, 0 },
116 {"GL_EXT_texture_lod_bias", EXT_TEXTURE_LOD_BIAS, 0 },
117 {"GL_EXT_vertex_array_bgra", EXT_VERTEX_ARRAY_BGRA, 0 },
118 {"GL_EXT_vertex_shader", EXT_VERTEX_SHADER, 0 },
119 {"GL_EXT_gpu_program_parameters", EXT_GPU_PROGRAM_PARAMETERS, 0 },
120
121 /* NV */
122 {"GL_NV_half_float", NV_HALF_FLOAT, 0 },
123 {"GL_NV_fence", NV_FENCE, 0 },
124 {"GL_NV_fog_distance", NV_FOG_DISTANCE, 0 },
125 {"GL_NV_fragment_program", NV_FRAGMENT_PROGRAM, 0 },
126 {"GL_NV_fragment_program2", NV_FRAGMENT_PROGRAM2, 0 },
127 {"GL_NV_register_combiners", NV_REGISTER_COMBINERS, 0 },
128 {"GL_NV_register_combiners2", NV_REGISTER_COMBINERS2, 0 },
129 {"GL_NV_texgen_reflection", NV_TEXGEN_REFLECTION, 0 },
130 {"GL_NV_texture_env_combine4", NV_TEXTURE_ENV_COMBINE4, 0 },
131 {"GL_NV_texture_shader", NV_TEXTURE_SHADER, 0 },
132 {"GL_NV_texture_shader2", NV_TEXTURE_SHADER2, 0 },
133 {"GL_NV_texture_shader3", NV_TEXTURE_SHADER3, 0 },
134 {"GL_NV_occlusion_query", NV_OCCLUSION_QUERY, 0 },
135 {"GL_NV_vertex_program", NV_VERTEX_PROGRAM, 0 },
136 {"GL_NV_vertex_program1_1", NV_VERTEX_PROGRAM1_1, 0 },
137 {"GL_NV_vertex_program2", NV_VERTEX_PROGRAM2, 0 },
138 {"GL_NV_vertex_program3", NV_VERTEX_PROGRAM3, 0 },
139 {"GL_NV_depth_clamp", NV_DEPTH_CLAMP, 0 },
140 {"GL_NV_light_max_exponent", NV_LIGHT_MAX_EXPONENT, 0 },
141
142 /* SGI */
143 {"GL_SGIS_generate_mipmap", SGIS_GENERATE_MIPMAP, 0 },
144 };
145
146 /**********************************************************
147 * Utility functions follow
148 **********************************************************/
149
150 /* Adapters */
151 static int numAdapters = 0;
152 static struct WineD3DAdapter Adapters[1];
153
154 static HRESULT WINAPI IWineD3DImpl_CheckDeviceFormat(IWineD3D *iface, UINT Adapter, WINED3DDEVTYPE DeviceType, WINED3DFORMAT AdapterFormat, DWORD Usage, WINED3DRESOURCETYPE RType, WINED3DFORMAT CheckFormat, WINED3DSURFTYPE SurfaceType);
155 static const struct fragment_pipeline *select_fragment_implementation(UINT Adapter, WINED3DDEVTYPE DeviceType);
156 static const shader_backend_t *select_shader_backend(UINT Adapter, WINED3DDEVTYPE DeviceType);
157 static const struct blit_shader *select_blit_implementation(UINT Adapter, WINED3DDEVTYPE DeviceType);
158
159 /* lookup tables */
160 const int minLookup[MAX_LOOKUPS] =
161 {
162 WINED3DTADDRESS_WRAP, /* WINELOOKUP_WARPPARAM */
163 };
164
165 const int maxLookup[MAX_LOOKUPS] =
166 {
167 WINED3DTADDRESS_MIRRORONCE, /* WINELOOKUP_WARPPARAM */
168 };
169
170 DWORD *stateLookup[MAX_LOOKUPS];
171
172 struct min_lookup minMipLookup[WINED3DTEXF_ANISOTROPIC + 1];
173 const struct min_lookup minMipLookup_noFilter[WINED3DTEXF_ANISOTROPIC + 1] =
174 {
175 {{GL_NEAREST, GL_NEAREST, GL_NEAREST}},
176 {{GL_NEAREST, GL_NEAREST, GL_NEAREST}},
177 {{GL_NEAREST, GL_NEAREST, GL_NEAREST}},
178 {{GL_NEAREST, GL_NEAREST, GL_NEAREST}},
179 };
180
181 GLenum magLookup[WINED3DTEXF_ANISOTROPIC + 1];
182 const GLenum magLookup_noFilter[WINED3DTEXF_ANISOTROPIC + 1] =
183 {
184 GL_NEAREST, GL_NEAREST, GL_NEAREST, GL_NEAREST
185 };
186
187 /* drawStridedSlow attributes */
188 glAttribFunc position_funcs[WINED3DDECLTYPE_UNUSED];
189 glAttribFunc diffuse_funcs[WINED3DDECLTYPE_UNUSED];
190 glAttribFunc specular_funcs[WINED3DDECLTYPE_UNUSED];
191 glAttribFunc normal_funcs[WINED3DDECLTYPE_UNUSED];
192 glMultiTexCoordFunc multi_texcoord_funcs[WINED3DDECLTYPE_UNUSED];
193
194 /**
195 * Note: GL seems to trap if GetDeviceCaps is called before any HWND's created,
196 * i.e., there is no GL Context - Get a default rendering context to enable the
197 * function query some info from GL.
198 */
199
200 static int wined3d_fake_gl_context_ref = 0;
201 static BOOL wined3d_fake_gl_context_foreign;
202 static BOOL wined3d_fake_gl_context_available = FALSE;
203 static HDC wined3d_fake_gl_context_hdc = NULL;
204 static HWND wined3d_fake_gl_context_hwnd = NULL;
205
206 static CRITICAL_SECTION wined3d_fake_gl_context_cs;
207 static CRITICAL_SECTION_DEBUG wined3d_fake_gl_context_cs_debug =
208 {
209 0, 0, &wined3d_fake_gl_context_cs,
210 { &wined3d_fake_gl_context_cs_debug.ProcessLocksList,
211 &wined3d_fake_gl_context_cs_debug.ProcessLocksList },
212 0, 0, { (DWORD_PTR)(__FILE__ ": wined3d_fake_gl_context_cs") }
213 };
214 static CRITICAL_SECTION wined3d_fake_gl_context_cs = { &wined3d_fake_gl_context_cs_debug, -1, 0, 0, 0, 0 };
215
216 static void WineD3D_ReleaseFakeGLContext(void) {
217 HGLRC glCtx;
218
219 EnterCriticalSection(&wined3d_fake_gl_context_cs);
220
221 if(!wined3d_fake_gl_context_available) {
222 TRACE_(d3d_caps)("context not available\n");
223 LeaveCriticalSection(&wined3d_fake_gl_context_cs);
224 return;
225 }
226
227 glCtx = pwglGetCurrentContext();
228
229 TRACE_(d3d_caps)("decrementing ref from %i\n", wined3d_fake_gl_context_ref);
230 if (0 == (--wined3d_fake_gl_context_ref) ) {
231 if(!wined3d_fake_gl_context_foreign && glCtx) {
232 TRACE_(d3d_caps)("destroying fake GL context\n");
233 pwglMakeCurrent(NULL, NULL);
234 //ros hack, this line does destire the real icd interface in windows and reactos
235 // pwglDeleteContext(glCtx);
236 }
237 if(wined3d_fake_gl_context_hdc)
238 ReleaseDC(wined3d_fake_gl_context_hwnd, wined3d_fake_gl_context_hdc);
239 wined3d_fake_gl_context_hdc = NULL; /* Make sure we don't think that it is still around */
240 if(wined3d_fake_gl_context_hwnd)
241 DestroyWindow(wined3d_fake_gl_context_hwnd);
242 wined3d_fake_gl_context_hwnd = NULL;
243 wined3d_fake_gl_context_available = FALSE;
244 }
245 assert(wined3d_fake_gl_context_ref >= 0);
246
247 LeaveCriticalSection(&wined3d_fake_gl_context_cs);
248 }
249
250 static BOOL WineD3D_CreateFakeGLContext(void) {
251 HGLRC glCtx = NULL;
252
253 EnterCriticalSection(&wined3d_fake_gl_context_cs);
254
255 TRACE("getting context...\n");
256 if(wined3d_fake_gl_context_ref > 0) goto ret;
257 assert(0 == wined3d_fake_gl_context_ref);
258
259 wined3d_fake_gl_context_foreign = TRUE;
260
261 glCtx = pwglGetCurrentContext();
262 if (!glCtx) {
263 PIXELFORMATDESCRIPTOR pfd;
264 int iPixelFormat;
265
266 wined3d_fake_gl_context_foreign = FALSE;
267
268 /* We need a fake window as a hdc retrieved using GetDC(0) can't be used for much GL purposes */
269 wined3d_fake_gl_context_hwnd = CreateWindowA("WineD3D_OpenGL", "WineD3D fake window", WS_OVERLAPPEDWINDOW, 10, 10, 10, 10, NULL, NULL, NULL, NULL);
270 if(!wined3d_fake_gl_context_hwnd) {
271 ERR("HWND creation failed!\n");
272 goto fail;
273 }
274 wined3d_fake_gl_context_hdc = GetDC(wined3d_fake_gl_context_hwnd);
275 if(!wined3d_fake_gl_context_hdc) {
276 ERR("GetDC failed!\n");
277 goto fail;
278 }
279
280 /* PixelFormat selection */
281 ZeroMemory(&pfd, sizeof(pfd));
282 pfd.nSize = sizeof(pfd);
283 pfd.nVersion = 1;
284 pfd.dwFlags = PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER | PFD_DRAW_TO_WINDOW;/*PFD_GENERIC_ACCELERATED*/
285 pfd.iPixelType = PFD_TYPE_RGBA;
286 pfd.cColorBits = 32;
287 pfd.iLayerType = PFD_MAIN_PLANE;
288
289 iPixelFormat = ChoosePixelFormat(wined3d_fake_gl_context_hdc, &pfd);
290 if(!iPixelFormat) {
291 /* If this happens something is very wrong as ChoosePixelFormat barely fails */
292 ERR("Can't find a suitable iPixelFormat\n");
293 goto fail;
294 }
295 DescribePixelFormat(wined3d_fake_gl_context_hdc, iPixelFormat, sizeof(pfd), &pfd);
296 SetPixelFormat(wined3d_fake_gl_context_hdc, iPixelFormat, &pfd);
297
298 /* Create a GL context */
299 glCtx = pwglCreateContext(wined3d_fake_gl_context_hdc);
300 if (!glCtx) {
301 WARN_(d3d_caps)("Error creating default context for capabilities initialization\n");
302 goto fail;
303 }
304
305 /* Make it the current GL context */
306 if (!pwglMakeCurrent(wined3d_fake_gl_context_hdc, glCtx)) {
307 WARN_(d3d_caps)("Error setting default context as current for capabilities initialization\n");
308 goto fail;
309 }
310 }
311
312 ret:
313 TRACE("incrementing ref from %i\n", wined3d_fake_gl_context_ref);
314 wined3d_fake_gl_context_ref++;
315 wined3d_fake_gl_context_available = TRUE;
316 LeaveCriticalSection(&wined3d_fake_gl_context_cs);
317 return TRUE;
318 fail:
319 if(wined3d_fake_gl_context_hdc)
320 ReleaseDC(wined3d_fake_gl_context_hwnd, wined3d_fake_gl_context_hdc);
321 wined3d_fake_gl_context_hdc = NULL;
322 if(wined3d_fake_gl_context_hwnd)
323 DestroyWindow(wined3d_fake_gl_context_hwnd);
324 wined3d_fake_gl_context_hwnd = NULL;
325 if(glCtx) pwglDeleteContext(glCtx);
326 LeaveCriticalSection(&wined3d_fake_gl_context_cs);
327 return FALSE;
328 }
329
330 /* Adjust the amount of used texture memory */
331 long WineD3DAdapterChangeGLRam(IWineD3DDeviceImpl *D3DDevice, long glram){
332 UINT Adapter = D3DDevice->adapterNo;
333
334 Adapters[Adapter].UsedTextureRam += glram;
335 TRACE("Adjusted gl ram by %ld to %d\n", glram, Adapters[Adapter].UsedTextureRam);
336 return Adapters[Adapter].UsedTextureRam;
337 }
338
339 /**********************************************************
340 * IUnknown parts follows
341 **********************************************************/
342
343 static HRESULT WINAPI IWineD3DImpl_QueryInterface(IWineD3D *iface,REFIID riid,LPVOID *ppobj)
344 {
345 IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
346
347 TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(riid),ppobj);
348 if (IsEqualGUID(riid, &IID_IUnknown)
349 || IsEqualGUID(riid, &IID_IWineD3DBase)
350 || IsEqualGUID(riid, &IID_IWineD3DDevice)) {
351 IUnknown_AddRef(iface);
352 *ppobj = This;
353 return S_OK;
354 }
355 *ppobj = NULL;
356 return E_NOINTERFACE;
357 }
358
359 static ULONG WINAPI IWineD3DImpl_AddRef(IWineD3D *iface) {
360 IWineD3DImpl *This = (IWineD3DImpl *)iface;
361 ULONG refCount = InterlockedIncrement(&This->ref);
362
363 TRACE("(%p) : AddRef increasing from %d\n", This, refCount - 1);
364 return refCount;
365 }
366
367 static ULONG WINAPI IWineD3DImpl_Release(IWineD3D *iface) {
368 IWineD3DImpl *This = (IWineD3DImpl *)iface;
369 ULONG ref;
370 TRACE("(%p) : Releasing from %d\n", This, This->ref);
371 ref = InterlockedDecrement(&This->ref);
372 if (ref == 0) {
373 HeapFree(GetProcessHeap(), 0, This);
374 }
375
376 return ref;
377 }
378
379 /* Set the shader type for this device, depending on the given capabilities,
380 * the device type, and the user preferences in wined3d_settings */
381
382 static void select_shader_mode(const WineD3D_GL_Info *gl_info, WINED3DDEVTYPE DeviceType, int *ps_selected, int *vs_selected)
383 {
384 if (wined3d_settings.vs_mode == VS_NONE) {
385 *vs_selected = SHADER_NONE;
386 } else if (gl_info->supported[ARB_VERTEX_SHADER] && wined3d_settings.glslRequested) {
387 /* Geforce4 cards support GLSL but for vertex shaders only. Further its reported GLSL caps are
388 * wrong. This combined with the fact that glsl won't offer more features or performance, use ARB
389 * shaders only on this card. */
390 if(gl_info->vs_nv_version && gl_info->vs_nv_version < VS_VERSION_20)
391 *vs_selected = SHADER_ARB;
392 else
393 *vs_selected = SHADER_GLSL;
394 } else if (gl_info->supported[ARB_VERTEX_PROGRAM]) {
395 *vs_selected = SHADER_ARB;
396 } else {
397 *vs_selected = SHADER_NONE;
398 }
399
400 if (wined3d_settings.ps_mode == PS_NONE) {
401 *ps_selected = SHADER_NONE;
402 } else if (gl_info->supported[ARB_FRAGMENT_SHADER] && wined3d_settings.glslRequested) {
403 *ps_selected = SHADER_GLSL;
404 } else if (gl_info->supported[ARB_FRAGMENT_PROGRAM]) {
405 *ps_selected = SHADER_ARB;
406 } else if (gl_info->supported[ATI_FRAGMENT_SHADER]) {
407 *ps_selected = SHADER_ATI;
408 } else {
409 *ps_selected = SHADER_NONE;
410 }
411 }
412
413 /** Select the number of report maximum shader constants based on the selected shader modes */
414 static void select_shader_max_constants(
415 int ps_selected_mode,
416 int vs_selected_mode,
417 WineD3D_GL_Info *gl_info) {
418
419 switch (vs_selected_mode) {
420 case SHADER_GLSL:
421 /* Subtract the other potential uniforms from the max available (bools, ints, and 1 row of projection matrix) */
422 gl_info->max_vshader_constantsF = gl_info->vs_glsl_constantsF - (MAX_CONST_B / 4) - MAX_CONST_I - 1;
423 break;
424 case SHADER_ARB:
425 /* We have to subtract any other PARAMs that we might use in our shader programs.
426 * ATI seems to count 2 implicit PARAMs when we use fog and NVIDIA counts 1,
427 * and we reference one row of the PROJECTION matrix which counts as 1 PARAM. */
428 gl_info->max_vshader_constantsF = gl_info->vs_arb_constantsF - 3;
429 break;
430 default:
431 gl_info->max_vshader_constantsF = 0;
432 break;
433 }
434
435 switch (ps_selected_mode) {
436 case SHADER_GLSL:
437 /* Subtract the other potential uniforms from the max available (bools & ints), and 2 states for fog.
438 * In theory the texbem instruction may need one more shader constant too. But lets assume
439 * that a sm <= 1.3 shader does not need all the uniforms provided by a glsl-capable card,
440 * and lets not take away a uniform needlessly from all other shaders.
441 */
442 gl_info->max_pshader_constantsF = gl_info->ps_glsl_constantsF - (MAX_CONST_B / 4) - MAX_CONST_I - 2;
443 break;
444 case SHADER_ARB:
445 /* The arb shader only loads the bump mapping environment matrix into the shader if it finds
446 * a free constant to do that, so only reduce the number of available constants by 2 for the fog states.
447 */
448 gl_info->max_pshader_constantsF = gl_info->ps_arb_constantsF - 2;
449 break;
450 default:
451 gl_info->max_pshader_constantsF = 0;
452 break;
453 }
454 }
455
456 /**********************************************************
457 * IWineD3D parts follows
458 **********************************************************/
459
460 #define GLINFO_LOCATION (*gl_info)
461 static inline BOOL test_arb_vs_offset_limit(const WineD3D_GL_Info *gl_info)
462 {
463 GLuint prog;
464 BOOL ret = FALSE;
465 const char *testcode =
466 "!!ARBvp1.0\n"
467 "PARAM C[66] = { program.env[0..65] };\n"
468 "ADDRESS A0;"
469 "PARAM zero = {0.0, 0.0, 0.0, 0.0};\n"
470 "ARL A0.x, zero.x;\n"
471 "MOV result.position, C[A0.x + 65];\n"
472 "END\n";
473
474 while(glGetError());
475 GL_EXTCALL(glGenProgramsARB(1, &prog));
476 if(!prog) {
477 ERR("Failed to create an ARB offset limit test program\n");
478 }
479 GL_EXTCALL(glBindProgramARB(GL_VERTEX_PROGRAM_ARB, prog));
480 GL_EXTCALL(glProgramStringARB(GL_VERTEX_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB,
481 strlen(testcode), testcode));
482 if(glGetError() != 0) {
483 TRACE("OpenGL implementation does not allow indirect addressing offsets > 63\n");
484 TRACE("error: %s\n", debugstr_a((const char *)glGetString(GL_PROGRAM_ERROR_STRING_ARB)));
485 ret = TRUE;
486 } else TRACE("OpenGL implementation allows offsets > 63\n");
487
488 GL_EXTCALL(glBindProgramARB(GL_VERTEX_PROGRAM_ARB, 0));
489 GL_EXTCALL(glDeleteProgramsARB(1, &prog));
490 checkGLcall("ARB vp offset limit test cleanup\n");
491
492 return ret;
493 }
494
495 static DWORD ver_for_ext(GL_SupportedExt ext)
496 {
497 unsigned int i;
498 for (i = 0; i < (sizeof(EXTENSION_MAP) / sizeof(*EXTENSION_MAP)); ++i) {
499 if(EXTENSION_MAP[i].extension == ext) {
500 return EXTENSION_MAP[i].version;
501 }
502 }
503 return 0;
504 }
505
506 static BOOL IWineD3DImpl_FillGLCaps(WineD3D_GL_Info *gl_info) {
507 const char *GL_Extensions = NULL;
508 const char *WGL_Extensions = NULL;
509 const char *gl_string = NULL;
510 const char *gl_string_cursor = NULL;
511 GLint gl_max;
512 GLfloat gl_floatv[2];
513 int major = 1, minor = 0;
514 BOOL return_value = TRUE;
515 unsigned i;
516 HDC hdc;
517 unsigned int vidmem=0;
518
519 TRACE_(d3d_caps)("(%p)\n", gl_info);
520
521 ENTER_GL();
522
523 gl_string = (const char *) glGetString(GL_RENDERER);
524 if (!gl_string) gl_string = "None";
525 strcpy(gl_info->gl_renderer, gl_string);
526
527 gl_string = (const char *) glGetString(GL_VENDOR);
528 TRACE_(d3d_caps)("Filling vendor string %s\n", gl_string);
529 if (gl_string != NULL) {
530 /* Fill in the GL vendor */
531 if (strstr(gl_string, "NVIDIA")) {
532 gl_info->gl_vendor = VENDOR_NVIDIA;
533 } else if (strstr(gl_string, "ATI")) {
534 gl_info->gl_vendor = VENDOR_ATI;
535 } else if (strstr(gl_string, "Intel(R)") ||
536 strstr(gl_info->gl_renderer, "Intel(R)") ||
537 strstr(gl_string, "Intel Inc.")) {
538 gl_info->gl_vendor = VENDOR_INTEL;
539 } else if (strstr(gl_string, "Mesa")) {
540 gl_info->gl_vendor = VENDOR_MESA;
541 } else {
542 gl_info->gl_vendor = VENDOR_WINE;
543 }
544 } else {
545 gl_info->gl_vendor = VENDOR_WINE;
546 }
547
548
549 TRACE_(d3d_caps)("found GL_VENDOR (%s)->(0x%04x)\n", debugstr_a(gl_string), gl_info->gl_vendor);
550
551 /* Parse the GL_VERSION field into major and minor information */
552 gl_string = (const char *) glGetString(GL_VERSION);
553 if (gl_string != NULL) {
554
555 /* First, parse the generic opengl version. This is supposed not to be convoluted with
556 * driver specific information
557 */
558 gl_string_cursor = gl_string;
559 major = atoi(gl_string_cursor);
560 if(major <= 0) {
561 ERR("Invalid opengl major version: %d\n", major);
562 }
563 while (*gl_string_cursor <= '9' && *gl_string_cursor >= '0') {
564 ++gl_string_cursor;
565 }
566 if (*gl_string_cursor++ != '.') {
567 ERR_(d3d_caps)("Invalid opengl version string: %s\n", debugstr_a(gl_string));
568 }
569 minor = atoi(gl_string_cursor);
570 TRACE_(d3d_caps)("Found OpenGL version: %d.%d\n", major, minor);
571 gl_info->gl_version = MAKEDWORD_VERSION(major, minor);
572
573 /* Now parse the driver specific string which we'll report to the app */
574 switch (gl_info->gl_vendor) {
575 case VENDOR_NVIDIA:
576 gl_string_cursor = strstr(gl_string, "NVIDIA");
577 if (!gl_string_cursor) {
578 ERR_(d3d_caps)("Invalid nVidia version string: %s\n", debugstr_a(gl_string));
579 break;
580 }
581
582 gl_string_cursor = strstr(gl_string_cursor, " ");
583 if (!gl_string_cursor) {
584 ERR_(d3d_caps)("Invalid nVidia version string: %s\n", debugstr_a(gl_string));
585 break;
586 }
587
588 while (*gl_string_cursor == ' ') {
589 ++gl_string_cursor;
590 }
591
592 if (!*gl_string_cursor) {
593 ERR_(d3d_caps)("Invalid nVidia version string: %s\n", debugstr_a(gl_string));
594 break;
595 }
596
597 major = atoi(gl_string_cursor);
598 while (*gl_string_cursor <= '9' && *gl_string_cursor >= '0') {
599 ++gl_string_cursor;
600 }
601
602 if (*gl_string_cursor++ != '.') {
603 ERR_(d3d_caps)("Invalid nVidia version string: %s\n", debugstr_a(gl_string));
604 break;
605 }
606
607 minor = atoi(gl_string_cursor);
608 minor = major*100+minor;
609 major = 10;
610
611 break;
612
613 case VENDOR_ATI:
614 major = minor = 0;
615 gl_string_cursor = strchr(gl_string, '-');
616 if (gl_string_cursor) {
617 int error = 0;
618 gl_string_cursor++;
619
620 /* Check if version number is of the form x.y.z */
621 if (*gl_string_cursor > '9' && *gl_string_cursor < '0')
622 error = 1;
623 if (!error && *(gl_string_cursor+2) > '9' && *(gl_string_cursor+2) < '0')
624 error = 1;
625 if (!error && *(gl_string_cursor+4) > '9' && *(gl_string_cursor+4) < '0')
626 error = 1;
627 if (!error && *(gl_string_cursor+1) != '.' && *(gl_string_cursor+3) != '.')
628 error = 1;
629
630 /* Mark version number as malformed */
631 if (error)
632 gl_string_cursor = 0;
633 }
634
635 if (!gl_string_cursor)
636 WARN_(d3d_caps)("malformed GL_VERSION (%s)\n", debugstr_a(gl_string));
637 else {
638 major = *gl_string_cursor - '0';
639 minor = (*(gl_string_cursor+2) - '0') * 256 + (*(gl_string_cursor+4) - '0');
640 }
641 break;
642
643 case VENDOR_INTEL:
644 /* Apple and Mesa version strings look differently, but both provide intel drivers */
645 if(strstr(gl_string, "APPLE")) {
646 /* [0-9]+.[0-9]+ APPLE-[0-9]+.[0.9]+.[0.9]+
647 * We only need the first part, and use the APPLE as identification
648 * "1.2 APPLE-1.4.56"
649 */
650 gl_string_cursor = gl_string;
651 major = atoi(gl_string_cursor);
652 while (*gl_string_cursor <= '9' && *gl_string_cursor >= '0') {
653 ++gl_string_cursor;
654 }
655
656 if (*gl_string_cursor++ != '.') {
657 ERR_(d3d_caps)("Invalid MacOS-Intel version string: %s\n", debugstr_a(gl_string));
658 break;
659 }
660
661 minor = atoi(gl_string_cursor);
662 break;
663 }
664
665 case VENDOR_MESA:
666 gl_string_cursor = strstr(gl_string, "Mesa");
667 gl_string_cursor = strstr(gl_string_cursor, " ");
668 while (*gl_string_cursor && ' ' == *gl_string_cursor) ++gl_string_cursor;
669 if (*gl_string_cursor) {
670 char tmp[16];
671 int cursor = 0;
672
673 while (*gl_string_cursor <= '9' && *gl_string_cursor >= '0') {
674 tmp[cursor++] = *gl_string_cursor;
675 ++gl_string_cursor;
676 }
677 tmp[cursor] = 0;
678 major = atoi(tmp);
679
680 if (*gl_string_cursor != '.') WARN_(d3d_caps)("malformed GL_VERSION (%s)\n", debugstr_a(gl_string));
681 ++gl_string_cursor;
682
683 cursor = 0;
684 while (*gl_string_cursor <= '9' && *gl_string_cursor >= '0') {
685 tmp[cursor++] = *gl_string_cursor;
686 ++gl_string_cursor;
687 }
688 tmp[cursor] = 0;
689 minor = atoi(tmp);
690 }
691 break;
692
693 default:
694 major = 0;
695 minor = 9;
696 }
697 gl_info->driver_version = MAKEDWORD_VERSION(major, minor);
698 TRACE_(d3d_caps)("found driver version (%s)->%i.%i->(0x%08x)\n", debugstr_a(gl_string), major, minor, gl_info->driver_version);
699 /* Current Windows drivers have versions like 6.14.... (some older have an earlier version) */
700 gl_info->driver_version_hipart = MAKEDWORD_VERSION(6, 14);
701 } else {
702 FIXME("OpenGL driver did not return version information\n");
703 gl_info->driver_version = MAKEDWORD_VERSION(0, 0);
704 gl_info->driver_version_hipart = MAKEDWORD_VERSION(6, 14);
705 }
706
707 TRACE_(d3d_caps)("found GL_RENDERER (%s)->(0x%04x)\n", debugstr_a(gl_info->gl_renderer), gl_info->gl_card);
708
709 /*
710 * Initialize openGL extension related variables
711 * with Default values
712 */
713 memset(gl_info->supported, 0, sizeof(gl_info->supported));
714 gl_info->max_buffers = 1;
715 gl_info->max_textures = 1;
716 gl_info->max_texture_stages = 1;
717 gl_info->max_fragment_samplers = 1;
718 gl_info->max_vertex_samplers = 0;
719 gl_info->max_combined_samplers = gl_info->max_fragment_samplers + gl_info->max_vertex_samplers;
720 gl_info->max_sampler_stages = 1;
721 gl_info->ps_arb_version = PS_VERSION_NOT_SUPPORTED;
722 gl_info->ps_arb_max_temps = 0;
723 gl_info->ps_arb_max_instructions = 0;
724 gl_info->vs_arb_version = VS_VERSION_NOT_SUPPORTED;
725 gl_info->vs_arb_max_temps = 0;
726 gl_info->vs_arb_max_instructions = 0;
727 gl_info->vs_nv_version = VS_VERSION_NOT_SUPPORTED;
728 gl_info->vs_ati_version = VS_VERSION_NOT_SUPPORTED;
729 gl_info->vs_glsl_constantsF = 0;
730 gl_info->ps_glsl_constantsF = 0;
731 gl_info->vs_arb_constantsF = 0;
732 gl_info->ps_arb_constantsF = 0;
733
734 /* Retrieve opengl defaults */
735 glGetIntegerv(GL_MAX_CLIP_PLANES, &gl_max);
736 gl_info->max_clipplanes = min(WINED3DMAXUSERCLIPPLANES, gl_max);
737 TRACE_(d3d_caps)("ClipPlanes support - num Planes=%d\n", gl_max);
738
739 glGetIntegerv(GL_MAX_LIGHTS, &gl_max);
740 gl_info->max_lights = gl_max;
741 TRACE_(d3d_caps)("Lights support - max lights=%d\n", gl_max);
742
743 glGetIntegerv(GL_MAX_TEXTURE_SIZE, &gl_max);
744 gl_info->max_texture_size = gl_max;
745 TRACE_(d3d_caps)("Maximum texture size support - max texture size=%d\n", gl_max);
746
747 glGetFloatv(GL_ALIASED_POINT_SIZE_RANGE, gl_floatv);
748 gl_info->max_pointsizemin = gl_floatv[0];
749 gl_info->max_pointsize = gl_floatv[1];
750 TRACE_(d3d_caps)("Maximum point size support - max point size=%f\n", gl_floatv[1]);
751
752 /* Parse the gl supported features, in theory enabling parts of our code appropriately */
753 GL_Extensions = (const char *) glGetString(GL_EXTENSIONS);
754 TRACE_(d3d_caps)("GL_Extensions reported:\n");
755
756 if (NULL == GL_Extensions) {
757 ERR(" GL_Extensions returns NULL\n");
758 } else {
759 while (*GL_Extensions != 0x00) {
760 const char *Start;
761 char ThisExtn[256];
762 size_t len;
763
764 while (isspace(*GL_Extensions)) GL_Extensions++;
765 Start = GL_Extensions;
766 while (!isspace(*GL_Extensions) && *GL_Extensions != 0x00) {
767 GL_Extensions++;
768 }
769
770 len = GL_Extensions - Start;
771 if (len == 0 || len >= sizeof(ThisExtn))
772 continue;
773
774 memcpy(ThisExtn, Start, len);
775 ThisExtn[len] = '\0';
776 TRACE_(d3d_caps)("- %s\n", ThisExtn);
777
778 for (i = 0; i < (sizeof(EXTENSION_MAP) / sizeof(*EXTENSION_MAP)); ++i) {
779 if (!strcmp(ThisExtn, EXTENSION_MAP[i].extension_string)) {
780 TRACE_(d3d_caps)(" FOUND: %s support\n", EXTENSION_MAP[i].extension_string);
781 gl_info->supported[EXTENSION_MAP[i].extension] = TRUE;
782 break;
783 }
784 }
785 }
786
787 LEAVE_GL();
788
789 /* Now work out what GL support this card really has */
790 #define USE_GL_FUNC(type, pfn, ext, replace) { \
791 DWORD ver = ver_for_ext(ext); \
792 if(gl_info->supported[ext]) gl_info->pfn = (type) pwglGetProcAddress(#pfn); \
793 else if(ver && ver <= gl_info->gl_version) gl_info->pfn = (type) pwglGetProcAddress(#replace); \
794 else gl_info->pfn = NULL; \
795 }
796 GL_EXT_FUNCS_GEN;
797 #undef USE_GL_FUNC
798
799 #define USE_GL_FUNC(type, pfn, ext, replace) gl_info->pfn = (type) pwglGetProcAddress(#pfn);
800 WGL_EXT_FUNCS_GEN;
801 #undef USE_GL_FUNC
802
803 ENTER_GL();
804 /* Now mark all the extensions supported which are included in the opengl core version. Do this *after*
805 * loading the functions, otherwise the code above will load the extension entry points instead of the
806 * core functions, which may not work
807 */
808 for (i = 0; i < (sizeof(EXTENSION_MAP) / sizeof(*EXTENSION_MAP)); ++i) {
809 if (gl_info->supported[EXTENSION_MAP[i].extension] == FALSE &&
810 EXTENSION_MAP[i].version <= gl_info->gl_version && EXTENSION_MAP[i].version) {
811 TRACE_(d3d_caps)(" GL CORE: %s support\n", EXTENSION_MAP[i].extension_string);
812 gl_info->supported[EXTENSION_MAP[i].extension] = TRUE;
813 }
814 }
815
816 if (gl_info->supported[APPLE_FENCE]) {
817 /* GL_NV_fence and GL_APPLE_fence provide the same functionality basically.
818 * The apple extension interacts with some other apple exts. Disable the NV
819 * extension if the apple one is support to prevent confusion in other parts
820 * of the code
821 */
822 gl_info->supported[NV_FENCE] = FALSE;
823 }
824 if (gl_info->supported[APPLE_FLOAT_PIXELS]) {
825 /* GL_APPLE_float_pixels == GL_ARB_texture_float + GL_ARB_half_float_pixel
826 *
827 * The enums are the same:
828 * GL_RGBA16F_ARB = GL_RGBA_FLOAT16_APPLE = 0x881A
829 * GL_RGB16F_ARB = GL_RGB_FLOAT16_APPLE = 0x881B
830 * GL_RGBA32F_ARB = GL_RGBA_FLOAT32_APPLE = 0x8814
831 * GL_RGB32F_ARB = GL_RGB_FLOAT32_APPLE = 0x8815
832 * GL_HALF_FLOAT_ARB = GL_HALF_APPLE = 0x140B
833 */
834 if(!gl_info->supported[ARB_TEXTURE_FLOAT]) {
835 TRACE_(d3d_caps)(" IMPLIED: GL_ARB_texture_float support(from GL_APPLE_float_pixels\n");
836 gl_info->supported[ARB_TEXTURE_FLOAT] = TRUE;
837 }
838 if(!gl_info->supported[ARB_HALF_FLOAT_PIXEL]) {
839 TRACE_(d3d_caps)(" IMPLIED: GL_ARB_half_float_pixel support(from GL_APPLE_float_pixels\n");
840 gl_info->supported[ARB_HALF_FLOAT_PIXEL] = TRUE;
841 }
842 }
843 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP]) {
844 TRACE_(d3d_caps)(" IMPLIED: NVIDIA (NV) Texture Gen Reflection support\n");
845 gl_info->supported[NV_TEXGEN_REFLECTION] = TRUE;
846 }
847 if (gl_info->supported[NV_TEXTURE_SHADER2]) {
848 if(gl_info->supported[NV_REGISTER_COMBINERS]) {
849 /* Also disable ATI_FRAGMENT_SHADER if register combiners and texture_shader2
850 * are supported. The nv extensions provide the same functionality as the
851 * ATI one, and a bit more(signed pixelformats)
852 */
853 gl_info->supported[ATI_FRAGMENT_SHADER] = FALSE;
854 }
855 }
856 if (gl_info->supported[ARB_DRAW_BUFFERS]) {
857 glGetIntegerv(GL_MAX_DRAW_BUFFERS_ARB, &gl_max);
858 gl_info->max_buffers = gl_max;
859 TRACE_(d3d_caps)("Max draw buffers: %u\n", gl_max);
860 }
861 if (gl_info->supported[ARB_MULTITEXTURE]) {
862 glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, &gl_max);
863 gl_info->max_textures = min(MAX_TEXTURES, gl_max);
864 TRACE_(d3d_caps)("Max textures: %d\n", gl_info->max_textures);
865
866 if (gl_info->supported[NV_REGISTER_COMBINERS]) {
867 GLint tmp;
868 glGetIntegerv(GL_MAX_GENERAL_COMBINERS_NV, &tmp);
869 gl_info->max_texture_stages = min(MAX_TEXTURES, tmp);
870 } else {
871 gl_info->max_texture_stages = min(MAX_TEXTURES, gl_max);
872 }
873 TRACE_(d3d_caps)("Max texture stages: %d\n", gl_info->max_texture_stages);
874
875 if (gl_info->supported[ARB_FRAGMENT_PROGRAM]) {
876 GLint tmp;
877 glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS_ARB, &tmp);
878 gl_info->max_fragment_samplers = min(MAX_FRAGMENT_SAMPLERS, tmp);
879 } else {
880 gl_info->max_fragment_samplers = max(gl_info->max_fragment_samplers, gl_max);
881 }
882 TRACE_(d3d_caps)("Max fragment samplers: %d\n", gl_info->max_fragment_samplers);
883
884 if (gl_info->supported[ARB_VERTEX_SHADER]) {
885 GLint tmp;
886 glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB, &tmp);
887 gl_info->max_vertex_samplers = tmp;
888 glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB, &tmp);
889 gl_info->max_combined_samplers = tmp;
890
891 /* Loading GLSL sampler uniforms is much simpler if we can assume that the sampler setup
892 * is known at shader link time. In a vertex shader + pixel shader combination this isn't
893 * an issue because then the sampler setup only depends on the two shaders. If a pixel
894 * shader is used with fixed function vertex processing we're fine too because fixed function
895 * vertex processing doesn't use any samplers. If fixed function fragment processing is
896 * used we have to make sure that all vertex sampler setups are valid together with all
897 * possible fixed function fragment processing setups. This is true if vsamplers + MAX_TEXTURES
898 * <= max_samplers. This is true on all d3d9 cards that support vtf(gf 6 and gf7 cards).
899 * dx9 radeon cards do not support vertex texture fetch. DX10 cards have 128 samplers, and
900 * dx9 is limited to 8 fixed function texture stages and 4 vertex samplers. DX10 does not have
901 * a fixed function pipeline anymore.
902 *
903 * So this is just a check to check that our assumption holds true. If not, write a warning
904 * and reduce the number of vertex samplers or probably disable vertex texture fetch.
905 */
906 if(gl_info->max_vertex_samplers &&
907 MAX_TEXTURES + gl_info->max_vertex_samplers > gl_info->max_combined_samplers) {
908 FIXME("OpenGL implementation supports %u vertex samplers and %u total samplers\n",
909 gl_info->max_vertex_samplers, gl_info->max_combined_samplers);
910 FIXME("Expected vertex samplers + MAX_TEXTURES(=8) > combined_samplers\n");
911 if( gl_info->max_combined_samplers > MAX_TEXTURES )
912 gl_info->max_vertex_samplers =
913 gl_info->max_combined_samplers - MAX_TEXTURES;
914 else
915 gl_info->max_vertex_samplers = 0;
916 }
917 } else {
918 gl_info->max_combined_samplers = gl_info->max_fragment_samplers;
919 }
920 TRACE_(d3d_caps)("Max vertex samplers: %u\n", gl_info->max_vertex_samplers);
921 TRACE_(d3d_caps)("Max combined samplers: %u\n", gl_info->max_combined_samplers);
922 }
923 if (gl_info->supported[ARB_VERTEX_BLEND]) {
924 glGetIntegerv(GL_MAX_VERTEX_UNITS_ARB, &gl_max);
925 gl_info->max_blends = gl_max;
926 TRACE_(d3d_caps)("Max blends: %u\n", gl_info->max_blends);
927 }
928 if (gl_info->supported[EXT_TEXTURE3D]) {
929 glGetIntegerv(GL_MAX_3D_TEXTURE_SIZE_EXT, &gl_max);
930 gl_info->max_texture3d_size = gl_max;
931 TRACE_(d3d_caps)("Max texture3D size: %d\n", gl_info->max_texture3d_size);
932 }
933 if (gl_info->supported[EXT_TEXTURE_FILTER_ANISOTROPIC]) {
934 glGetIntegerv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &gl_max);
935 gl_info->max_anisotropy = gl_max;
936 TRACE_(d3d_caps)("Max anisotropy: %d\n", gl_info->max_anisotropy);
937 }
938 if (gl_info->supported[ARB_FRAGMENT_PROGRAM]) {
939 gl_info->ps_arb_version = PS_VERSION_11;
940 GL_EXTCALL(glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_ENV_PARAMETERS_ARB, &gl_max));
941 gl_info->ps_arb_constantsF = gl_max;
942 TRACE_(d3d_caps)("Max ARB_FRAGMENT_PROGRAM float constants: %d\n", gl_info->ps_arb_constantsF);
943 GL_EXTCALL(glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB, &gl_max));
944 gl_info->ps_arb_max_temps = gl_max;
945 TRACE_(d3d_caps)("Max ARB_FRAGMENT_PROGRAM native temporaries: %d\n", gl_info->ps_arb_max_temps);
946 GL_EXTCALL(glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB, &gl_max));
947 gl_info->ps_arb_max_instructions = gl_max;
948 TRACE_(d3d_caps)("Max ARB_FRAGMENT_PROGRAM native instructions: %d\n", gl_info->ps_arb_max_instructions);
949 }
950 if (gl_info->supported[ARB_VERTEX_PROGRAM]) {
951 gl_info->vs_arb_version = VS_VERSION_11;
952 GL_EXTCALL(glGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_MAX_PROGRAM_ENV_PARAMETERS_ARB, &gl_max));
953 gl_info->vs_arb_constantsF = gl_max;
954 TRACE_(d3d_caps)("Max ARB_VERTEX_PROGRAM float constants: %d\n", gl_info->vs_arb_constantsF);
955 GL_EXTCALL(glGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB, &gl_max));
956 gl_info->vs_arb_max_temps = gl_max;
957 TRACE_(d3d_caps)("Max ARB_VERTEX_PROGRAM native temporaries: %d\n", gl_info->vs_arb_max_temps);
958 GL_EXTCALL(glGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB, &gl_max));
959 gl_info->vs_arb_max_instructions = gl_max;
960 TRACE_(d3d_caps)("Max ARB_VERTEX_PROGRAM native instructions: %d\n", gl_info->vs_arb_max_instructions);
961
962 gl_info->arb_vs_offset_limit = test_arb_vs_offset_limit(gl_info);
963 }
964 if (gl_info->supported[ARB_VERTEX_SHADER]) {
965 glGetIntegerv(GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB, &gl_max);
966 gl_info->vs_glsl_constantsF = gl_max / 4;
967 TRACE_(d3d_caps)("Max ARB_VERTEX_SHADER float constants: %u\n", gl_info->vs_glsl_constantsF);
968 }
969 if (gl_info->supported[ARB_FRAGMENT_SHADER]) {
970 glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB, &gl_max);
971 gl_info->ps_glsl_constantsF = gl_max / 4;
972 TRACE_(d3d_caps)("Max ARB_FRAGMENT_SHADER float constants: %u\n", gl_info->ps_glsl_constantsF);
973 glGetIntegerv(GL_MAX_VARYING_FLOATS_ARB, &gl_max);
974 gl_info->max_glsl_varyings = gl_max;
975 TRACE_(d3d_caps)("Max GLSL varyings: %u (%u 4 component varyings)\n", gl_max, gl_max / 4);
976 }
977 if (gl_info->supported[EXT_VERTEX_SHADER]) {
978 gl_info->vs_ati_version = VS_VERSION_11;
979 }
980 if (gl_info->supported[NV_VERTEX_PROGRAM3]) {
981 gl_info->vs_nv_version = VS_VERSION_30;
982 } else if (gl_info->supported[NV_VERTEX_PROGRAM2]) {
983 gl_info->vs_nv_version = VS_VERSION_20;
984 } else if (gl_info->supported[NV_VERTEX_PROGRAM1_1]) {
985 gl_info->vs_nv_version = VS_VERSION_11;
986 } else if (gl_info->supported[NV_VERTEX_PROGRAM]) {
987 gl_info->vs_nv_version = VS_VERSION_10;
988 }
989 if (gl_info->supported[NV_FRAGMENT_PROGRAM2]) {
990 gl_info->ps_nv_version = PS_VERSION_30;
991 } else if (gl_info->supported[NV_FRAGMENT_PROGRAM]) {
992 gl_info->ps_nv_version = PS_VERSION_20;
993 }
994 if (gl_info->supported[NV_LIGHT_MAX_EXPONENT]) {
995 glGetFloatv(GL_MAX_SHININESS_NV, &gl_info->max_shininess);
996 } else {
997 gl_info->max_shininess = 128.0;
998 }
999 if (gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO]) {
1000 /* If we have full NP2 texture support, disable GL_ARB_texture_rectangle because we will never use it.
1001 * This saves a few redundant glDisable calls
1002 */
1003 gl_info->supported[ARB_TEXTURE_RECTANGLE] = FALSE;
1004 }
1005 if(gl_info->supported[ATI_FRAGMENT_SHADER]) {
1006 /* Disable NV_register_combiners and fragment shader if this is supported.
1007 * generally the NV extensions are preferred over the ATI ones, and this
1008 * extension is disabled if register_combiners and texture_shader2 are both
1009 * supported. So we reach this place only if we have incomplete NV dxlevel 8
1010 * fragment processing support
1011 */
1012 gl_info->supported[NV_REGISTER_COMBINERS] = FALSE;
1013 gl_info->supported[NV_REGISTER_COMBINERS2] = FALSE;
1014 gl_info->supported[NV_TEXTURE_SHADER] = FALSE;
1015 gl_info->supported[NV_TEXTURE_SHADER2] = FALSE;
1016 gl_info->supported[NV_TEXTURE_SHADER3] = FALSE;
1017 }
1018
1019 }
1020 checkGLcall("extension detection\n");
1021
1022 /* In some cases the number of texture stages can be larger than the number
1023 * of samplers. The GF4 for example can use only 2 samplers (no fragment
1024 * shaders), but 8 texture stages (register combiners). */
1025 gl_info->max_sampler_stages = max(gl_info->max_fragment_samplers, gl_info->max_texture_stages);
1026
1027 /* We can only use ORM_FBO when the hardware supports it. */
1028 if (wined3d_settings.offscreen_rendering_mode == ORM_FBO && !gl_info->supported[EXT_FRAMEBUFFER_OBJECT]) {
1029 WARN_(d3d_caps)("GL_EXT_framebuffer_object not supported, falling back to PBuffer offscreen rendering mode.\n");
1030 wined3d_settings.offscreen_rendering_mode = ORM_PBUFFER;
1031 }
1032
1033 /* MRTs are currently only supported when FBOs are used. */
1034 if (wined3d_settings.offscreen_rendering_mode != ORM_FBO) {
1035 gl_info->max_buffers = 1;
1036 }
1037
1038 /* Below is a list of Nvidia and ATI GPUs. Both vendors have dozens of different GPUs with roughly the same
1039 * features. In most cases GPUs from a certain family differ in clockspeeds, the amount of video memory and
1040 * in case of the latest videocards in the number of pixel/vertex pipelines.
1041 *
1042 * A Direct3D device object contains the PCI id (vendor + device) of the videocard which is used for
1043 * rendering. Various games use this information to get a rough estimation of the features of the card
1044 * and some might use it for enabling 3d effects only on certain types of videocards. In some cases
1045 * games might even use it to work around bugs which happen on certain videocards/driver combinations.
1046 * The problem is that OpenGL only exposes a rendering string containing the name of the videocard and
1047 * not the PCI id.
1048 *
1049 * Various games depend on the PCI id, so somehow we need to provide one. A simple option is to parse
1050 * the renderer string and translate this to the right PCI id. This is a lot of work because there are more
1051 * than 200 GPUs just for Nvidia. Various cards share the same renderer string, so the amount of code might
1052 * be 'small' but there are quite a number of exceptions which would make this a pain to maintain.
1053 * Another way would be to query the PCI id from the operating system (assuming this is the videocard which
1054 * is used for rendering which is not always the case). This would work but it is not very portable. Second
1055 * it would not work well in, let's say, a remote X situation in which the amount of 3d features which can be used
1056 * is limited.
1057 *
1058 * As said most games only use the PCI id to get an indication of the capabilities of the card.
1059 * It doesn't really matter if the given id is the correct one if we return the id of a card with
1060 * similar 3d features.
1061 *
1062 * The code below checks the OpenGL capabilities of a videocard and matches that to a certain level of
1063 * Direct3D functionality. Once a card passes the Direct3D9 check, we know that the card (in case of Nvidia)
1064 * is at least a GeforceFX. To give a better estimate we do a basic check on the renderer string but if that
1065 * won't pass we return a default card. This way is better than maintaining a full card database as even
1066 * without a full database we can return a card with similar features. Second the size of the database
1067 * can be made quite small because when you know what type of 3d functionality a card has, you know to which
1068 * GPU family the GPU must belong. Because of this you only have to check a small part of the renderer string
1069 * to distinguishes between different models from that family.
1070 *
1071 * The code also selects a default amount of video memory which we will use for an estimation of the amount
1072 * of free texture memory. In case of real D3D the amount of texture memory includes video memory and system
1073 * memory (to be specific AGP memory or in case of PCIE TurboCache/HyperMemory). We don't know how much
1074 * system memory can be addressed by the system but we can make a reasonable estimation about the amount of
1075 * video memory. If the value is slightly wrong it doesn't matter as we didn't include AGP-like memory which
1076 * makes the amount of addressable memory higher and second OpenGL isn't that critical it moves to system
1077 * memory behind our backs if really needed.
1078 * Note that the amount of video memory can be overruled using a registry setting.
1079 */
1080 switch (gl_info->gl_vendor) {
1081 case VENDOR_NVIDIA:
1082 /* Both the GeforceFX, 6xxx and 7xxx series support D3D9. The last two types have more
1083 * shader capabilities, so we use the shader capabilities to distinguish between FX and 6xxx/7xxx.
1084 */
1085 if(WINE_D3D9_CAPABLE(gl_info) && (gl_info->vs_nv_version == VS_VERSION_30)) {
1086 /* Geforce GTX - highend */
1087 if(strstr(gl_info->gl_renderer, "GTX 280")) {
1088 gl_info->gl_card = CARD_NVIDIA_GEFORCE_GTX280;
1089 vidmem = 1024;
1090 }
1091 /* Geforce9 - highend */
1092 else if(strstr(gl_info->gl_renderer, "9800")) {
1093 gl_info->gl_card = CARD_NVIDIA_GEFORCE_9800GT;
1094 vidmem = 512;
1095 }
1096 /* Geforce9 - midend */
1097 else if(strstr(gl_info->gl_renderer, "9600")) {
1098 gl_info->gl_card = CARD_NVIDIA_GEFORCE_9600GT;
1099 vidmem = 384; /* The 9600GSO has 384MB, the 9600GT has 512-1024MB */
1100 }
1101 /* Geforce8 - highend */
1102 else if (strstr(gl_info->gl_renderer, "8800")) {
1103 gl_info->gl_card = CARD_NVIDIA_GEFORCE_8800GTS;
1104 vidmem = 320; /* The 8800GTS uses 320MB, a 8800GTX can have 768MB */
1105 }
1106 /* Geforce8 - midend mobile */
1107 else if(strstr(gl_info->gl_renderer, "8600 M")) {
1108 gl_info->gl_card = CARD_NVIDIA_GEFORCE_8600MGT;
1109 vidmem = 512;
1110 }
1111 /* Geforce8 - midend */
1112 else if(strstr(gl_info->gl_renderer, "8600") ||
1113 strstr(gl_info->gl_renderer, "8700"))
1114 {
1115 gl_info->gl_card = CARD_NVIDIA_GEFORCE_8600GT;
1116 vidmem = 256;
1117 }
1118 /* Geforce8 - lowend */
1119 else if(strstr(gl_info->gl_renderer, "8300") ||
1120 strstr(gl_info->gl_renderer, "8400") ||
1121 strstr(gl_info->gl_renderer, "8500"))
1122 {
1123 gl_info->gl_card = CARD_NVIDIA_GEFORCE_8300GS;
1124 vidmem = 128; /* 128-256MB for a 8300, 256-512MB for a 8400 */
1125 }
1126 /* Geforce7 - highend */
1127 else if(strstr(gl_info->gl_renderer, "7800") ||
1128 strstr(gl_info->gl_renderer, "7900") ||
1129 strstr(gl_info->gl_renderer, "7950") ||
1130 strstr(gl_info->gl_renderer, "Quadro FX 4") ||
1131 strstr(gl_info->gl_renderer, "Quadro FX 5"))
1132 {
1133 gl_info->gl_card = CARD_NVIDIA_GEFORCE_7800GT;
1134 vidmem = 256; /* A 7800GT uses 256MB while highend 7900 cards can use 512MB */
1135 }
1136 /* Geforce7 midend */
1137 else if(strstr(gl_info->gl_renderer, "7600") ||
1138 strstr(gl_info->gl_renderer, "7700")) {
1139 gl_info->gl_card = CARD_NVIDIA_GEFORCE_7600;
1140 vidmem = 256; /* The 7600 uses 256-512MB */
1141 /* Geforce7 lower medium */
1142 } else if(strstr(gl_info->gl_renderer, "7400")) {
1143 gl_info->gl_card = CARD_NVIDIA_GEFORCE_7400;
1144 vidmem = 256; /* The 7400 uses 256-512MB */
1145 }
1146 /* Geforce7 lowend */
1147 else if(strstr(gl_info->gl_renderer, "7300")) {
1148 gl_info->gl_card = CARD_NVIDIA_GEFORCE_7300;
1149 vidmem = 256; /* Mac Pros with this card have 256 MB */
1150 }
1151 /* Geforce6 highend */
1152 else if(strstr(gl_info->gl_renderer, "6800"))
1153 {
1154 gl_info->gl_card = CARD_NVIDIA_GEFORCE_6800;
1155 vidmem = 128; /* The 6800 uses 128-256MB, the 7600 uses 256-512MB */
1156 }
1157 /* Geforce6 - midend */
1158 else if(strstr(gl_info->gl_renderer, "6600") ||
1159 strstr(gl_info->gl_renderer, "6610") ||
1160 strstr(gl_info->gl_renderer, "6700"))
1161 {
1162 gl_info->gl_card = CARD_NVIDIA_GEFORCE_6600GT;
1163 vidmem = 128; /* A 6600GT has 128-256MB */
1164 }
1165 /* Geforce6/7 lowend */
1166 else {
1167 gl_info->gl_card = CARD_NVIDIA_GEFORCE_6200; /* Geforce 6100/6150/6200/7300/7400/7500 */
1168 vidmem = 64; /* */
1169 }
1170 } else if(WINE_D3D9_CAPABLE(gl_info)) {
1171 /* GeforceFX - highend */
1172 if (strstr(gl_info->gl_renderer, "5800") ||
1173 strstr(gl_info->gl_renderer, "5900") ||
1174 strstr(gl_info->gl_renderer, "5950") ||
1175 strstr(gl_info->gl_renderer, "Quadro FX"))
1176 {
1177 gl_info->gl_card = CARD_NVIDIA_GEFORCEFX_5800;
1178 vidmem = 256; /* 5800-5900 cards use 256MB */
1179 }
1180 /* GeforceFX - midend */
1181 else if(strstr(gl_info->gl_renderer, "5600") ||
1182 strstr(gl_info->gl_renderer, "5650") ||
1183 strstr(gl_info->gl_renderer, "5700") ||
1184 strstr(gl_info->gl_renderer, "5750"))
1185 {
1186 gl_info->gl_card = CARD_NVIDIA_GEFORCEFX_5600;
1187 vidmem = 128; /* A 5600 uses 128-256MB */
1188 }
1189 /* GeforceFX - lowend */
1190 else {
1191 gl_info->gl_card = CARD_NVIDIA_GEFORCEFX_5200; /* GeforceFX 5100/5200/5250/5300/5500 */
1192 vidmem = 64; /* Normal FX5200 cards use 64-256MB; laptop (non-standard) can have less */
1193 }
1194 } else if(WINE_D3D8_CAPABLE(gl_info)) {
1195 if (strstr(gl_info->gl_renderer, "GeForce4 Ti") || strstr(gl_info->gl_renderer, "Quadro4")) {
1196 gl_info->gl_card = CARD_NVIDIA_GEFORCE4_TI4200; /* Geforce4 Ti4200/Ti4400/Ti4600/Ti4800, Quadro4 */
1197 vidmem = 64; /* Geforce4 Ti cards have 64-128MB */
1198 }
1199 else {
1200 gl_info->gl_card = CARD_NVIDIA_GEFORCE3; /* Geforce3 standard/Ti200/Ti500, Quadro DCC */
1201 vidmem = 64; /* Geforce3 cards have 64-128MB */
1202 }
1203 } else if(WINE_D3D7_CAPABLE(gl_info)) {
1204 if (strstr(gl_info->gl_renderer, "GeForce4 MX")) {
1205 gl_info->gl_card = CARD_NVIDIA_GEFORCE4_MX; /* MX420/MX440/MX460/MX4000 */
1206 vidmem = 64; /* Most Geforce4MX GPUs have at least 64MB of memory, some early models had 32MB but most have 64MB or even 128MB */
1207 }
1208 else if(strstr(gl_info->gl_renderer, "GeForce2 MX") || strstr(gl_info->gl_renderer, "Quadro2 MXR")) {
1209 gl_info->gl_card = CARD_NVIDIA_GEFORCE2_MX; /* Geforce2 standard/MX100/MX200/MX400, Quadro2 MXR */
1210 vidmem = 32; /* Geforce2MX GPUs have 32-64MB of video memory */
1211 }
1212 else if(strstr(gl_info->gl_renderer, "GeForce2") || strstr(gl_info->gl_renderer, "Quadro2")) {
1213 gl_info->gl_card = CARD_NVIDIA_GEFORCE2; /* Geforce2 GTS/Pro/Ti/Ultra, Quadro2 */
1214 vidmem = 32; /* Geforce2 GPUs have 32-64MB of video memory */
1215 }
1216 else {
1217 gl_info->gl_card = CARD_NVIDIA_GEFORCE; /* Geforce 256/DDR, Quadro */
1218 vidmem = 32; /* Most Geforce1 cards have 32MB, there are also some rare 16 and 64MB (Dell) models */
1219 }
1220 } else {
1221 if (strstr(gl_info->gl_renderer, "TNT2")) {
1222 gl_info->gl_card = CARD_NVIDIA_RIVA_TNT2; /* Riva TNT2 standard/M64/Pro/Ultra */
1223 vidmem = 32; /* Most TNT2 boards have 32MB, though there are 16MB boards too */
1224 }
1225 else {
1226 gl_info->gl_card = CARD_NVIDIA_RIVA_TNT; /* Riva TNT, Vanta */
1227 vidmem = 16; /* Most TNT boards have 16MB, some rare models have 8MB */
1228 }
1229 }
1230 break;
1231 case VENDOR_ATI:
1232 if(WINE_D3D9_CAPABLE(gl_info)) {
1233 /* Radeon R6xx HD2900/HD3800 - highend */
1234 if (strstr(gl_info->gl_renderer, "HD 2900") ||
1235 strstr(gl_info->gl_renderer, "HD 3870") ||
1236 strstr(gl_info->gl_renderer, "HD 3850"))
1237 {
1238 gl_info->gl_card = CARD_ATI_RADEON_HD2900;
1239 vidmem = 512; /* HD2900/HD3800 uses 256-1024MB */
1240 }
1241 /* Radeon R6xx HD2600/HD3600 - midend; HD3830 is China-only midend */
1242 else if (strstr(gl_info->gl_renderer, "HD 2600") ||
1243 strstr(gl_info->gl_renderer, "HD 3830") ||
1244 strstr(gl_info->gl_renderer, "HD 3690") ||
1245 strstr(gl_info->gl_renderer, "HD 3650"))
1246 {
1247 gl_info->gl_card = CARD_ATI_RADEON_HD2600;
1248 vidmem = 256; /* HD2600/HD3600 uses 256-512MB */
1249 }
1250 /* Radeon R6xx HD2300/HD2400/HD3400 - lowend */
1251 else if (strstr(gl_info->gl_renderer, "HD 2300") ||
1252 strstr(gl_info->gl_renderer, "HD 2400") ||
1253 strstr(gl_info->gl_renderer, "HD 3470") ||
1254 strstr(gl_info->gl_renderer, "HD 3450") ||
1255 strstr(gl_info->gl_renderer, "HD 3430"))
1256 {
1257 gl_info->gl_card = CARD_ATI_RADEON_HD2300;
1258 vidmem = 128; /* HD2300 uses at least 128MB, HD2400 uses 256MB */
1259 }
1260 /* Radeon R6xx/R7xx integrated */
1261 else if (strstr(gl_info->gl_renderer, "HD 3100") ||
1262 strstr(gl_info->gl_renderer, "HD 3200") ||
1263 strstr(gl_info->gl_renderer, "HD 3300"))
1264 {
1265 gl_info->gl_card = CARD_ATI_RADEON_HD3200;
1266 vidmem = 128; /* 128MB */
1267 }
1268 /* Radeon R5xx */
1269 else if (strstr(gl_info->gl_renderer, "X1600") ||
1270 strstr(gl_info->gl_renderer, "X1650") ||
1271 strstr(gl_info->gl_renderer, "X1800") ||
1272 strstr(gl_info->gl_renderer, "X1900") ||
1273 strstr(gl_info->gl_renderer, "X1950"))
1274 {
1275 gl_info->gl_card = CARD_ATI_RADEON_X1600;
1276 vidmem = 128; /* X1600 uses 128-256MB, >=X1800 uses 256MB */
1277 }
1278 /* Radeon R4xx + X1300/X1400/X1450/X1550/X2300 (lowend R5xx) */
1279 else if(strstr(gl_info->gl_renderer, "X700") ||
1280 strstr(gl_info->gl_renderer, "X800") ||
1281 strstr(gl_info->gl_renderer, "X850") ||
1282 strstr(gl_info->gl_renderer, "X1300") ||
1283 strstr(gl_info->gl_renderer, "X1400") ||
1284 strstr(gl_info->gl_renderer, "X1450") ||
1285 strstr(gl_info->gl_renderer, "X1550"))
1286 {
1287 gl_info->gl_card = CARD_ATI_RADEON_X700;
1288 vidmem = 128; /* x700/x8*0 use 128-256MB, >=x1300 128-512MB */
1289 }
1290 /* Radeon Xpress Series - onboard, DX9b, Shader 2.0, 300-400MHz */
1291 else if(strstr(gl_info->gl_renderer, "Radeon Xpress"))
1292 {
1293 gl_info->gl_card = CARD_ATI_RADEON_XPRESS_200M;
1294 vidmem = 64; /* Shared RAM, BIOS configurable, 64-256M */
1295 }
1296 /* Radeon R3xx */
1297 else {
1298 gl_info->gl_card = CARD_ATI_RADEON_9500; /* Radeon 9500/9550/9600/9700/9800/X300/X550/X600 */
1299 vidmem = 64; /* Radeon 9500 uses 64MB, higher models use up to 256MB */
1300 }
1301 } else if(WINE_D3D8_CAPABLE(gl_info)) {
1302 gl_info->gl_card = CARD_ATI_RADEON_8500; /* Radeon 8500/9000/9100/9200/9300 */
1303 vidmem = 64; /* 8500/9000 cards use mostly 64MB, though there are 32MB and 128MB models */
1304 } else if(WINE_D3D7_CAPABLE(gl_info)) {
1305 gl_info->gl_card = CARD_ATI_RADEON_7200; /* Radeon 7000/7100/7200/7500 */
1306 vidmem = 32; /* There are models with up to 64MB */
1307 } else {
1308 gl_info->gl_card = CARD_ATI_RAGE_128PRO;
1309 vidmem = 16; /* There are 16-32MB models */
1310 }
1311 break;
1312 case VENDOR_INTEL:
1313 if (strstr(gl_info->gl_renderer, "GMA 950") ||
1314 strstr(gl_info->gl_renderer, "945GM")) {
1315 /* MacOS calls the card GMA 950, but everywhere else the PCI ID is named 945GM */
1316 gl_info->gl_card = CARD_INTEL_I945GM;
1317 vidmem = 64;
1318 } else if (strstr(gl_info->gl_renderer, "915GM")) {
1319 gl_info->gl_card = CARD_INTEL_I915GM;
1320 } else if (strstr(gl_info->gl_renderer, "915G")) {
1321 gl_info->gl_card = CARD_INTEL_I915G;
1322 } else if (strstr(gl_info->gl_renderer, "865G")) {
1323 gl_info->gl_card = CARD_INTEL_I865G;
1324 } else if (strstr(gl_info->gl_renderer, "855G")) {
1325 gl_info->gl_card = CARD_INTEL_I855G;
1326 } else if (strstr(gl_info->gl_renderer, "830G")) {
1327 gl_info->gl_card = CARD_INTEL_I830G;
1328 } else {
1329 gl_info->gl_card = CARD_INTEL_I915G;
1330 }
1331 break;
1332 case VENDOR_MESA:
1333 case VENDOR_WINE:
1334 default:
1335 /* Default to generic Nvidia hardware based on the supported OpenGL extensions. The choice
1336 * for Nvidia was because the hardware and drivers they make are of good quality. This makes
1337 * them a good generic choice.
1338 */
1339 gl_info->gl_vendor = VENDOR_NVIDIA;
1340 if(WINE_D3D9_CAPABLE(gl_info))
1341 gl_info->gl_card = CARD_NVIDIA_GEFORCEFX_5600;
1342 else if(WINE_D3D8_CAPABLE(gl_info))
1343 gl_info->gl_card = CARD_NVIDIA_GEFORCE3;
1344 else if(WINE_D3D7_CAPABLE(gl_info))
1345 gl_info->gl_card = CARD_NVIDIA_GEFORCE;
1346 else if(WINE_D3D6_CAPABLE(gl_info))
1347 gl_info->gl_card = CARD_NVIDIA_RIVA_TNT;
1348 else
1349 gl_info->gl_card = CARD_NVIDIA_RIVA_128;
1350 }
1351 TRACE_(d3d_caps)("FOUND (fake) card: 0x%x (vendor id), 0x%x (device id)\n", gl_info->gl_vendor, gl_info->gl_card);
1352
1353 /* If we have an estimate use it, else default to 64MB; */
1354 if(vidmem)
1355 gl_info->vidmem = vidmem*1024*1024; /* convert from MBs to bytes */
1356 else
1357 gl_info->vidmem = WINE_DEFAULT_VIDMEM;
1358
1359 /* Load all the lookup tables */
1360 for (i = 0; i < MAX_LOOKUPS; i++) {
1361 stateLookup[i] = HeapAlloc(GetProcessHeap(), 0, sizeof(*stateLookup[i]) * (1 + maxLookup[i] - minLookup[i]) );
1362 }
1363
1364 stateLookup[WINELOOKUP_WARPPARAM][WINED3DTADDRESS_WRAP - minLookup[WINELOOKUP_WARPPARAM]] = GL_REPEAT;
1365 stateLookup[WINELOOKUP_WARPPARAM][WINED3DTADDRESS_CLAMP - minLookup[WINELOOKUP_WARPPARAM]] = GL_CLAMP_TO_EDGE;
1366 stateLookup[WINELOOKUP_WARPPARAM][WINED3DTADDRESS_BORDER - minLookup[WINELOOKUP_WARPPARAM]] =
1367 gl_info->supported[ARB_TEXTURE_BORDER_CLAMP] ? GL_CLAMP_TO_BORDER_ARB : GL_REPEAT;
1368 stateLookup[WINELOOKUP_WARPPARAM][WINED3DTADDRESS_BORDER - minLookup[WINELOOKUP_WARPPARAM]] =
1369 gl_info->supported[ARB_TEXTURE_BORDER_CLAMP] ? GL_CLAMP_TO_BORDER_ARB : GL_REPEAT;
1370 stateLookup[WINELOOKUP_WARPPARAM][WINED3DTADDRESS_MIRROR - minLookup[WINELOOKUP_WARPPARAM]] =
1371 gl_info->supported[ARB_TEXTURE_MIRRORED_REPEAT] ? GL_MIRRORED_REPEAT_ARB : GL_REPEAT;
1372 stateLookup[WINELOOKUP_WARPPARAM][WINED3DTADDRESS_MIRRORONCE - minLookup[WINELOOKUP_WARPPARAM]] =
1373 gl_info->supported[ATI_TEXTURE_MIRROR_ONCE] ? GL_MIRROR_CLAMP_TO_EDGE_ATI : GL_REPEAT;
1374
1375 magLookup[WINED3DTEXF_NONE - WINED3DTEXF_NONE] = GL_NEAREST;
1376 magLookup[WINED3DTEXF_POINT - WINED3DTEXF_NONE] = GL_NEAREST;
1377 magLookup[WINED3DTEXF_LINEAR - WINED3DTEXF_NONE] = GL_LINEAR;
1378 magLookup[WINED3DTEXF_ANISOTROPIC - WINED3DTEXF_NONE] =
1379 gl_info->supported[EXT_TEXTURE_FILTER_ANISOTROPIC] ? GL_LINEAR : GL_NEAREST;
1380
1381
1382 minMipLookup[WINED3DTEXF_NONE].mip[WINED3DTEXF_NONE] = GL_LINEAR;
1383 minMipLookup[WINED3DTEXF_NONE].mip[WINED3DTEXF_POINT] = GL_LINEAR;
1384 minMipLookup[WINED3DTEXF_NONE].mip[WINED3DTEXF_LINEAR] = GL_LINEAR;
1385 minMipLookup[WINED3DTEXF_POINT].mip[WINED3DTEXF_NONE] = GL_NEAREST;
1386 minMipLookup[WINED3DTEXF_POINT].mip[WINED3DTEXF_POINT] = GL_NEAREST_MIPMAP_NEAREST;
1387 minMipLookup[WINED3DTEXF_POINT].mip[WINED3DTEXF_LINEAR] = GL_NEAREST_MIPMAP_LINEAR;
1388 minMipLookup[WINED3DTEXF_LINEAR].mip[WINED3DTEXF_NONE] = GL_LINEAR;
1389 minMipLookup[WINED3DTEXF_LINEAR].mip[WINED3DTEXF_POINT] = GL_LINEAR_MIPMAP_NEAREST;
1390 minMipLookup[WINED3DTEXF_LINEAR].mip[WINED3DTEXF_LINEAR] = GL_LINEAR_MIPMAP_LINEAR;
1391 minMipLookup[WINED3DTEXF_ANISOTROPIC].mip[WINED3DTEXF_NONE]
1392 = gl_info->supported[EXT_TEXTURE_FILTER_ANISOTROPIC] ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR;
1393 minMipLookup[WINED3DTEXF_ANISOTROPIC].mip[WINED3DTEXF_POINT]
1394 = gl_info->supported[EXT_TEXTURE_FILTER_ANISOTROPIC] ? GL_LINEAR_MIPMAP_NEAREST : GL_LINEAR;
1395 minMipLookup[WINED3DTEXF_ANISOTROPIC].mip[WINED3DTEXF_LINEAR]
1396 = gl_info->supported[EXT_TEXTURE_FILTER_ANISOTROPIC] ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR;
1397
1398 /* TODO: config lookups */
1399
1400 /* Make sure there's an active HDC else the WGL extensions will fail */
1401 hdc = pwglGetCurrentDC();
1402 if (hdc) {
1403 WGL_Extensions = GL_EXTCALL(wglGetExtensionsStringARB(hdc));
1404 TRACE_(d3d_caps)("WGL_Extensions reported:\n");
1405
1406 if (NULL == WGL_Extensions) {
1407 ERR(" WGL_Extensions returns NULL\n");
1408 } else {
1409 while (*WGL_Extensions != 0x00) {
1410 const char *Start;
1411 char ThisExtn[256];
1412 size_t len;
1413
1414 while (isspace(*WGL_Extensions)) WGL_Extensions++;
1415 Start = WGL_Extensions;
1416 while (!isspace(*WGL_Extensions) && *WGL_Extensions != 0x00) {
1417 WGL_Extensions++;
1418 }
1419
1420 len = WGL_Extensions - Start;
1421 if (len == 0 || len >= sizeof(ThisExtn))
1422 continue;
1423
1424 memcpy(ThisExtn, Start, len);
1425 ThisExtn[len] = '\0';
1426 TRACE_(d3d_caps)("- %s\n", ThisExtn);
1427
1428 if (!strcmp(ThisExtn, "WGL_ARB_pbuffer")) {
1429 gl_info->supported[WGL_ARB_PBUFFER] = TRUE;
1430 TRACE_(d3d_caps)("FOUND: WGL_ARB_pbuffer support\n");
1431 }
1432 if (!strcmp(ThisExtn, "WGL_WINE_pixel_format_passthrough")) {
1433 gl_info->supported[WGL_WINE_PIXEL_FORMAT_PASSTHROUGH] = TRUE;
1434 TRACE_(d3d_caps)("FOUND: WGL_WINE_pixel_format_passthrough support\n");
1435 }
1436 }
1437 }
1438 }
1439 LEAVE_GL();
1440
1441 return return_value;
1442 }
1443 #undef GLINFO_LOCATION
1444
1445 /**********************************************************
1446 * IWineD3D implementation follows
1447 **********************************************************/
1448
1449 static UINT WINAPI IWineD3DImpl_GetAdapterCount (IWineD3D *iface) {
1450 IWineD3DImpl *This = (IWineD3DImpl *)iface;
1451
1452 TRACE_(d3d_caps)("(%p): Reporting %d adapters\n", This, numAdapters);
1453 return numAdapters;
1454 }
1455
1456 static HRESULT WINAPI IWineD3DImpl_RegisterSoftwareDevice(IWineD3D *iface, void* pInitializeFunction) {
1457 IWineD3DImpl *This = (IWineD3DImpl *)iface;
1458 FIXME("(%p)->(%p): stub\n", This, pInitializeFunction);
1459 return WINED3D_OK;
1460 }
1461
1462 static HMONITOR WINAPI IWineD3DImpl_GetAdapterMonitor(IWineD3D *iface, UINT Adapter) {
1463 IWineD3DImpl *This = (IWineD3DImpl *)iface;
1464
1465 TRACE_(d3d_caps)("(%p)->(%d)\n", This, Adapter);
1466
1467 if (Adapter >= IWineD3DImpl_GetAdapterCount(iface)) {
1468 return NULL;
1469 }
1470
1471 return MonitorFromPoint(Adapters[Adapter].monitorPoint, MONITOR_DEFAULTTOPRIMARY);
1472 }
1473
1474 /* FIXME: GetAdapterModeCount and EnumAdapterModes currently only returns modes
1475 of the same bpp but different resolutions */
1476
1477 /* Note: dx9 supplies a format. Calls from d3d8 supply WINED3DFMT_UNKNOWN */
1478 static UINT WINAPI IWineD3DImpl_GetAdapterModeCount(IWineD3D *iface, UINT Adapter, WINED3DFORMAT Format) {
1479 IWineD3DImpl *This = (IWineD3DImpl *)iface;
1480 TRACE_(d3d_caps)("(%p}->(Adapter: %d, Format: %s)\n", This, Adapter, debug_d3dformat(Format));
1481
1482 if (Adapter >= IWineD3D_GetAdapterCount(iface)) {
1483 return 0;
1484 }
1485
1486 /* TODO: Store modes per adapter and read it from the adapter structure */
1487 if (Adapter == 0) { /* Display */
1488 int i = 0;
1489 int j = 0;
1490
1491 if (!DEBUG_SINGLE_MODE) {
1492 DEVMODEW DevModeW;
1493
1494 ZeroMemory(&DevModeW, sizeof(DevModeW));
1495 DevModeW.dmSize = sizeof(DevModeW);
1496 while (EnumDisplaySettingsExW(NULL, j, &DevModeW, 0)) {
1497 j++;
1498 switch (Format)
1499 {
1500 case WINED3DFMT_UNKNOWN:
1501 /* This is for D3D8, do not enumerate P8 here */
1502 if (DevModeW.dmBitsPerPel == 32 ||
1503 DevModeW.dmBitsPerPel == 16) i++;
1504 break;
1505 case WINED3DFMT_X8R8G8B8:
1506 if (DevModeW.dmBitsPerPel == 32) i++;
1507 break;
1508 case WINED3DFMT_R5G6B5:
1509 if (DevModeW.dmBitsPerPel == 16) i++;
1510 break;
1511 case WINED3DFMT_P8:
1512 if (DevModeW.dmBitsPerPel == 8) i++;
1513 break;
1514 default:
1515 /* Skip other modes as they do not match the requested format */
1516 break;
1517 }
1518 }
1519 } else {
1520 i = 1;
1521 j = 1;
1522 }
1523
1524 TRACE_(d3d_caps)("(%p}->(Adapter: %d) => %d (out of %d)\n", This, Adapter, i, j);
1525 return i;
1526 } else {
1527 FIXME_(d3d_caps)("Adapter not primary display\n");
1528 }
1529 return 0;
1530 }
1531
1532 /* Note: dx9 supplies a format. Calls from d3d8 supply WINED3DFMT_UNKNOWN */
1533 static HRESULT WINAPI IWineD3DImpl_EnumAdapterModes(IWineD3D *iface, UINT Adapter, WINED3DFORMAT Format, UINT Mode, WINED3DDISPLAYMODE* pMode) {
1534 IWineD3DImpl *This = (IWineD3DImpl *)iface;
1535 TRACE_(d3d_caps)("(%p}->(Adapter:%d, mode:%d, pMode:%p, format:%s)\n", This, Adapter, Mode, pMode, debug_d3dformat(Format));
1536
1537 /* Validate the parameters as much as possible */
1538 if (NULL == pMode ||
1539 Adapter >= IWineD3DImpl_GetAdapterCount(iface) ||
1540 Mode >= IWineD3DImpl_GetAdapterModeCount(iface, Adapter, Format)) {
1541 return WINED3DERR_INVALIDCALL;
1542 }
1543
1544 /* TODO: Store modes per adapter and read it from the adapter structure */
1545 if (Adapter == 0 && !DEBUG_SINGLE_MODE) { /* Display */
1546 DEVMODEW DevModeW;
1547 int ModeIdx = 0;
1548 UINT i = 0;
1549 int j = 0;
1550
1551 ZeroMemory(&DevModeW, sizeof(DevModeW));
1552 DevModeW.dmSize = sizeof(DevModeW);
1553
1554 /* If we are filtering to a specific format (D3D9), then need to skip
1555 all unrelated modes, but if mode is irrelevant (D3D8), then we can
1556 just count through the ones with valid bit depths */
1557 while ((i<=Mode) && EnumDisplaySettingsExW(NULL, j++, &DevModeW, 0)) {
1558 switch (Format)
1559 {
1560 case WINED3DFMT_UNKNOWN:
1561 /* This is D3D8. Do not enumerate P8 here */
1562 if (DevModeW.dmBitsPerPel == 32 ||
1563 DevModeW.dmBitsPerPel == 16) i++;
1564 break;
1565 case WINED3DFMT_X8R8G8B8:
1566 if (DevModeW.dmBitsPerPel == 32) i++;
1567 break;
1568 case WINED3DFMT_R5G6B5:
1569 if (DevModeW.dmBitsPerPel == 16) i++;
1570 break;
1571 case WINED3DFMT_P8:
1572 if (DevModeW.dmBitsPerPel == 8) i++;
1573 break;
1574 default:
1575 /* Modes that don't match what we support can get an early-out */
1576 TRACE_(d3d_caps)("Searching for %s, returning D3DERR_INVALIDCALL\n", debug_d3dformat(Format));
1577 return WINED3DERR_INVALIDCALL;
1578 }
1579 }
1580
1581 if (i == 0) {
1582 TRACE_(d3d_caps)("No modes found for format (%x - %s)\n", Format, debug_d3dformat(Format));
1583 return WINED3DERR_INVALIDCALL;
1584 }
1585 ModeIdx = j - 1;
1586
1587 /* Now get the display mode via the calculated index */
1588 if (EnumDisplaySettingsExW(NULL, ModeIdx, &DevModeW, 0)) {
1589 pMode->Width = DevModeW.dmPelsWidth;
1590 pMode->Height = DevModeW.dmPelsHeight;
1591 pMode->RefreshRate = WINED3DADAPTER_DEFAULT;
1592 if (DevModeW.dmFields & DM_DISPLAYFREQUENCY)
1593 pMode->RefreshRate = DevModeW.dmDisplayFrequency;
1594
1595 if (Format == WINED3DFMT_UNKNOWN) {
1596 pMode->Format = pixelformat_for_depth(DevModeW.dmBitsPerPel);
1597 } else {
1598 pMode->Format = Format;
1599 }
1600 } else {
1601 TRACE_(d3d_caps)("Requested mode out of range %d\n", Mode);
1602 return WINED3DERR_INVALIDCALL;
1603 }
1604
1605 TRACE_(d3d_caps)("W %d H %d rr %d fmt (%x - %s) bpp %u\n", pMode->Width, pMode->Height,
1606 pMode->RefreshRate, pMode->Format, debug_d3dformat(pMode->Format),
1607 DevModeW.dmBitsPerPel);
1608
1609 } else if (DEBUG_SINGLE_MODE) {
1610 /* Return one setting of the format requested */
1611 if (Mode > 0) return WINED3DERR_INVALIDCALL;
1612 pMode->Width = 800;
1613 pMode->Height = 600;
1614 pMode->RefreshRate = 60;
1615 pMode->Format = (Format == WINED3DFMT_UNKNOWN) ? WINED3DFMT_X8R8G8B8 : Format;
1616 } else {
1617 FIXME_(d3d_caps)("Adapter not primary display\n");
1618 }
1619
1620 return WINED3D_OK;
1621 }
1622
1623 static HRESULT WINAPI IWineD3DImpl_GetAdapterDisplayMode(IWineD3D *iface, UINT Adapter, WINED3DDISPLAYMODE* pMode) {
1624 IWineD3DImpl *This = (IWineD3DImpl *)iface;
1625 TRACE_(d3d_caps)("(%p}->(Adapter: %d, pMode: %p)\n", This, Adapter, pMode);
1626
1627 if (NULL == pMode ||
1628 Adapter >= IWineD3D_GetAdapterCount(iface)) {
1629 return WINED3DERR_INVALIDCALL;
1630 }
1631
1632 if (Adapter == 0) { /* Display */
1633 int bpp = 0;
1634 DEVMODEW DevModeW;
1635
1636 ZeroMemory(&DevModeW, sizeof(DevModeW));
1637 DevModeW.dmSize = sizeof(DevModeW);
1638
1639 EnumDisplaySettingsExW(NULL, ENUM_CURRENT_SETTINGS, &DevModeW, 0);
1640 pMode->Width = DevModeW.dmPelsWidth;
1641 pMode->Height = DevModeW.dmPelsHeight;
1642 bpp = DevModeW.dmBitsPerPel;
1643 pMode->RefreshRate = WINED3DADAPTER_DEFAULT;
1644 if (DevModeW.dmFields&DM_DISPLAYFREQUENCY)
1645 {
1646 pMode->RefreshRate = DevModeW.dmDisplayFrequency;
1647 }
1648
1649 pMode->Format = pixelformat_for_depth(bpp);
1650 } else {
1651 FIXME_(d3d_caps)("Adapter not primary display\n");
1652 }
1653
1654 TRACE_(d3d_caps)("returning w:%d, h:%d, ref:%d, fmt:%s\n", pMode->Width,
1655 pMode->Height, pMode->RefreshRate, debug_d3dformat(pMode->Format));
1656 return WINED3D_OK;
1657 }
1658
1659 /* NOTE: due to structure differences between dx8 and dx9 D3DADAPTER_IDENTIFIER,
1660 and fields being inserted in the middle, a new structure is used in place */
1661 static HRESULT WINAPI IWineD3DImpl_GetAdapterIdentifier(IWineD3D *iface, UINT Adapter, DWORD Flags,
1662 WINED3DADAPTER_IDENTIFIER* pIdentifier) {
1663 IWineD3DImpl *This = (IWineD3DImpl *)iface;
1664
1665 TRACE_(d3d_caps)("(%p}->(Adapter: %d, Flags: %x, pId=%p)\n", This, Adapter, Flags, pIdentifier);
1666
1667 if (Adapter >= IWineD3D_GetAdapterCount(iface)) {
1668 return WINED3DERR_INVALIDCALL;
1669 }
1670
1671 /* Return the information requested */
1672 TRACE_(d3d_caps)("device/Vendor Name and Version detection using FillGLCaps\n");
1673 strcpy(pIdentifier->Driver, Adapters[Adapter].driver);
1674 strcpy(pIdentifier->Description, Adapters[Adapter].description);
1675
1676 /* Note dx8 doesn't supply a DeviceName */
1677 if (NULL != pIdentifier->DeviceName) strcpy(pIdentifier->DeviceName, "\\\\.\\DISPLAY"); /* FIXME: May depend on desktop? */
1678 pIdentifier->DriverVersion->u.HighPart = Adapters[Adapter].gl_info.driver_version_hipart;
1679 pIdentifier->DriverVersion->u.LowPart = Adapters[Adapter].gl_info.driver_version;
1680 *(pIdentifier->VendorId) = Adapters[Adapter].gl_info.gl_vendor;
1681 *(pIdentifier->DeviceId) = Adapters[Adapter].gl_info.gl_card;
1682 *(pIdentifier->SubSysId) = 0;
1683 *(pIdentifier->Revision) = 0;
1684 *pIdentifier->DeviceIdentifier = IID_D3DDEVICE_D3DUID;
1685
1686 if(wined3d_settings.pci_device_id != PCI_DEVICE_NONE)
1687 {
1688 TRACE_(d3d_caps)("Overriding pci device id with: %x\n", wined3d_settings.pci_device_id);
1689 *(pIdentifier->DeviceId) = wined3d_settings.pci_device_id;
1690 }
1691
1692 if(wined3d_settings.pci_vendor_id != PCI_VENDOR_NONE)
1693 {
1694 TRACE_(d3d_caps)("Overriding pci vendor id with: %x\n", wined3d_settings.pci_vendor_id);
1695 *(pIdentifier->VendorId) = wined3d_settings.pci_vendor_id;
1696 }
1697
1698 if (Flags & WINED3DENUM_NO_WHQL_LEVEL) {
1699 *(pIdentifier->WHQLLevel) = 0;
1700 } else {
1701 *(pIdentifier->WHQLLevel) = 1;
1702 }
1703
1704 return WINED3D_OK;
1705 }
1706
1707 static BOOL IWineD3DImpl_IsPixelFormatCompatibleWithRenderFmt(const WineD3D_PixelFormat *cfg, WINED3DFORMAT Format) {
1708 short redSize, greenSize, blueSize, alphaSize, colorBits;
1709
1710 if(!cfg)
1711 return FALSE;
1712
1713 if(cfg->iPixelType == WGL_TYPE_RGBA_ARB) { /* Integer RGBA formats */
1714 if(!getColorBits(Format, &redSize, &greenSize, &blueSize, &alphaSize, &colorBits)) {
1715 ERR("Unable to check compatibility for Format=%s\n", debug_d3dformat(Format));
1716 return FALSE;
1717 }
1718
1719 if(cfg->redSize < redSize)
1720 return FALSE;
1721
1722 if(cfg->greenSize < greenSize)
1723 return FALSE;
1724
1725 if(cfg->blueSize < blueSize)
1726 return FALSE;
1727
1728 if(cfg->alphaSize < alphaSize)
1729 return FALSE;
1730
1731 return TRUE;
1732 } else if(cfg->iPixelType == WGL_TYPE_RGBA_FLOAT_ARB) { /* Float RGBA formats; TODO: WGL_NV_float_buffer */
1733 if(Format == WINED3DFMT_R16F)
1734 return (cfg->redSize == 16 && cfg->greenSize == 0 && cfg->blueSize == 0 && cfg->alphaSize == 0);
1735 if(Format == WINED3DFMT_G16R16F)
1736 return (cfg->redSize == 16 && cfg->greenSize == 16 && cfg->blueSize == 0 && cfg->alphaSize == 0);
1737 if(Format == WINED3DFMT_A16B16G16R16F)
1738 return (cfg->redSize == 16 && cfg->greenSize == 16 && cfg->blueSize == 16 && cfg->alphaSize == 16);
1739 if(Format == WINED3DFMT_R32F)
1740 return (cfg->redSize == 32 && cfg->greenSize == 0 && cfg->blueSize == 0 && cfg->alphaSize == 0);
1741 if(Format == WINED3DFMT_G32R32F)
1742 return (cfg->redSize == 32 && cfg->greenSize == 32 && cfg->blueSize == 0 && cfg->alphaSize == 0);
1743 if(Format == WINED3DFMT_A32B32G32R32F)
1744 return (cfg->redSize == 32 && cfg->greenSize == 32 && cfg->blueSize == 32 && cfg->alphaSize == 32);
1745 } else {
1746 /* Probably a color index mode */
1747 return FALSE;
1748 }
1749
1750 return FALSE;
1751 }
1752
1753 static BOOL IWineD3DImpl_IsPixelFormatCompatibleWithDepthFmt(const WineD3D_PixelFormat *cfg, WINED3DFORMAT Format) {
1754 short depthSize, stencilSize;
1755 BOOL lockable = FALSE;
1756
1757 if(!cfg)
1758 return FALSE;
1759
1760 if(!getDepthStencilBits(Format, &depthSize, &stencilSize)) {
1761 ERR("Unable to check compatibility for Format=%s\n", debug_d3dformat(Format));
1762 return FALSE;
1763 }
1764
1765 if((Format == WINED3DFMT_D16_LOCKABLE) || (Format == WINED3DFMT_D32F_LOCKABLE))
1766 lockable = TRUE;
1767
1768 /* On some modern cards like the Geforce8/9 GLX doesn't offer some dephthstencil formats which D3D9 reports.
1769 * We can safely report 'compatible' formats (e.g. D24 can be used for D16) as long as we aren't dealing with
1770 * a lockable format. This also helps D3D <= 7 as they expect D16 which isn't offered without this on Geforce8 cards. */
1771 if(!(cfg->depthSize == depthSize || (!lockable && cfg->depthSize > depthSize)))
1772 return FALSE;
1773
1774 /* Some cards like Intel i915 ones only offer D24S8 but lots of games also need a format without stencil, so
1775 * allow more stencil bits than requested. */
1776 if(cfg->stencilSize < stencilSize)
1777 return FALSE;
1778
1779 return TRUE;
1780 }
1781
1782 static HRESULT WINAPI IWineD3DImpl_CheckDepthStencilMatch(IWineD3D *iface, UINT Adapter, WINED3DDEVTYPE DeviceType,
1783 WINED3DFORMAT AdapterFormat,
1784 WINED3DFORMAT RenderTargetFormat,
1785 WINED3DFORMAT DepthStencilFormat) {
1786 IWineD3DImpl *This = (IWineD3DImpl *)iface;
1787 int nCfgs;
1788 const WineD3D_PixelFormat *cfgs;
1789 int it;
1790
1791 WARN_(d3d_caps)("(%p)-> (STUB) (Adptr:%d, DevType:(%x,%s), AdptFmt:(%x,%s), RendrTgtFmt:(%x,%s), DepthStencilFmt:(%x,%s))\n",
1792 This, Adapter,
1793 DeviceType, debug_d3ddevicetype(DeviceType),
1794 AdapterFormat, debug_d3dformat(AdapterFormat),
1795 RenderTargetFormat, debug_d3dformat(RenderTargetFormat),
1796 DepthStencilFormat, debug_d3dformat(DepthStencilFormat));
1797
1798 if (Adapter >= IWineD3D_GetAdapterCount(iface)) {
1799 TRACE("(%p) Failed: Atapter (%u) higher than supported adapters (%u) returning WINED3DERR_INVALIDCALL\n", This, Adapter, IWineD3D_GetAdapterCount(iface));
1800 return WINED3DERR_INVALIDCALL;
1801 }
1802
1803 cfgs = Adapters[Adapter].cfgs;
1804 nCfgs = Adapters[Adapter].nCfgs;
1805 for (it = 0; it < nCfgs; ++it) {
1806 if (IWineD3DImpl_IsPixelFormatCompatibleWithRenderFmt(&cfgs[it], RenderTargetFormat)) {
1807 if (IWineD3DImpl_IsPixelFormatCompatibleWithDepthFmt(&cfgs[it], DepthStencilFormat)) {
1808 TRACE_(d3d_caps)("(%p) : Formats matched\n", This);
1809 return WINED3D_OK;
1810 }
1811 }
1812 }
1813 WARN_(d3d_caps)("unsupported format pair: %s and %s\n", debug_d3dformat(RenderTargetFormat), debug_d3dformat(DepthStencilFormat));
1814
1815 return WINED3DERR_NOTAVAILABLE;
1816 }
1817
1818 static HRESULT WINAPI IWineD3DImpl_CheckDeviceMultiSampleType(IWineD3D *iface, UINT Adapter, WINED3DDEVTYPE DeviceType,
1819 WINED3DFORMAT SurfaceFormat,
1820 BOOL Windowed, WINED3DMULTISAMPLE_TYPE MultiSampleType, DWORD* pQualityLevels) {
1821
1822 IWineD3DImpl *This = (IWineD3DImpl *)iface;
1823 const struct GlPixelFormatDesc *glDesc;
1824 const StaticPixelFormatDesc *desc;
1825
1826 TRACE_(d3d_caps)("(%p)-> (Adptr:%d, DevType:(%x,%s), SurfFmt:(%x,%s), Win?%d, MultiSamp:%x, pQual:%p)\n",
1827 This,
1828 Adapter,
1829 DeviceType, debug_d3ddevicetype(DeviceType),
1830 SurfaceFormat, debug_d3dformat(SurfaceFormat),
1831 Windowed,
1832 MultiSampleType,
1833 pQualityLevels);
1834
1835 if (Adapter >= IWineD3D_GetAdapterCount(iface)) {
1836 return WINED3DERR_INVALIDCALL;
1837 }
1838
1839 /* TODO: handle Windowed, add more quality levels */
1840
1841 if (WINED3DMULTISAMPLE_NONE == MultiSampleType) return WINED3D_OK;
1842
1843 /* By default multisampling is disabled right now as it causes issues
1844 * on some Nvidia driver versions and it doesn't work well in combination
1845 * with FBOs yet. */
1846 if(!wined3d_settings.allow_multisampling)
1847 return WINED3DERR_NOTAVAILABLE;
1848
1849 desc = getFormatDescEntry(SurfaceFormat, &Adapters[Adapter].gl_info, &glDesc);
1850 if(!desc || !glDesc) {
1851 return WINED3DERR_INVALIDCALL;
1852 }
1853
1854 if(glDesc->Flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL)) {
1855 int i, nCfgs;
1856 const WineD3D_PixelFormat *cfgs;
1857
1858 cfgs = Adapters[Adapter].cfgs;
1859 nCfgs = Adapters[Adapter].nCfgs;
1860 for(i=0; i<nCfgs; i++) {
1861 if(cfgs[i].numSamples != MultiSampleType)
1862 continue;
1863
1864 if(!IWineD3DImpl_IsPixelFormatCompatibleWithDepthFmt(&cfgs[i], SurfaceFormat))
1865 continue;
1866
1867 TRACE("Found iPixelFormat=%d to support MultiSampleType=%d for format %s\n", cfgs[i].iPixelFormat, MultiSampleType, debug_d3dformat(SurfaceFormat));
1868
1869 if(pQualityLevels)
1870 *pQualityLevels = 1; /* Guess at a value! */
1871 return WINED3D_OK;
1872 }
1873 }
1874 else if(glDesc->Flags & WINED3DFMT_FLAG_RENDERTARGET) {
1875 short redSize, greenSize, blueSize, alphaSize, colorBits;
1876 int i, nCfgs;
1877 const WineD3D_PixelFormat *cfgs;
1878
1879 if(!getColorBits(SurfaceFormat, &redSize, &greenSize, &blueSize, &alphaSize, &colorBits)) {
1880 ERR("Unable to color bits for format %#x, can't check multisampling capability!\n", SurfaceFormat);
1881 return WINED3DERR_NOTAVAILABLE;
1882 }
1883
1884 cfgs = Adapters[Adapter].cfgs;
1885 nCfgs = Adapters[Adapter].nCfgs;
1886 for(i=0; i<nCfgs; i++) {
1887 if(cfgs[i].numSamples != MultiSampleType)
1888 continue;
1889 if(cfgs[i].redSize != redSize)
1890 continue;
1891 if(cfgs[i].greenSize != greenSize)
1892 continue;
1893 if(cfgs[i].blueSize != blueSize)
1894 continue;
1895 if(cfgs[i].alphaSize != alphaSize)
1896 continue;
1897
1898 TRACE("Found iPixelFormat=%d to support MultiSampleType=%d for format %s\n", cfgs[i].iPixelFormat, MultiSampleType, debug_d3dformat(SurfaceFormat));
1899
1900 if(pQualityLevels)
1901 *pQualityLevels = 1; /* Guess at a value! */
1902 return WINED3D_OK;
1903 }
1904 }
1905 return WINED3DERR_NOTAVAILABLE;
1906 }
1907
1908 static HRESULT WINAPI IWineD3DImpl_CheckDeviceType(IWineD3D *iface, UINT Adapter, WINED3DDEVTYPE DeviceType,
1909 WINED3DFORMAT DisplayFormat, WINED3DFORMAT BackBufferFormat, BOOL Windowed) {
1910
1911 IWineD3DImpl *This = (IWineD3DImpl *)iface;
1912 HRESULT hr = WINED3DERR_NOTAVAILABLE;
1913 UINT nmodes;
1914
1915 TRACE_(d3d_caps)("(%p)-> (STUB) (Adptr:%d, CheckType:(%x,%s), DispFmt:(%x,%s), BackBuf:(%x,%s), Win?%d): stub\n",
1916 This,
1917 Adapter,
1918 DeviceType, debug_d3ddevicetype(DeviceType),
1919 DisplayFormat, debug_d3dformat(DisplayFormat),
1920 BackBufferFormat, debug_d3dformat(BackBufferFormat),
1921 Windowed);
1922
1923 if (Adapter >= IWineD3D_GetAdapterCount(iface)) {
1924 WARN_(d3d_caps)("Adapter >= IWineD3D_GetAdapterCount(iface), returning WINED3DERR_INVALIDCALL\n");
1925 return WINED3DERR_INVALIDCALL;
1926 }
1927
1928 /* The task of this function is to check whether a certain display / backbuffer format
1929 * combination is available on the given adapter. In fullscreen mode microsoft specified
1930 * that the display format shouldn't provide alpha and that ignoring alpha the backbuffer
1931 * and display format should match exactly.
1932 * In windowed mode format conversion can occur and this depends on the driver. When format
1933 * conversion is done, this function should nevertheless fail and applications need to use
1934 * CheckDeviceFormatConversion.
1935 * At the moment we assume that fullscreen and windowed have the same capabilities */
1936
1937 /* There are only 4 display formats */
1938 if(!((DisplayFormat == WINED3DFMT_R5G6B5) ||
1939 (DisplayFormat == WINED3DFMT_X1R5G5B5) ||
1940 (DisplayFormat == WINED3DFMT_X8R8G8B8) ||
1941 (DisplayFormat == WINED3DFMT_A2R10G10B10)))
1942 {
1943 TRACE_(d3d_caps)("Format %s unsupported as display format\n", debug_d3dformat(DisplayFormat));
1944 return WINED3DERR_NOTAVAILABLE;
1945 }
1946
1947 /* If the requested DisplayFormat is not available, don't continue */
1948 nmodes = IWineD3DImpl_GetAdapterModeCount(iface, Adapter, DisplayFormat);
1949 if(!nmodes) {
1950 TRACE_(d3d_caps)("No available modes for display format %s\n", debug_d3dformat(DisplayFormat));
1951 return WINED3DERR_NOTAVAILABLE;
1952 }
1953
1954 /* Windowed mode allows you to specify WINED3DFMT_UNKNOWN for the backbufferformat, it means 'reuse' the display format for the backbuffer */
1955 if(!Windowed && BackBufferFormat == WINED3DFMT_UNKNOWN) {
1956 TRACE_(d3d_caps)("BackBufferFormat WINED3FMT_UNKNOWN not available in Windowed mode\n");
1957 return WINED3DERR_NOTAVAILABLE;
1958 }
1959
1960 /* In FULLSCREEN mode R5G6B5 can only be mixed with backbuffer format R5G6B5 */
1961 if( (DisplayFormat == WINED3DFMT_R5G6B5) && (BackBufferFormat != WINED3DFMT_R5G6B5) ) {
1962 TRACE_(d3d_caps)("Unsupported display/backbuffer format combination %s/%s\n", debug_d3dformat(DisplayFormat), debug_d3dformat(BackBufferFormat));
1963 return WINED3DERR_NOTAVAILABLE;
1964 }
1965
1966 /* In FULLSCREEN mode X1R5G5B5 can only be mixed with backbuffer format *1R5G5B5 */
1967 if( (DisplayFormat == WINED3DFMT_X1R5G5B5) && !((BackBufferFormat == WINED3DFMT_X1R5G5B5) || (BackBufferFormat == WINED3DFMT_A1R5G5B5)) ) {
1968 TRACE_(d3d_caps)("Unsupported display/backbuffer format combination %s/%s\n", debug_d3dformat(DisplayFormat), debug_d3dformat(BackBufferFormat));
1969 return WINED3DERR_NOTAVAILABLE;
1970 }
1971
1972 /* In FULLSCREEN mode X8R8G8B8 can only be mixed with backbuffer format *8R8G8B8 */
1973 if( (DisplayFormat == WINED3DFMT_X8R8G8B8) && !((BackBufferFormat == WINED3DFMT_X8R8G8B8) || (BackBufferFormat == WINED3DFMT_A8R8G8B8)) ) {
1974 TRACE_(d3d_caps)("Unsupported display/backbuffer format combination %s/%s\n", debug_d3dformat(DisplayFormat), debug_d3dformat(BackBufferFormat));
1975 return WINED3DERR_NOTAVAILABLE;
1976 }
1977
1978 /* A2R10G10B10 is only allowed in fullscreen mode and it can only be mixed with backbuffer format A2R10G10B10 */
1979 if( (DisplayFormat == WINED3DFMT_A2R10G10B10) && ((BackBufferFormat != WINED3DFMT_A2R10G10B10) || Windowed)) {
1980 TRACE_(d3d_caps)("Unsupported display/backbuffer format combination %s/%s\n", debug_d3dformat(DisplayFormat), debug_d3dformat(BackBufferFormat));
1981 return WINED3DERR_NOTAVAILABLE;
1982 }
1983
1984 /* Use CheckDeviceFormat to see if the BackBufferFormat is usable with the given DisplayFormat */
1985 hr = IWineD3DImpl_CheckDeviceFormat(iface, Adapter, DeviceType, DisplayFormat, WINED3DUSAGE_RENDERTARGET, WINED3DRTYPE_SURFACE, BackBufferFormat, SURFACE_OPENGL);
1986 if(FAILED(hr))
1987 TRACE_(d3d_caps)("Unsupported display/backbuffer format combination %s/%s\n", debug_d3dformat(DisplayFormat), debug_d3dformat(BackBufferFormat));
1988
1989 return hr;
1990 }
1991
1992
1993 #define GLINFO_LOCATION Adapters[Adapter].gl_info
1994 /* Check if we support bumpmapping for a format */
1995 static BOOL CheckBumpMapCapability(UINT Adapter, WINED3DDEVTYPE DeviceType, WINED3DFORMAT CheckFormat)
1996 {
1997 const struct fragment_pipeline *fp;
1998 const struct GlPixelFormatDesc *glDesc;
1999
2000 switch(CheckFormat) {
2001 case WINED3DFMT_V8U8:
2002 case WINED3DFMT_V16U16:
2003 case WINED3DFMT_L6V5U5:
2004 case WINED3DFMT_X8L8V8U8:
2005 case WINED3DFMT_Q8W8V8U8:
2006 /* Ask the fixed function pipeline implementation if it can deal
2007 * with the conversion. If we've got a GL extension giving native
2008 * support this will be an identity conversion. */
2009 getFormatDescEntry(CheckFormat, &GLINFO_LOCATION, &glDesc);
2010 fp = select_fragment_implementation(Adapter, DeviceType);
2011 if (fp->color_fixup_supported(glDesc->color_fixup))
2012 {
2013 TRACE_(d3d_caps)("[OK]\n");
2014 return TRUE;
2015 }
2016 TRACE_(d3d_caps)("[FAILED]\n");
2017 return FALSE;
2018
2019 default:
2020 TRACE_(d3d_caps)("[FAILED]\n");
2021 return FALSE;
2022 }
2023 }
2024
2025 /* Check if the given DisplayFormat + DepthStencilFormat combination is valid for the Adapter */
2026 static BOOL CheckDepthStencilCapability(UINT Adapter, WINED3DFORMAT DisplayFormat, WINED3DFORMAT DepthStencilFormat)
2027 {
2028 int it=0;
2029 const struct GlPixelFormatDesc *glDesc;
2030 const StaticPixelFormatDesc *desc = getFormatDescEntry(DepthStencilFormat, &GLINFO_LOCATION, &glDesc);
2031
2032 /* Fail if we weren't able to get a description of the format */
2033 if(!desc || !glDesc)
2034 return FALSE;
2035
2036 /* Only allow depth/stencil formats */
2037 if(!(glDesc->Flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL)))
2038 return FALSE;
2039
2040 /* Walk through all WGL pixel formats to find a match */
2041 for (it = 0; it < Adapters[Adapter].nCfgs; ++it) {
2042 WineD3D_PixelFormat *cfg = &Adapters[Adapter].cfgs[it];
2043 if (IWineD3DImpl_IsPixelFormatCompatibleWithRenderFmt(cfg, DisplayFormat)) {
2044 if (IWineD3DImpl_IsPixelFormatCompatibleWithDepthFmt(cfg, DepthStencilFormat)) {
2045 return TRUE;
2046 }
2047 }
2048 }
2049
2050 return FALSE;
2051 }
2052
2053 static BOOL CheckFilterCapability(UINT Adapter, WINED3DFORMAT CheckFormat)
2054 {
2055 const struct GlPixelFormatDesc *glDesc;
2056 const StaticPixelFormatDesc *desc = getFormatDescEntry(CheckFormat, &GLINFO_LOCATION, &glDesc);
2057
2058 /* Fail if we weren't able to get a description of the format */
2059 if(!desc || !glDesc)
2060 return FALSE;
2061
2062 /* The flags entry of a format contains the filtering capability */
2063 if(glDesc->Flags & WINED3DFMT_FLAG_FILTERING)
2064 return TRUE;
2065
2066 return FALSE;
2067 }
2068
2069 /* Check the render target capabilities of a format */
2070 static BOOL CheckRenderTargetCapability(WINED3DFORMAT AdapterFormat, WINED3DFORMAT CheckFormat)
2071 {
2072 UINT Adapter = 0;
2073 const struct GlPixelFormatDesc *glDesc;
2074 const StaticPixelFormatDesc *desc = getFormatDescEntry(CheckFormat, &GLINFO_LOCATION, &glDesc);
2075
2076 /* Fail if we weren't able to get a description of the format */
2077 if(!desc || !glDesc)
2078 return FALSE;
2079
2080 /* Filter out non-RT formats */
2081 if(!(glDesc->Flags & WINED3DFMT_FLAG_RENDERTARGET))
2082 return FALSE;
2083
2084 if(wined3d_settings.offscreen_rendering_mode == ORM_BACKBUFFER) {
2085 WineD3D_PixelFormat *cfgs = Adapters[Adapter].cfgs;
2086 int it;
2087 short AdapterRed, AdapterGreen, AdapterBlue, AdapterAlpha, AdapterTotalSize;
2088 short CheckRed, CheckGreen, CheckBlue, CheckAlpha, CheckTotalSize;
2089
2090 getColorBits(AdapterFormat, &AdapterRed, &AdapterGreen, &AdapterBlue, &AdapterAlpha, &AdapterTotalSize);
2091 getColorBits(CheckFormat, &CheckRed, &CheckGreen, &CheckBlue, &CheckAlpha, &CheckTotalSize);
2092
2093 /* In backbuffer mode the front and backbuffer share the same WGL pixelformat.
2094 * The format must match in RGB, alpha is allowed to be different. (Only the backbuffer can have alpha) */
2095 if(!((AdapterRed == CheckRed) && (AdapterGreen == CheckGreen) && (AdapterBlue == CheckBlue))) {
2096 TRACE_(d3d_caps)("[FAILED]\n");
2097 return FALSE;
2098 }
2099
2100 /* Check if there is a WGL pixel format matching the requirements, the format should also be window
2101 * drawable (not offscreen; e.g. Nvidia offers R5G6B5 for pbuffers even when X is running at 24bit) */
2102 for (it = 0; it < Adapters[Adapter].nCfgs; ++it) {
2103 if (cfgs[it].windowDrawable && IWineD3DImpl_IsPixelFormatCompatibleWithRenderFmt(&cfgs[it], CheckFormat)) {
2104 TRACE_(d3d_caps)("iPixelFormat=%d is compatible with CheckFormat=%s\n", cfgs[it].iPixelFormat, debug_d3dformat(CheckFormat));
2105 return TRUE;
2106 }
2107 }
2108 } else if(wined3d_settings.offscreen_rendering_mode == ORM_PBUFFER) {
2109 /* We can probably use this function in FBO mode too on some drivers to get some basic indication of the capabilities. */
2110 WineD3D_PixelFormat *cfgs = Adapters[Adapter].cfgs;
2111 int it;
2112
2113 /* Check if there is a WGL pixel format matching the requirements, the pixel format should also be usable with pbuffers */
2114 for (it = 0; it < Adapters[Adapter].nCfgs; ++it) {
2115 if (cfgs[it].pbufferDrawable && IWineD3DImpl_IsPixelFormatCompatibleWithRenderFmt(&cfgs[it], CheckFormat)) {
2116 TRACE_(d3d_caps)("iPixelFormat=%d is compatible with CheckFormat=%s\n", cfgs[it].iPixelFormat, debug_d3dformat(CheckFormat));
2117 return TRUE;
2118 }
2119 }
2120 } else if(wined3d_settings.offscreen_rendering_mode == ORM_FBO){
2121 /* For now return TRUE for FBOs until we have some proper checks.
2122 * Note that this function will only be called when the format is around for texturing. */
2123 return TRUE;
2124 }
2125 return FALSE;
2126 }
2127
2128 static BOOL CheckSrgbReadCapability(UINT Adapter, WINED3DFORMAT CheckFormat)
2129 {
2130 /* Check for supported sRGB formats (Texture loading and framebuffer) */
2131 if(!GL_SUPPORT(EXT_TEXTURE_SRGB)) {
2132 TRACE_(d3d_caps)("[FAILED] GL_EXT_texture_sRGB not supported\n");
2133 return FALSE;
2134 }
2135
2136 switch (CheckFormat) {
2137 case WINED3DFMT_A8R8G8B8:
2138 case WINED3DFMT_X8R8G8B8:
2139 case WINED3DFMT_A4R4G4B4:
2140 case WINED3DFMT_L8:
2141 case WINED3DFMT_A8L8:
2142 case WINED3DFMT_DXT1:
2143 case WINED3DFMT_DXT2:
2144 case WINED3DFMT_DXT3:
2145 case WINED3DFMT_DXT4:
2146 case WINED3DFMT_DXT5:
2147 TRACE_(d3d_caps)("[OK]\n");
2148 return TRUE;
2149
2150 default:
2151 TRACE_(d3d_caps)("[FAILED] Gamma texture format %s not supported.\n", debug_d3dformat(CheckFormat));
2152 return FALSE;
2153 }
2154 return FALSE;
2155 }
2156
2157 static BOOL CheckSrgbWriteCapability(UINT Adapter, WINED3DDEVTYPE DeviceType, WINED3DFORMAT CheckFormat)
2158 {
2159 /* Only offer SRGB writing on X8R8G8B8/A8R8G8B8 when we use ARB or GLSL shaders as we are
2160 * doing the color fixup in shaders.
2161 * Note Windows drivers (at least on the Geforce 8800) also offer this on R5G6B5. */
2162 if((CheckFormat == WINED3DFMT_X8R8G8B8) || (CheckFormat == WINED3DFMT_A8R8G8B8)) {
2163 int vs_selected_mode;
2164 int ps_selected_mode;
2165 select_shader_mode(&GLINFO_LOCATION, DeviceType, &ps_selected_mode, &vs_selected_mode);
2166
2167 if((ps_selected_mode == SHADER_ARB) || (ps_selected_mode == SHADER_GLSL)) {
2168 TRACE_(d3d_caps)("[OK]\n");
2169 return TRUE;
2170 }
2171 }
2172
2173 TRACE_(d3d_caps)("[FAILED] - no SRGB writing support on format=%s\n", debug_d3dformat(CheckFormat));
2174 return FALSE;
2175 }
2176
2177 /* Check if a format support blending in combination with pixel shaders */
2178 static BOOL CheckPostPixelShaderBlendingCapability(UINT Adapter, WINED3DFORMAT CheckFormat)
2179 {
2180 const struct GlPixelFormatDesc *glDesc;
2181 const StaticPixelFormatDesc *desc = getFormatDescEntry(CheckFormat, &GLINFO_LOCATION, &glDesc);
2182
2183 /* Fail if we weren't able to get a description of the format */
2184 if(!desc || !glDesc)
2185 return FALSE;
2186
2187 /* The flags entry of a format contains the post pixel shader blending capability */
2188 if(glDesc->Flags & WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING)
2189 return TRUE;
2190
2191 return FALSE;
2192 }
2193
2194 static BOOL CheckWrapAndMipCapability(UINT Adapter, WINED3DFORMAT CheckFormat) {
2195 /* OpenGL supports mipmapping on all formats basically. Wrapping is unsupported,
2196 * but we have to report mipmapping so we cannot reject this flag. Tests show that
2197 * windows reports WRAPANDMIP on unfilterable surfaces as well, apparently to show
2198 * that wrapping is supported. The lack of filtering will sort out the mipmapping
2199 * capability anyway.
2200 *
2201 * For now lets report this on all formats, but in the future we may want to
2202 * restrict it to some should games need that
2203 */
2204 return TRUE;
2205 }
2206
2207 /* Check if a texture format is supported on the given adapter */
2208 static BOOL CheckTextureCapability(UINT Adapter, WINED3DDEVTYPE DeviceType, WINED3DFORMAT CheckFormat)
2209 {
2210 const shader_backend_t *shader_backend;
2211 const struct fragment_pipeline *fp;
2212 const struct GlPixelFormatDesc *glDesc;
2213
2214 switch (CheckFormat) {
2215
2216 /*****
2217 * supported: RGB(A) formats
2218 */
2219 case WINED3DFMT_R8G8B8: /* Enable for dx7, blacklisted for 8 and 9 above */
2220 case WINED3DFMT_A8R8G8B8:
2221 case WINED3DFMT_X8R8G8B8:
2222 case WINED3DFMT_R5G6B5:
2223 case WINED3DFMT_X1R5G5B5:
2224 case WINED3DFMT_A1R5G5B5:
2225 case WINED3DFMT_A4R4G4B4:
2226 case WINED3DFMT_A8:
2227 case WINED3DFMT_X4R4G4B4:
2228 case WINED3DFMT_A8B8G8R8:
2229 case WINED3DFMT_X8B8G8R8:
2230 case WINED3DFMT_A2R10G10B10:
2231 case WINED3DFMT_A2B10G10R10:
2232 case WINED3DFMT_G16R16:
2233 TRACE_(d3d_caps)("[OK]\n");
2234 return TRUE;
2235
2236 case WINED3DFMT_R3G3B2:
2237 TRACE_(d3d_caps)("[FAILED] - Not supported on Windows\n");
2238 return FALSE;
2239
2240 /*****
2241 * supported: Palettized
2242 */
2243 case WINED3DFMT_P8:
2244 TRACE_(d3d_caps)("[OK]\n");
2245 return TRUE;
2246 /* No Windows driver offers A8P8, so don't offer it either */
2247 case WINED3DFMT_A8P8:
2248 return FALSE;
2249
2250 /*****
2251 * Supported: (Alpha)-Luminance
2252 */
2253 case WINED3DFMT_L8:
2254 case WINED3DFMT_A8L8:
2255 case WINED3DFMT_L16:
2256 TRACE_(d3d_caps)("[OK]\n");
2257 return TRUE;
2258
2259 /* Not supported on Windows, thus disabled */
2260 case WINED3DFMT_A4L4:
2261 TRACE_(d3d_caps)("[FAILED] - not supported on windows\n");
2262 return FALSE;
2263
2264 /*****
2265 * Supported: Depth/Stencil formats
2266 */
2267 case WINED3DFMT_D16_LOCKABLE:
2268 case WINED3DFMT_D16:
2269 case WINED3DFMT_D15S1:
2270 case WINED3DFMT_D24X8:
2271 case WINED3DFMT_D24X4S4:
2272 case WINED3DFMT_D24S8:
2273 case WINED3DFMT_D24FS8:
2274 case WINED3DFMT_D32:
2275 case WINED3DFMT_D32F_LOCKABLE:
2276 return TRUE;
2277
2278 /*****
2279 * Not supported everywhere(depends on GL_ATI_envmap_bumpmap or
2280 * GL_NV_texture_shader). Emulated by shaders
2281 */
2282 case WINED3DFMT_V8U8:
2283 case WINED3DFMT_X8L8V8U8:
2284 case WINED3DFMT_L6V5U5:
2285 case WINED3DFMT_Q8W8V8U8:
2286 case WINED3DFMT_V16U16:
2287 /* Ask the shader backend if it can deal with the conversion. If
2288 * we've got a GL extension giving native support this will be an
2289 * identity conversion. */
2290 getFormatDescEntry(CheckFormat, &GLINFO_LOCATION, &glDesc);
2291 shader_backend = select_shader_backend(Adapter, DeviceType);
2292 if (shader_backend->shader_color_fixup_supported(glDesc->color_fixup))
2293 {
2294 TRACE_(d3d_caps)("[OK]\n");
2295 return TRUE;
2296 }
2297 TRACE_(d3d_caps)("[FAILED]\n");
2298 return FALSE;
2299
2300 case WINED3DFMT_DXT1:
2301 case WINED3DFMT_DXT2:
2302 case WINED3DFMT_DXT3:
2303 case WINED3DFMT_DXT4:
2304 case WINED3DFMT_DXT5:
2305 if (GL_SUPPORT(EXT_TEXTURE_COMPRESSION_S3TC)) {
2306 TRACE_(d3d_caps)("[OK]\n");
2307 return TRUE;
2308 }
2309 TRACE_(d3d_caps)("[FAILED]\n");
2310 return FALSE;
2311
2312
2313 /*****
2314 * Odd formats - not supported
2315 */
2316 case WINED3DFMT_VERTEXDATA:
2317 case WINED3DFMT_INDEX16:
2318 case WINED3DFMT_INDEX32:
2319 case WINED3DFMT_Q16W16V16U16:
2320 case WINED3DFMT_A2W10V10U10:
2321 case WINED3DFMT_W11V11U10:
2322 TRACE_(d3d_caps)("[FAILED]\n"); /* Enable when implemented */
2323 return FALSE;
2324
2325 /*****
2326 * WINED3DFMT_CxV8U8: Not supported right now
2327 */
2328 case WINED3DFMT_CxV8U8:
2329 TRACE_(d3d_caps)("[FAILED]\n"); /* Enable when implemented */
2330 return FALSE;
2331
2332 /* YUV formats */
2333 case WINED3DFMT_UYVY:
2334 case WINED3DFMT_YUY2:
2335 if(GL_SUPPORT(APPLE_YCBCR_422)) {
2336 TRACE_(d3d_caps)("[OK]\n");
2337 return TRUE;
2338 }
2339 TRACE_(d3d_caps)("[FAILED]\n");
2340 return FALSE;
2341 case WINED3DFMT_YV12:
2342 TRACE_(d3d_caps)("[FAILED]\n");
2343 return FALSE;
2344
2345 /* Not supported */
2346 case WINED3DFMT_A16B16G16R16:
2347 case WINED3DFMT_A8R3G3B2:
2348 TRACE_(d3d_caps)("[FAILED]\n"); /* Enable when implemented */
2349 return FALSE;
2350
2351 /* Floating point formats */
2352 case WINED3DFMT_R16F:
2353 case WINED3DFMT_A16B16G16R16F:
2354 if(GL_SUPPORT(ARB_TEXTURE_FLOAT) && GL_SUPPORT(ARB_HALF_FLOAT_PIXEL)) {
2355 TRACE_(d3d_caps)("[OK]\n");
2356 return TRUE;
2357 }
2358 TRACE_(d3d_caps)("[FAILED]\n");
2359 return FALSE;
2360
2361 case WINED3DFMT_R32F:
2362 case WINED3DFMT_A32B32G32R32F:
2363 if (GL_SUPPORT(ARB_TEXTURE_FLOAT)) {
2364 TRACE_(d3d_caps)("[OK]\n");
2365 return TRUE;
2366 }
2367 TRACE_(d3d_caps)("[FAILED]\n");
2368 return FALSE;
2369
2370 case WINED3DFMT_G16R16F:
2371 case WINED3DFMT_G32R32F:
2372 if(GL_SUPPORT(ARB_TEXTURE_RG)) {
2373 TRACE_(d3d_caps)("[OK]\n");
2374 return TRUE;
2375 }
2376 TRACE_(d3d_caps)("[FAILED]\n");
2377 return FALSE;
2378
2379 /* ATI instancing hack: Although ATI cards do not support Shader Model 3.0, they support
2380 * instancing. To query if the card supports instancing CheckDeviceFormat with the special format
2381 * MAKEFOURCC('I','N','S','T') is used. Should a (broken) app check for this provide a proper return value.
2382 * We can do instancing with all shader versions, but we need vertex shaders.
2383 *
2384 * Additionally applications have to set the D3DRS_POINTSIZE render state to MAKEFOURCC('I','N','S','T') once
2385 * to enable instancing. WineD3D doesn't need that and just ignores it.
2386 *
2387 * With Shader Model 3.0 capable cards Instancing 'just works' in Windows.
2388 */
2389 case WINEMAKEFOURCC('I','N','S','T'):
2390 TRACE("ATI Instancing check hack\n");
2391 if(GL_SUPPORT(ARB_VERTEX_PROGRAM) || GL_SUPPORT(ARB_VERTEX_SHADER)) {
2392 TRACE_(d3d_caps)("[OK]\n");
2393 return TRUE;
2394 }
2395 TRACE_(d3d_caps)("[FAILED]\n");
2396 return FALSE;
2397
2398 /* Some weird FOURCC formats */
2399 case WINED3DFMT_R8G8_B8G8:
2400 case WINED3DFMT_G8R8_G8B8:
2401 case WINED3DFMT_MULTI2_ARGB8:
2402 TRACE_(d3d_caps)("[FAILED]\n");
2403 return FALSE;
2404
2405 /* Vendor specific formats */
2406 case WINED3DFMT_ATI2N:
2407 if(GL_SUPPORT(ATI_TEXTURE_COMPRESSION_3DC) || GL_SUPPORT(EXT_TEXTURE_COMPRESSION_RGTC)) {
2408 getFormatDescEntry(CheckFormat, &GLINFO_LOCATION, &glDesc);
2409 shader_backend = select_shader_backend(Adapter, DeviceType);
2410 fp = select_fragment_implementation(Adapter, DeviceType);
2411 if (shader_backend->shader_color_fixup_supported(glDesc->color_fixup)
2412 && fp->color_fixup_supported(glDesc->color_fixup))
2413 {
2414 TRACE_(d3d_caps)("[OK]\n");
2415 return TRUE;
2416 }
2417
2418 TRACE_(d3d_caps)("[OK]\n");
2419 return TRUE;
2420 }
2421 TRACE_(d3d_caps)("[FAILED]\n");
2422 return FALSE;
2423
2424 case WINED3DFMT_NVHU:
2425 case WINED3DFMT_NVHS:
2426 /* These formats seem to be similar to the HILO formats in GL_NV_texture_shader. NVHU
2427 * is said to be GL_UNSIGNED_HILO16, NVHS GL_SIGNED_HILO16. Rumours say that d3d computes
2428 * a 3rd channel similarly to D3DFMT_CxV8U8(So NVHS could be called D3DFMT_CxV16U16).
2429 * ATI refused to support formats which can easilly be emulated with pixel shaders, so
2430 * Applications have to deal with not having NVHS and NVHU.
2431 */
2432 TRACE_(d3d_caps)("[FAILED]\n");
2433 return FALSE;
2434
2435 case WINED3DFMT_UNKNOWN:
2436 return FALSE;
2437
2438 default:
2439 ERR("Unhandled format=%s\n", debug_d3dformat(CheckFormat));
2440 break;
2441 }
2442 return FALSE;
2443 }
2444
2445 static BOOL CheckSurfaceCapability(UINT Adapter, WINED3DFORMAT AdapterFormat, WINED3DDEVTYPE DeviceType, WINED3DFORMAT CheckFormat, WINED3DSURFTYPE SurfaceType) {
2446 const struct GlPixelFormatDesc *format_desc;
2447 const struct blit_shader *blitter;
2448
2449 if(SurfaceType == SURFACE_GDI) {
2450 switch(CheckFormat) {
2451 case WINED3DFMT_R8G8B8:
2452 case WINED3DFMT_A8R8G8B8:
2453 case WINED3DFMT_X8R8G8B8:
2454 case WINED3DFMT_R5G6B5:
2455 case WINED3DFMT_X1R5G5B5:
2456 case WINED3DFMT_A1R5G5B5:
2457 case WINED3DFMT_A4R4G4B4:
2458 case WINED3DFMT_R3G3B2:
2459 case WINED3DFMT_A8:
2460 case WINED3DFMT_A8R3G3B2:
2461 case WINED3DFMT_X4R4G4B4:
2462 case WINED3DFMT_A2B10G10R10:
2463 case WINED3DFMT_A8B8G8R8:
2464 case WINED3DFMT_X8B8G8R8:
2465 case WINED3DFMT_G16R16:
2466 case WINED3DFMT_A2R10G10B10:
2467 case WINED3DFMT_A16B16G16R16:
2468 case WINED3DFMT_P8:
2469 TRACE_(d3d_caps)("[OK]\n");
2470 return TRUE;
2471 default:
2472 TRACE_(d3d_caps)("[FAILED] - not available on GDI surfaces\n");
2473 return FALSE;
2474 }
2475 }
2476
2477 /* All format that are supported for textures are supported for surfaces as well */
2478 if(CheckTextureCapability(Adapter, DeviceType, CheckFormat)) return TRUE;
2479 /* All depth stencil formats are supported on surfaces */
2480 if(CheckDepthStencilCapability(Adapter, AdapterFormat, CheckFormat)) return TRUE;
2481
2482 /* If opengl can't process the format natively, the blitter may be able to convert it */
2483 getFormatDescEntry(CheckFormat, &GLINFO_LOCATION, &format_desc);
2484 blitter = select_blit_implementation(Adapter, DeviceType);
2485 if (blitter->color_fixup_supported(format_desc->color_fixup))
2486 {
2487 TRACE_(d3d_caps)("[OK]\n");
2488 return TRUE;
2489 }
2490
2491 /* Reject other formats */
2492 TRACE_(d3d_caps)("[FAILED]\n");
2493 return FALSE;
2494 }
2495
2496 static BOOL CheckVertexTextureCapability(UINT Adapter, WINED3DFORMAT CheckFormat)
2497 {
2498 if (!GL_LIMITS(vertex_samplers)) {
2499 TRACE_(d3d_caps)("[FAILED]\n");
2500 return FALSE;
2501 }
2502
2503 switch (CheckFormat) {
2504 case WINED3DFMT_A32B32G32R32F:
2505 if (!GL_SUPPORT(ARB_TEXTURE_FLOAT)) {
2506 TRACE_(d3d_caps)("[FAILED]\n");
2507 return FALSE;
2508 }
2509 TRACE_(d3d_caps)("[OK]\n");
2510 return TRUE;
2511
2512 default:
2513 TRACE_(d3d_caps)("[FAILED]\n");
2514 return FALSE;
2515 }
2516 return FALSE;
2517 }
2518
2519 static HRESULT WINAPI IWineD3DImpl_CheckDeviceFormat(IWineD3D *iface, UINT Adapter, WINED3DDEVTYPE DeviceType,
2520 WINED3DFORMAT AdapterFormat, DWORD Usage, WINED3DRESOURCETYPE RType, WINED3DFORMAT CheckFormat,
2521 WINED3DSURFTYPE SurfaceType) {
2522 IWineD3DImpl *This = (IWineD3DImpl *)iface;
2523 DWORD UsageCaps = 0;
2524
2525 TRACE_(d3d_caps)("(%p)-> (STUB) (Adptr:%d, DevType:(%u,%s), AdptFmt:(%u,%s), Use:(%u,%s,%s), ResTyp:(%x,%s), CheckFmt:(%u,%s))\n",
2526 This,
2527 Adapter,
2528 DeviceType, debug_d3ddevicetype(DeviceType),
2529 AdapterFormat, debug_d3dformat(AdapterFormat),
2530 Usage, debug_d3dusage(Usage), debug_d3dusagequery(Usage),
2531 RType, debug_d3dresourcetype(RType),
2532 CheckFormat, debug_d3dformat(CheckFormat));
2533
2534 if (Adapter >= IWineD3D_GetAdapterCount(iface)) {
2535 return WINED3DERR_INVALIDCALL;
2536 }
2537
2538 if(RType == WINED3DRTYPE_CUBETEXTURE) {
2539
2540 if(SurfaceType != SURFACE_OPENGL) {
2541 TRACE("[FAILED]\n");
2542 return WINED3DERR_NOTAVAILABLE;
2543 }
2544
2545 /* Cubetexture allows:
2546 * - D3DUSAGE_AUTOGENMIPMAP
2547 * - D3DUSAGE_DEPTHSTENCIL
2548 * - D3DUSAGE_DYNAMIC
2549 * - D3DUSAGE_NONSECURE (d3d9ex)
2550 * - D3DUSAGE_RENDERTARGET
2551 * - D3DUSAGE_SOFTWAREPROCESSING
2552 * - D3DUSAGE_QUERY_WRAPANDMIP
2553 */
2554 if(GL_SUPPORT(ARB_TEXTURE_CUBE_MAP)) {
2555 /* Check if the texture format is around */
2556 if(CheckTextureCapability(Adapter, DeviceType, CheckFormat)) {
2557 if(Usage & WINED3DUSAGE_AUTOGENMIPMAP) {
2558 /* Check for automatic mipmap generation support */
2559 if(GL_SUPPORT(SGIS_GENERATE_MIPMAP)) {
2560 UsageCaps |= WINED3DUSAGE_AUTOGENMIPMAP;
2561 } else {
2562 /* When autogenmipmap isn't around continue and return WINED3DOK_NOAUTOGEN instead of D3D_OK */
2563 TRACE_(d3d_caps)("[FAILED] - No autogenmipmap support, but continuing\n");
2564 }
2565 }
2566
2567 /* Always report dynamic locking */
2568 if(Usage & WINED3DUSAGE_DYNAMIC)
2569 UsageCaps |= WINED3DUSAGE_DYNAMIC;
2570
2571 if(Usage & WINED3DUSAGE_RENDERTARGET) {
2572 if(CheckRenderTargetCapability(AdapterFormat, CheckFormat)) {
2573 UsageCaps |= WINED3DUSAGE_RENDERTARGET;
2574 } else {
2575 TRACE_(d3d_caps)("[FAILED] - No rendertarget support\n");
2576 return WINED3DERR_NOTAVAILABLE;
2577 }
2578 }
2579
2580 /* Always report software processing */
2581 if(Usage & WINED3DUSAGE_SOFTWAREPROCESSING)
2582 UsageCaps |= WINED3DUSAGE_SOFTWAREPROCESSING;
2583
2584 /* Check QUERY_FILTER support */
2585 if(Usage & WINED3DUSAGE_QUERY_FILTER) {
2586 if(CheckFilterCapability(Adapter, CheckFormat)) {
2587 UsageCaps |= WINED3DUSAGE_QUERY_FILTER;
2588 } else {
2589 TRACE_(d3d_caps)("[FAILED] - No query filter support\n");
2590 return WINED3DERR_NOTAVAILABLE;
2591 }
2592 }
2593
2594 /* Check QUERY_POSTPIXELSHADER_BLENDING support */
2595 if(Usage & WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING) {
2596 if(CheckPostPixelShaderBlendingCapability(Adapter, CheckFormat)) {
2597 UsageCaps |= WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING;
2598 } else {
2599 TRACE_(d3d_caps)("[FAILED] - No query post pixelshader blending support\n");
2600 return WINED3DERR_NOTAVAILABLE;
2601 }
2602 }
2603
2604 /* Check QUERY_SRGBREAD support */
2605 if(Usage & WINED3DUSAGE_QUERY_SRGBREAD) {
2606 if(CheckSrgbReadCapability(Adapter, CheckFormat)) {
2607 UsageCaps |= WINED3DUSAGE_QUERY_SRGBREAD;
2608 } else {
2609 TRACE_(d3d_caps)("[FAILED] - No query srgbread support\n");
2610 return WINED3DERR_NOTAVAILABLE;
2611 }
2612 }
2613
2614 /* Check QUERY_SRGBWRITE support */
2615 if(Usage & WINED3DUSAGE_QUERY_SRGBWRITE) {
2616 if(CheckSrgbWriteCapability(Adapter, DeviceType, CheckFormat)) {
2617 UsageCaps |= WINED3DUSAGE_QUERY_SRGBWRITE;
2618 } else {
2619 TRACE_(d3d_caps)("[FAILED] - No query srgbwrite support\n");
2620 return WINED3DERR_NOTAVAILABLE;
2621 }
2622 }
2623
2624 /* Check QUERY_VERTEXTEXTURE support */
2625 if(Usage & WINED3DUSAGE_QUERY_VERTEXTEXTURE) {
2626 if(CheckVertexTextureCapability(Adapter, CheckFormat)) {
2627 UsageCaps |= WINED3DUSAGE_QUERY_VERTEXTEXTURE;
2628 } else {
2629 TRACE_(d3d_caps)("[FAILED] - No query vertextexture support\n");
2630 return WINED3DERR_NOTAVAILABLE;
2631 }
2632 }
2633
2634 /* Check QUERY_WRAPANDMIP support */
2635 if(Usage & WINED3DUSAGE_QUERY_WRAPANDMIP) {
2636 if(CheckWrapAndMipCapability(Adapter, CheckFormat)) {
2637 UsageCaps |= WINED3DUSAGE_QUERY_WRAPANDMIP;
2638 } else {
2639 TRACE_(d3d_caps)("[FAILED] - No wrapping and mipmapping support\n");
2640 return WINED3DERR_NOTAVAILABLE;
2641 }
2642 }
2643 } else {
2644 TRACE_(d3d_caps)("[FAILED] - Cube texture format not supported\n");
2645 return WINED3DERR_NOTAVAILABLE;
2646 }
2647 } else {
2648 TRACE_(d3d_caps)("[FAILED] - No cube texture support\n");
2649 return WINED3DERR_NOTAVAILABLE;
2650 }
2651 } else if(RType == WINED3DRTYPE_SURFACE) {
2652 /* Surface allows:
2653 * - D3DUSAGE_DEPTHSTENCIL
2654 * - D3DUSAGE_NONSECURE (d3d9ex)
2655 * - D3DUSAGE_RENDERTARGET
2656 */
2657
2658 if(CheckSurfaceCapability(Adapter, AdapterFormat, DeviceType, CheckFormat, SurfaceType)) {
2659 if(Usage & WINED3DUSAGE_DEPTHSTENCIL) {
2660 if(CheckDepthStencilCapability(Adapter, AdapterFormat, CheckFormat)) {
2661 UsageCaps |= WINED3DUSAGE_DEPTHSTENCIL;
2662 } else {
2663 TRACE_(d3d_caps)("[FAILED] - No depthstencil support\n");
2664 return WINED3DERR_NOTAVAILABLE;
2665 }
2666 }
2667
2668 if(Usage & WINED3DUSAGE_RENDERTARGET) {
2669 if(CheckRenderTargetCapability(AdapterFormat, CheckFormat)) {
2670 UsageCaps |= WINED3DUSAGE_RENDERTARGET;
2671 } else {
2672 TRACE_(d3d_caps)("[FAILED] - No rendertarget support\n");
2673 return WINED3DERR_NOTAVAILABLE;
2674 }
2675 }
2676
2677 /* Check QUERY_POSTPIXELSHADER_BLENDING support */
2678 if(Usage & WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING) {
2679 if(CheckPostPixelShaderBlendingCapability(Adapter, CheckFormat)) {
2680 UsageCaps |= WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING;
2681 } else {
2682 TRACE_(d3d_caps)("[FAILED] - No query post pixelshader blending support\n");
2683 return WINED3DERR_NOTAVAILABLE;
2684 }
2685 }
2686 } else {
2687 TRACE_(d3d_caps)("[FAILED] - Not supported for plain surfaces\n");
2688 return WINED3DERR_NOTAVAILABLE;
2689 }
2690
2691 } else if(RType == WINED3DRTYPE_TEXTURE) {
2692 /* Texture allows:
2693 * - D3DUSAGE_AUTOGENMIPMAP
2694 * - D3DUSAGE_DEPTHSTENCIL
2695 * - D3DUSAGE_DMAP
2696 * - D3DUSAGE_DYNAMIC
2697 * - D3DUSAGE_NONSECURE (d3d9ex)
2698 * - D3DUSAGE_RENDERTARGET
2699 * - D3DUSAGE_SOFTWAREPROCESSING
2700 * - D3DUSAGE_TEXTAPI (d3d9ex)
2701 * - D3DUSAGE_QUERY_WRAPANDMIP
2702 */
2703
2704 if(SurfaceType != SURFACE_OPENGL) {
2705 TRACE("[FAILED]\n");
2706 return WINED3DERR_NOTAVAILABLE;
2707 }
2708
2709 /* Check if the texture format is around */
2710 if(CheckTextureCapability(Adapter, DeviceType, CheckFormat)) {
2711 if(Usage & WINED3DUSAGE_AUTOGENMIPMAP) {
2712 /* Check for automatic mipmap generation support */
2713 if(GL_SUPPORT(SGIS_GENERATE_MIPMAP)) {
2714 UsageCaps |= WINED3DUSAGE_AUTOGENMIPMAP;
2715 } else {
2716 /* When autogenmipmap isn't around continue and return WINED3DOK_NOAUTOGEN instead of D3D_OK */
2717 TRACE_(d3d_caps)("[FAILED] - No autogenmipmap support, but continuing\n");
2718 }
2719 }
2720
2721 /* Always report dynamic locking */
2722 if(Usage & WINED3DUSAGE_DYNAMIC)
2723 UsageCaps |= WINED3DUSAGE_DYNAMIC;
2724
2725 if(Usage & WINED3DUSAGE_RENDERTARGET) {
2726 if(CheckRenderTargetCapability(AdapterFormat, CheckFormat)) {
2727 UsageCaps |= WINED3DUSAGE_RENDERTARGET;
2728 } else {
2729 TRACE_(d3d_caps)("[FAILED] - No rendertarget support\n");
2730 return WINED3DERR_NOTAVAILABLE;
2731 }
2732 }
2733
2734 /* Always report software processing */
2735 if(Usage & WINED3DUSAGE_SOFTWAREPROCESSING)
2736 UsageCaps |= WINED3DUSAGE_SOFTWAREPROCESSING;
2737
2738 /* Check QUERY_FILTER support */
2739 if(Usage & WINED3DUSAGE_QUERY_FILTER) {
2740 if(CheckFilterCapability(Adapter, CheckFormat)) {
2741 UsageCaps |= WINED3DUSAGE_QUERY_FILTER;
2742 } else {
2743 TRACE_(d3d_caps)("[FAILED] - No query filter support\n");
2744 return WINED3DERR_NOTAVAILABLE;
2745 }
2746 }
2747
2748 /* Check QUERY_LEGACYBUMPMAP support */
2749 if(Usage & WINED3DUSAGE_QUERY_LEGACYBUMPMAP) {
2750 if(CheckBumpMapCapability(Adapter, DeviceType, CheckFormat)) {
2751 UsageCaps |= WINED3DUSAGE_QUERY_LEGACYBUMPMAP;
2752 } else {
2753 TRACE_(d3d_caps)("[FAILED] - No legacy bumpmap support\n");
2754 return WINED3DERR_NOTAVAILABLE;
2755 }
2756 }
2757
2758 /* Check QUERY_POSTPIXELSHADER_BLENDING support */
2759 if(Usage & WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING) {
2760 if(CheckPostPixelShaderBlendingCapability(Adapter, CheckFormat)) {
2761 UsageCaps |= WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING;
2762 } else {
2763 TRACE_(d3d_caps)("[FAILED] - No query post pixelshader blending support\n");
2764 return WINED3DERR_NOTAVAILABLE;
2765 }
2766 }
2767
2768 /* Check QUERY_SRGBREAD support */
2769 if(Usage & WINED3DUSAGE_QUERY_SRGBREAD) {
2770 if(CheckSrgbReadCapability(Adapter, CheckFormat)) {
2771 UsageCaps |= WINED3DUSAGE_QUERY_SRGBREAD;
2772 } else {
2773 TRACE_(d3d_caps)("[FAILED] - No query srgbread support\n");
2774 return WINED3DERR_NOTAVAILABLE;
2775 }
2776 }
2777
2778 /* Check QUERY_SRGBWRITE support */
2779 if(Usage & WINED3DUSAGE_QUERY_SRGBWRITE) {
2780 if(CheckSrgbWriteCapability(Adapter, DeviceType, CheckFormat)) {
2781 UsageCaps |= WINED3DUSAGE_QUERY_SRGBWRITE;
2782 } else {
2783 TRACE_(d3d_caps)("[FAILED] - No query srgbwrite support\n");
2784 return WINED3DERR_NOTAVAILABLE;
2785 }
2786 }
2787
2788 /* Check QUERY_VERTEXTEXTURE support */
2789 if(Usage & WINED3DUSAGE_QUERY_VERTEXTEXTURE) {
2790 if(CheckVertexTextureCapability(Adapter, CheckFormat)) {
2791 UsageCaps |= WINED3DUSAGE_QUERY_VERTEXTEXTURE;
2792 } else {
2793 TRACE_(d3d_caps)("[FAILED] - No query vertextexture support\n");
2794 return WINED3DERR_NOTAVAILABLE;
2795 }
2796 }
2797
2798 /* Check QUERY_WRAPANDMIP support */
2799 if(Usage & WINED3DUSAGE_QUERY_WRAPANDMIP) {
2800 if(CheckWrapAndMipCapability(Adapter, CheckFormat)) {
2801 UsageCaps |= WINED3DUSAGE_QUERY_WRAPANDMIP;
2802 } else {
2803 TRACE_(d3d_caps)("[FAILED] - No wrapping and mipmapping support\n");
2804 return WINED3DERR_NOTAVAILABLE;
2805 }
2806 }
2807
2808 if(Usage & WINED3DUSAGE_DEPTHSTENCIL) {
2809 if(CheckDepthStencilCapability(Adapter, AdapterFormat, CheckFormat)) {
2810 UsageCaps |= WINED3DUSAGE_DEPTHSTENCIL;
2811 } else {
2812 TRACE_(d3d_caps)("[FAILED] - No depth stencil support\n");
2813 return WINED3DERR_NOTAVAILABLE;
2814 }
2815 }
2816 } else {
2817 TRACE_(d3d_caps)("[FAILED] - Texture format not supported\n");
2818 return WINED3DERR_NOTAVAILABLE;
2819 }
2820 } else if((RType == WINED3DRTYPE_VOLUME) || (RType == WINED3DRTYPE_VOLUMETEXTURE)) {
2821 /* Volume is to VolumeTexture what Surface is to Texture but its usage caps are not documented.
2822 * Most driver seem to offer (nearly) the same on Volume and VolumeTexture, so do that too.
2823 *
2824 * Volumetexture allows:
2825 * - D3DUSAGE_DYNAMIC
2826 * - D3DUSAGE_NONSECURE (d3d9ex)
2827 * - D3DUSAGE_SOFTWAREPROCESSING
2828 * - D3DUSAGE_QUERY_WRAPANDMIP
2829 */
2830
2831 if(SurfaceType != SURFACE_OPENGL) {
2832 TRACE("[FAILED]\n");
2833 return WINED3DERR_NOTAVAILABLE;
2834 }
2835
2836 /* Check volume texture and volume usage caps */
2837 if(GL_SUPPORT(EXT_TEXTURE3D)) {
2838 if(CheckTextureCapability(Adapter, DeviceType, CheckFormat) == FALSE) {
2839 TRACE_(d3d_caps)("[FAILED] - Format not supported\n");
2840 return WINED3DERR_NOTAVAILABLE;
2841 }
2842
2843 /* Always report dynamic locking */
2844 if(Usage & WINED3DUSAGE_DYNAMIC)
2845 UsageCaps |= WINED3DUSAGE_DYNAMIC;
2846
2847 /* Always report software processing */
2848 if(Usage & WINED3DUSAGE_SOFTWAREPROCESSING)
2849 UsageCaps |= WINED3DUSAGE_SOFTWAREPROCESSING;
2850
2851 /* Check QUERY_FILTER support */
2852 if(Usage & WINED3DUSAGE_QUERY_FILTER) {
2853 if(CheckFilterCapability(Adapter, CheckFormat)) {
2854 UsageCaps |= WINED3DUSAGE_QUERY_FILTER;
2855 } else {
2856 TRACE_(d3d_caps)("[FAILED] - No query filter support\n");
2857 return WINED3DERR_NOTAVAILABLE;
2858 }
2859 }
2860
2861 /* Check QUERY_POSTPIXELSHADER_BLENDING support */
2862 if(Usage & WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING) {
2863 if(CheckPostPixelShaderBlendingCapability(Adapter, CheckFormat)) {
2864 UsageCaps |= WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING;
2865 } else {
2866 TRACE_(d3d_caps)("[FAILED] - No query post pixelshader blending support\n");
2867 return WINED3DERR_NOTAVAILABLE;
2868 }
2869 }
2870
2871 /* Check QUERY_SRGBREAD support */
2872 if(Usage & WINED3DUSAGE_QUERY_SRGBREAD) {
2873 if(CheckSrgbReadCapability(Adapter, CheckFormat)) {
2874 UsageCaps |= WINED3DUSAGE_QUERY_SRGBREAD;
2875 } else {
2876 TRACE_(d3d_caps)("[FAILED] - No query srgbread support\n");
2877 return WINED3DERR_NOTAVAILABLE;
2878 }
2879 }
2880
2881 /* Check QUERY_SRGBWRITE support */
2882 if(Usage & WINED3DUSAGE_QUERY_SRGBWRITE) {
2883 if(CheckSrgbWriteCapability(Adapter, DeviceType, CheckFormat)) {
2884 UsageCaps |= WINED3DUSAGE_QUERY_SRGBWRITE;
2885 } else {
2886 TRACE_(d3d_caps)("[FAILED] - No query srgbwrite support\n");
2887 return WINED3DERR_NOTAVAILABLE;
2888 }
2889 }
2890
2891 /* Check QUERY_VERTEXTEXTURE support */
2892 if(Usage & WINED3DUSAGE_QUERY_VERTEXTEXTURE) {
2893 if(CheckVertexTextureCapability(Adapter, CheckFormat)) {
2894 UsageCaps |= WINED3DUSAGE_QUERY_VERTEXTEXTURE;
2895 } else {
2896 TRACE_(d3d_caps)("[FAILED] - No query vertextexture support\n");
2897 return WINED3DERR_NOTAVAILABLE;
2898 }
2899 }
2900
2901 /* Check QUERY_WRAPANDMIP support */
2902 if(Usage & WINED3DUSAGE_QUERY_WRAPANDMIP) {
2903 if(CheckWrapAndMipCapability(Adapter, CheckFormat)) {
2904 UsageCaps |= WINED3DUSAGE_QUERY_WRAPANDMIP;
2905 } else {
2906 TRACE_(d3d_caps)("[FAILED] - No wrapping and mipmapping support\n");
2907 return WINED3DERR_NOTAVAILABLE;
2908 }
2909 }
2910 } else {
2911 TRACE_(d3d_caps)("[FAILED] - No volume texture support\n");
2912 return WINED3DERR_NOTAVAILABLE;
2913 }
2914
2915 /* Filter formats that need conversion; For one part, this conversion is unimplemented,
2916 * and volume textures are huge, so it would be a big performance hit. Unless we hit an
2917 * app needing one of those formats, don't advertize them to avoid leading apps into
2918 * temptation. The windows drivers don't support most of those formats on volumes anyway,
2919 * except of R32F.
2920 */
2921 switch(CheckFormat) {
2922 case WINED3DFMT_P8:
2923 case WINED3DFMT_A4L4:
2924 case WINED3DFMT_R32F:
2925 case WINED3DFMT_R16F:
2926 case WINED3DFMT_X8L8V8U8:
2927 case WINED3DFMT_L6V5U5:
2928 case WINED3DFMT_G16R16:
2929 TRACE_(d3d_caps)("[FAILED] - No converted formats on volumes\n");
2930 return WINED3DERR_NOTAVAILABLE;
2931
2932 case WINED3DFMT_Q8W8V8U8:
2933 case WINED3DFMT_V16U16:
2934 if(!GL_SUPPORT(NV_TEXTURE_SHADER)) {
2935 TRACE_(d3d_caps)("[FAILED] - No converted formats on volumes\n");
2936 return WINED3DERR_NOTAVAILABLE;
2937 }
2938 break;
2939
2940 case WINED3DFMT_V8U8:
2941 if(!GL_SUPPORT(NV_TEXTURE_SHADER)) {
2942 TRACE_(d3d_caps)("[FAILED] - No converted formats on volumes\n");
2943 return WINED3DERR_NOTAVAILABLE;
2944 }
2945 break;
2946
2947 case WINED3DFMT_DXT1:
2948 case WINED3DFMT_DXT2:
2949 case WINED3DFMT_DXT3:
2950 case WINED3DFMT_DXT4:
2951 case WINED3DFMT_DXT5:
2952 /* The GL_EXT_texture_compression_s3tc spec requires that loading an s3tc
2953 * compressed texture results in an error. While the D3D refrast does
2954 * support s3tc volumes, at least the nvidia windows driver does not, so
2955 * we're free not to support this format.
2956 */
2957 TRACE_(d3d_caps)("[FAILED] - DXTn does not support 3D textures\n");
2958 return WINED3DERR_NOTAVAILABLE;
2959
2960 default:
2961 /* Do nothing, continue with checking the format below */
2962 break;
2963 }
2964 } else if((RType == WINED3DRTYPE_INDEXBUFFER) || (RType == WINED3DRTYPE_VERTEXBUFFER)){
2965 /* For instance vertexbuffer/indexbuffer aren't supported yet because no Windows drivers seem to offer it */
2966 TRACE_(d3d_caps)("Unhandled resource type D3DRTYPE_INDEXBUFFER / D3DRTYPE_VERTEXBUFFER\n");
2967 return WINED3DERR_NOTAVAILABLE;
2968 }
2969
2970 /* This format is nothing special and it is supported perfectly.
2971 * However, ati and nvidia driver on windows do not mark this format as
2972 * supported (tested with the dxCapsViewer) and pretending to
2973 * support this format uncovers a bug in Battlefield 1942 (fonts are missing)
2974 * So do the same as Windows drivers and pretend not to support it on dx8 and 9
2975 * Enable it on dx7. It will need additional checking on dx10 when we support it.
2976 */
2977 if(This->dxVersion > 7 && CheckFormat == WINED3DFMT_R8G8B8) {
2978 TRACE_(d3d_caps)("[FAILED]\n");
2979 return WINED3DERR_NOTAVAILABLE;
2980 }
2981
2982 /* When the UsageCaps exactly matches Usage return WINED3D_OK except for the situation in which
2983 * WINED3DUSAGE_AUTOGENMIPMAP isn't around, then WINED3DOK_NOAUTOGEN is returned if all the other
2984 * usage flags match. */
2985 if(UsageCaps == Usage) {
2986 return WINED3D_OK;
2987 } else if((UsageCaps == (Usage & ~WINED3DUSAGE_AUTOGENMIPMAP)) && (Usage & WINED3DUSAGE_AUTOGENMIPMAP)){
2988 return WINED3DOK_NOAUTOGEN;
2989 } else {
2990 TRACE_(d3d_caps)("[FAILED] - Usage=%#08x requested for CheckFormat=%s and RType=%d but only %#08x is available\n", Usage, debug_d3dformat(CheckFormat), RType, UsageCaps);
2991 return WINED3DERR_NOTAVAILABLE;
2992 }
2993 }
2994
2995 static HRESULT WINAPI IWineD3DImpl_CheckDeviceFormatConversion(IWineD3D *iface, UINT Adapter, WINED3DDEVTYPE DeviceType,
2996 WINED3DFORMAT SourceFormat, WINED3DFORMAT TargetFormat) {
2997 IWineD3DImpl *This = (IWineD3DImpl *)iface;
2998
2999 FIXME_(d3d_caps)("(%p)-> (STUB) (Adptr:%d, DevType:(%u,%s), SrcFmt:(%u,%s), TgtFmt:(%u,%s))\n",
3000 This,
3001 Adapter,
3002 DeviceType, debug_d3ddevicetype(DeviceType),
3003 SourceFormat, debug_d3dformat(SourceFormat),
3004 TargetFormat, debug_d3dformat(TargetFormat));
3005 return WINED3D_OK;
3006 }
3007
3008 static const shader_backend_t *select_shader_backend(UINT Adapter, WINED3DDEVTYPE DeviceType) {
3009 const shader_backend_t *ret;
3010 int vs_selected_mode;
3011 int ps_selected_mode;
3012
3013 select_shader_mode(&GLINFO_LOCATION, DeviceType, &ps_selected_mode, &vs_selected_mode);
3014 if (vs_selected_mode == SHADER_GLSL || ps_selected_mode == SHADER_GLSL) {
3015 ret = &glsl_shader_backend;
3016 } else if (vs_selected_mode == SHADER_ARB || ps_selected_mode == SHADER_ARB) {
3017 ret = &arb_program_shader_backend;
3018 } else {
3019 ret = &none_shader_backend;
3020 }
3021 return ret;
3022 }
3023
3024 static const struct fragment_pipeline *select_fragment_implementation(UINT Adapter, WINED3DDEVTYPE DeviceType) {
3025 int vs_selected_mode;
3026 int ps_selected_mode;
3027
3028 select_shader_mode(&GLINFO_LOCATION, DeviceType, &ps_selected_mode, &vs_selected_mode);
3029 if((ps_selected_mode == SHADER_ARB || ps_selected_mode == SHADER_GLSL) && GL_SUPPORT(ARB_FRAGMENT_PROGRAM)) {
3030 return &arbfp_fragment_pipeline;
3031 } else if(ps_selected_mode == SHADER_ATI) {
3032 return &atifs_fragment_pipeline;
3033 } else if(GL_SUPPORT(NV_REGISTER_COMBINERS) && GL_SUPPORT(NV_TEXTURE_SHADER2)) {
3034 return &nvts_fragment_pipeline;
3035 } else if(GL_SUPPORT(NV_REGISTER_COMBINERS)) {
3036 return &nvrc_fragment_pipeline;
3037 } else {
3038 return &ffp_fragment_pipeline;
3039 }
3040 }
3041
3042 static const struct blit_shader *select_blit_implementation(UINT Adapter, WINED3DDEVTYPE DeviceType) {
3043 int vs_selected_mode;
3044 int ps_selected_mode;
3045
3046 select_shader_mode(&GLINFO_LOCATION, DeviceType, &ps_selected_mode, &vs_selected_mode);
3047 if((ps_selected_mode == SHADER_ARB || ps_selected_mode == SHADER_GLSL) && GL_SUPPORT(ARB_FRAGMENT_PROGRAM)) {
3048 return &arbfp_blit;
3049 } else {
3050 return &ffp_blit;
3051 }
3052 }
3053
3054 /* Note: d3d8 passes in a pointer to a D3DCAPS8 structure, which is a true
3055 subset of a D3DCAPS9 structure. However, it has to come via a void *
3056 as the d3d8 interface cannot import the d3d9 header */
3057 static HRESULT WINAPI IWineD3DImpl_GetDeviceCaps(IWineD3D *iface, UINT Adapter, WINED3DDEVTYPE DeviceType, WINED3DCAPS* pCaps) {
3058
3059 IWineD3DImpl *This = (IWineD3DImpl *)iface;
3060 int vs_selected_mode;
3061 int ps_selected_mode;
3062 struct shader_caps shader_caps;
3063 struct fragment_caps fragment_caps;
3064 const shader_backend_t *shader_backend;
3065 const struct fragment_pipeline *frag_pipeline = NULL;
3066 DWORD ckey_caps, blit_caps, fx_caps;
3067
3068 TRACE_(d3d_caps)("(%p)->(Adptr:%d, DevType: %x, pCaps: %p)\n", This, Adapter, DeviceType, pCaps);
3069
3070 if (Adapter >= IWineD3D_GetAdapterCount(iface)) {
3071 return WINED3DERR_INVALIDCALL;
3072 }
3073
3074 select_shader_mode(&Adapters[Adapter].gl_info, DeviceType, &ps_selected_mode, &vs_selected_mode);
3075
3076 /* This function should *not* be modifying GL caps
3077 * TODO: move the functionality where it belongs */
3078 select_shader_max_constants(ps_selected_mode, vs_selected_mode, &Adapters[Adapter].gl_info);
3079
3080 /* ------------------------------------------------
3081 The following fields apply to both d3d8 and d3d9
3082 ------------------------------------------------ */
3083 pCaps->DeviceType = (DeviceType == WINED3DDEVTYPE_HAL) ? WINED3DDEVTYPE_HAL : WINED3DDEVTYPE_REF; /* Not quite true, but use h/w supported by opengl I suppose */
3084 pCaps->AdapterOrdinal = Adapter;
3085
3086 pCaps->Caps = 0;
3087 pCaps->Caps2 = WINED3DCAPS2_CANRENDERWINDOWED |
3088 WINED3DCAPS2_FULLSCREENGAMMA |
3089 WINED3DCAPS2_DYNAMICTEXTURES;
3090 if(GL_SUPPORT(SGIS_GENERATE_MIPMAP)) {
3091 pCaps->Caps2 |= WINED3DCAPS2_CANAUTOGENMIPMAP;
3092 }
3093
3094 pCaps->Caps3 = WINED3DCAPS3_ALPHA_FULLSCREEN_FLIP_OR_DISCARD |
3095 WINED3DCAPS3_COPY_TO_VIDMEM |
3096 WINED3DCAPS3_COPY_TO_SYSTEMMEM;
3097
3098 pCaps->PresentationIntervals = WINED3DPRESENT_INTERVAL_IMMEDIATE |
3099 WINED3DPRESENT_INTERVAL_ONE;
3100
3101 pCaps->CursorCaps = WINED3DCURSORCAPS_COLOR |
3102 WINED3DCURSORCAPS_LOWRES;
3103
3104 pCaps->DevCaps = WINED3DDEVCAPS_FLOATTLVERTEX |
3105 WINED3DDEVCAPS_EXECUTESYSTEMMEMORY |
3106 WINED3DDEVCAPS_TLVERTEXSYSTEMMEMORY|
3107 WINED3DDEVCAPS_TLVERTEXVIDEOMEMORY |
3108 WINED3DDEVCAPS_DRAWPRIMTLVERTEX |
3109 WINED3DDEVCAPS_HWTRANSFORMANDLIGHT |
3110 WINED3DDEVCAPS_EXECUTEVIDEOMEMORY |
3111 WINED3DDEVCAPS_PUREDEVICE |
3112 WINED3DDEVCAPS_HWRASTERIZATION |
3113 WINED3DDEVCAPS_TEXTUREVIDEOMEMORY |
3114 WINED3DDEVCAPS_TEXTURESYSTEMMEMORY |
3115 WINED3DDEVCAPS_CANRENDERAFTERFLIP |
3116 WINED3DDEVCAPS_DRAWPRIMITIVES2 |
3117 WINED3DDEVCAPS_DRAWPRIMITIVES2EX |
3118 WINED3DDEVCAPS_RTPATCHES;
3119
3120 pCaps->PrimitiveMiscCaps = WINED3DPMISCCAPS_CULLNONE |
3121 WINED3DPMISCCAPS_CULLCCW |
3122 WINED3DPMISCCAPS_CULLCW |
3123 WINED3DPMISCCAPS_COLORWRITEENABLE |
3124 WINED3DPMISCCAPS_CLIPTLVERTS |
3125 WINED3DPMISCCAPS_CLIPPLANESCALEDPOINTS |
3126 WINED3DPMISCCAPS_MASKZ |
3127 WINED3DPMISCCAPS_BLENDOP |
3128 WINED3DPMISCCAPS_MRTPOSTPIXELSHADERBLENDING;
3129 /* TODO:
3130 WINED3DPMISCCAPS_NULLREFERENCE
3131 WINED3DPMISCCAPS_INDEPENDENTWRITEMASKS
3132 WINED3DPMISCCAPS_FOGANDSPECULARALPHA
3133 WINED3DPMISCCAPS_MRTINDEPENDENTBITDEPTHS
3134 WINED3DPMISCCAPS_FOGVERTEXCLAMPED */
3135
3136 if(GL_SUPPORT(EXT_BLEND_EQUATION_SEPARATE) && GL_SUPPORT(EXT_BLEND_FUNC_SEPARATE))
3137 pCaps->PrimitiveMiscCaps |= WINED3DPMISCCAPS_SEPARATEALPHABLEND;
3138
3139 pCaps->RasterCaps = WINED3DPRASTERCAPS_DITHER |
3140 WINED3DPRASTERCAPS_PAT |
3141 WINED3DPRASTERCAPS_WFOG |
3142 WINED3DPRASTERCAPS_ZFOG |
3143 WINED3DPRASTERCAPS_FOGVERTEX |
3144 WINED3DPRASTERCAPS_FOGTABLE |
3145 WINED3DPRASTERCAPS_STIPPLE |
3146 WINED3DPRASTERCAPS_SUBPIXEL |
3147 WINED3DPRASTERCAPS_ZTEST |
3148 WINED3DPRASTERCAPS_SCISSORTEST |
3149 WINED3DPRASTERCAPS_SLOPESCALEDEPTHBIAS |
3150 WINED3DPRASTERCAPS_DEPTHBIAS;
3151
3152 if (GL_SUPPORT(EXT_TEXTURE_FILTER_ANISOTROPIC)) {
3153 pCaps->RasterCaps |= WINED3DPRASTERCAPS_ANISOTROPY |
3154 WINED3DPRASTERCAPS_ZBIAS |
3155 WINED3DPRASTERCAPS_MIPMAPLODBIAS;
3156 }
3157 if(GL_SUPPORT(NV_FOG_DISTANCE)) {
3158 pCaps->RasterCaps |= WINED3DPRASTERCAPS_FOGRANGE;
3159 }
3160 /* FIXME Add:
3161 WINED3DPRASTERCAPS_COLORPERSPECTIVE
3162 WINED3DPRASTERCAPS_STRETCHBLTMULTISAMPLE
3163 WINED3DPRASTERCAPS_ANTIALIASEDGES
3164 WINED3DPRASTERCAPS_ZBUFFERLESSHSR
3165 WINED3DPRASTERCAPS_WBUFFER */
3166
3167 pCaps->ZCmpCaps = WINED3DPCMPCAPS_ALWAYS |
3168 WINED3DPCMPCAPS_EQUAL |
3169 WINED3DPCMPCAPS_GREATER |
3170 WINED3DPCMPCAPS_GREATEREQUAL |
3171 WINED3DPCMPCAPS_LESS |
3172 WINED3DPCMPCAPS_LESSEQUAL |
3173 WINED3DPCMPCAPS_NEVER |
3174 WINED3DPCMPCAPS_NOTEQUAL;
3175
3176 pCaps->SrcBlendCaps = WINED3DPBLENDCAPS_BOTHINVSRCALPHA |
3177 WINED3DPBLENDCAPS_BOTHSRCALPHA |
3178 WINED3DPBLENDCAPS_DESTALPHA |
3179 WINED3DPBLENDCAPS_DESTCOLOR |
3180 WINED3DPBLENDCAPS_INVDESTALPHA |
3181 WINED3DPBLENDCAPS_INVDESTCOLOR |
3182 WINED3DPBLENDCAPS_INVSRCALPHA |
3183 WINED3DPBLENDCAPS_INVSRCCOLOR |
3184 WINED3DPBLENDCAPS_ONE |
3185 WINED3DPBLENDCAPS_SRCALPHA |
3186 WINED3DPBLENDCAPS_SRCALPHASAT |
3187 WINED3DPBLENDCAPS_SRCCOLOR |
3188 WINED3DPBLENDCAPS_ZERO;
3189
3190 pCaps->DestBlendCaps = WINED3DPBLENDCAPS_DESTALPHA |
3191 WINED3DPBLENDCAPS_DESTCOLOR |
3192 WINED3DPBLENDCAPS_INVDESTALPHA |
3193 WINED3DPBLENDCAPS_INVDESTCOLOR |
3194 WINED3DPBLENDCAPS_INVSRCALPHA |
3195 WINED3DPBLENDCAPS_INVSRCCOLOR |
3196 WINED3DPBLENDCAPS_ONE |
3197 WINED3DPBLENDCAPS_SRCALPHA |
3198 WINED3DPBLENDCAPS_SRCCOLOR |
3199 WINED3DPBLENDCAPS_ZERO;
3200 /* NOTE: WINED3DPBLENDCAPS_SRCALPHASAT is not supported as dest blend factor,
3201 * according to the glBlendFunc manpage
3202 *
3203 * WINED3DPBLENDCAPS_BOTHINVSRCALPHA and WINED3DPBLENDCAPS_BOTHSRCALPHA are
3204 * legacy settings for srcblend only
3205 */
3206
3207 if( GL_SUPPORT(EXT_BLEND_COLOR)) {
3208 pCaps->SrcBlendCaps |= WINED3DPBLENDCAPS_BLENDFACTOR;
3209 pCaps->DestBlendCaps |= WINED3DPBLENDCAPS_BLENDFACTOR;
3210 }
3211
3212
3213 pCaps->AlphaCmpCaps = WINED3DPCMPCAPS_ALWAYS |
3214 WINED3DPCMPCAPS_EQUAL |
3215 WINED3DPCMPCAPS_GREATER |
3216 WINED3DPCMPCAPS_GREATEREQUAL |
3217 WINED3DPCMPCAPS_LESS |
3218 WINED3DPCMPCAPS_LESSEQUAL |
3219 WINED3DPCMPCAPS_NEVER |
3220 WINED3DPCMPCAPS_NOTEQUAL;
3221
3222 pCaps->ShadeCaps = WINED3DPSHADECAPS_SPECULARGOURAUDRGB |
3223 WINED3DPSHADECAPS_COLORGOURAUDRGB |
3224 WINED3DPSHADECAPS_ALPHAFLATBLEND |
3225 WINED3DPSHADECAPS_ALPHAGOURAUDBLEND |
3226 WINED3DPSHADECAPS_COLORFLATRGB |
3227 WINED3DPSHADECAPS_FOGFLAT |
3228 WINED3DPSHADECAPS_FOGGOURAUD |
3229 WINED3DPSHADECAPS_SPECULARFLATRGB;
3230
3231 pCaps->TextureCaps = WINED3DPTEXTURECAPS_ALPHA |
3232 WINED3DPTEXTURECAPS_ALPHAPALETTE |
3233 WINED3DPTEXTURECAPS_TRANSPARENCY |
3234 WINED3DPTEXTURECAPS_BORDER |
3235 WINED3DPTEXTURECAPS_MIPMAP |
3236 WINED3DPTEXTURECAPS_PROJECTED |
3237 WINED3DPTEXTURECAPS_PERSPECTIVE;
3238
3239 if( !GL_SUPPORT(ARB_TEXTURE_NON_POWER_OF_TWO)) {
3240 pCaps->TextureCaps |= WINED3DPTEXTURECAPS_POW2 |
3241 WINED3DPTEXTURECAPS_NONPOW2CONDITIONAL;
3242 }
3243
3244 if( GL_SUPPORT(EXT_TEXTURE3D)) {
3245 pCaps->TextureCaps |= WINED3DPTEXTURECAPS_VOLUMEMAP |
3246 WINED3DPTEXTURECAPS_MIPVOLUMEMAP |
3247 WINED3DPTEXTURECAPS_VOLUMEMAP_POW2;
3248 }
3249
3250 if (GL_SUPPORT(ARB_TEXTURE_CUBE_MAP)) {
3251 pCaps->TextureCaps |= WINED3DPTEXTURECAPS_CUBEMAP |
3252 WINED3DPTEXTURECAPS_MIPCUBEMAP |
3253 WINED3DPTEXTURECAPS_CUBEMAP_POW2;
3254
3255 }
3256
3257 pCaps->TextureFilterCaps = WINED3DPTFILTERCAPS_MAGFLINEAR |
3258 WINED3DPTFILTERCAPS_MAGFPOINT |
3259 WINED3DPTFILTERCAPS_MINFLINEAR |
3260 WINED3DPTFILTERCAPS_MINFPOINT |
3261 WINED3DPTFILTERCAPS_MIPFLINEAR |
3262 WINED3DPTFILTERCAPS_MIPFPOINT |
3263 WINED3DPTFILTERCAPS_LINEAR |
3264 WINED3DPTFILTERCAPS_LINEARMIPLINEAR |
3265 WINED3DPTFILTERCAPS_LINEARMIPNEAREST |
3266 WINED3DPTFILTERCAPS_MIPLINEAR |
3267 WINED3DPTFILTERCAPS_MIPNEAREST |
3268 WINED3DPTFILTERCAPS_NEAREST;
3269
3270 if (GL_SUPPORT(EXT_TEXTURE_FILTER_ANISOTROPIC)) {
3271 pCaps->TextureFilterCaps |= WINED3DPTFILTERCAPS_MAGFANISOTROPIC |
3272 WINED3DPTFILTERCAPS_MINFANISOTROPIC;
3273 }
3274
3275 if (GL_SUPPORT(ARB_TEXTURE_CUBE_MAP)) {
3276 pCaps->CubeTextureFilterCaps = WINED3DPTFILTERCAPS_MAGFLINEAR |
3277 WINED3DPTFILTERCAPS_MAGFPOINT |
3278 WINED3DPTFILTERCAPS_MINFLINEAR |
3279 WINED3DPTFILTERCAPS_MINFPOINT |
3280 WINED3DPTFILTERCAPS_MIPFLINEAR |
3281 WINED3DPTFILTERCAPS_MIPFPOINT |
3282 WINED3DPTFILTERCAPS_LINEAR |
3283 WINED3DPTFILTERCAPS_LINEARMIPLINEAR |
3284 WINED3DPTFILTERCAPS_LINEARMIPNEAREST |
3285 WINED3DPTFILTERCAPS_MIPLINEAR |
3286 WINED3DPTFILTERCAPS_MIPNEAREST |
3287 WINED3DPTFILTERCAPS_NEAREST;
3288
3289 if (GL_SUPPORT(EXT_TEXTURE_FILTER_ANISOTROPIC)) {
3290 pCaps->CubeTextureFilterCaps |= WINED3DPTFILTERCAPS_MAGFANISOTROPIC |
3291 WINED3DPTFILTERCAPS_MINFANISOTROPIC;
3292 }
3293 } else
3294 pCaps->CubeTextureFilterCaps = 0;
3295
3296 if (GL_SUPPORT(EXT_TEXTURE3D)) {
3297 pCaps->VolumeTextureFilterCaps = WINED3DPTFILTERCAPS_MAGFLINEAR |
3298 WINED3DPTFILTERCAPS_MAGFPOINT |
3299 WINED3DPTFILTERCAPS_MINFLINEAR |
3300 WINED3DPTFILTERCAPS_MINFPOINT |
3301 WINED3DPTFILTERCAPS_MIPFLINEAR |
3302 WINED3DPTFILTERCAPS_MIPFPOINT |
3303 WINED3DPTFILTERCAPS_LINEAR |
3304 WINED3DPTFILTERCAPS_LINEARMIPLINEAR |
3305 WINED3DPTFILTERCAPS_LINEARMIPNEAREST |
3306 WINED3DPTFILTERCAPS_MIPLINEAR |
3307 WINED3DPTFILTERCAPS_MIPNEAREST |
3308 WINED3DPTFILTERCAPS_NEAREST;
3309 } else
3310 pCaps->VolumeTextureFilterCaps = 0;
3311
3312 pCaps->TextureAddressCaps = WINED3DPTADDRESSCAPS_INDEPENDENTUV |
3313 WINED3DPTADDRESSCAPS_CLAMP |
3314 WINED3DPTADDRESSCAPS_WRAP;
3315
3316 if (GL_SUPPORT(ARB_TEXTURE_BORDER_CLAMP)) {
3317 pCaps->TextureAddressCaps |= WINED3DPTADDRESSCAPS_BORDER;
3318 }
3319 if (GL_SUPPORT(ARB_TEXTURE_MIRRORED_REPEAT)) {
3320 pCaps->TextureAddressCaps |= WINED3DPTADDRESSCAPS_MIRROR;
3321 }
3322 if (GL_SUPPORT(ATI_TEXTURE_MIRROR_ONCE)) {
3323 pCaps->TextureAddressCaps |= WINED3DPTADDRESSCAPS_MIRRORONCE;
3324 }
3325
3326 if (GL_SUPPORT(EXT_TEXTURE3D)) {
3327 pCaps->VolumeTextureAddressCaps = WINED3DPTADDRESSCAPS_INDEPENDENTUV |
3328 WINED3DPTADDRESSCAPS_CLAMP |
3329 WINED3DPTADDRESSCAPS_WRAP;
3330 if (GL_SUPPORT(ARB_TEXTURE_BORDER_CLAMP)) {
3331 pCaps->VolumeTextureAddressCaps |= WINED3DPTADDRESSCAPS_BORDER;
3332 }
3333 if (GL_SUPPORT(ARB_TEXTURE_MIRRORED_REPEAT)) {
3334 pCaps->VolumeTextureAddressCaps |= WINED3DPTADDRESSCAPS_MIRROR;
3335 }
3336 if (GL_SUPPORT(ATI_TEXTURE_MIRROR_ONCE)) {
3337 pCaps->VolumeTextureAddressCaps |= WINED3DPTADDRESSCAPS_MIRRORONCE;
3338 }
3339 } else
3340 pCaps->VolumeTextureAddressCaps = 0;
3341
3342 pCaps->LineCaps = WINED3DLINECAPS_TEXTURE |
3343 WINED3DLINECAPS_ZTEST |
3344 WINED3DLINECAPS_BLEND |
3345 WINED3DLINECAPS_ALPHACMP |
3346 WINED3DLINECAPS_FOG;
3347 /* WINED3DLINECAPS_ANTIALIAS is not supported on Windows, and dx and gl seem to have a different
3348 * idea how generating the smoothing alpha values works; the result is different
3349 */
3350
3351 pCaps->MaxTextureWidth = GL_LIMITS(texture_size);
3352 pCaps->MaxTextureHeight = GL_LIMITS(texture_size);
3353
3354 if(GL_SUPPORT(EXT_TEXTURE3D))
3355 pCaps->MaxVolumeExtent = GL_LIMITS(texture3d_size);
3356 else
3357 pCaps->MaxVolumeExtent = 0;
3358
3359 pCaps->MaxTextureRepeat = 32768;
3360 pCaps->MaxTextureAspectRatio = GL_LIMITS(texture_size);
3361 pCaps->MaxVertexW = 1.0;
3362
3363 pCaps->GuardBandLeft = 0;
3364 pCaps->GuardBandTop = 0;
3365 pCaps->GuardBandRight = 0;
3366 pCaps->GuardBandBottom = 0;
3367
3368 pCaps->ExtentsAdjust = 0;
3369
3370 pCaps->StencilCaps = WINED3DSTENCILCAPS_DECRSAT |
3371 WINED3DSTENCILCAPS_INCRSAT |
3372 WINED3DSTENCILCAPS_INVERT |
3373 WINED3DSTENCILCAPS_KEEP |
3374 WINED3DSTENCILCAPS_REPLACE |
3375 WINED3DSTENCILCAPS_ZERO;
3376 if (GL_SUPPORT(EXT_STENCIL_WRAP)) {
3377 pCaps->StencilCaps |= WINED3DSTENCILCAPS_DECR |
3378 WINED3DSTENCILCAPS_INCR;
3379 }
3380 if ( This->dxVersion > 8 &&
3381 ( GL_SUPPORT(EXT_STENCIL_TWO_SIDE) ||
3382 GL_SUPPORT(ATI_SEPARATE_STENCIL) ) ) {
3383 pCaps->StencilCaps |= WINED3DSTENCILCAPS_TWOSIDED;
3384 }
3385
3386 pCaps->FVFCaps = WINED3DFVFCAPS_PSIZE | 0x0008; /* 8 texture coords */
3387
3388 pCaps->MaxUserClipPlanes = GL_LIMITS(clipplanes);
3389 pCaps->MaxActiveLights = GL_LIMITS(lights);
3390
3391 pCaps->MaxVertexBlendMatrices = GL_LIMITS(blends);
3392 pCaps->MaxVertexBlendMatrixIndex = 0;
3393
3394 pCaps->MaxAnisotropy = GL_LIMITS(anisotropy);
3395 pCaps->MaxPointSize = GL_LIMITS(pointsize);
3396
3397
3398 pCaps->VertexProcessingCaps = WINED3DVTXPCAPS_DIRECTIONALLIGHTS |
3399 WINED3DVTXPCAPS_MATERIALSOURCE7 |
3400 WINED3DVTXPCAPS_POSITIONALLIGHTS |
3401 WINED3DVTXPCAPS_LOCALVIEWER |
3402 WINED3DVTXPCAPS_VERTEXFOG |
3403 WINED3DVTXPCAPS_TEXGEN;
3404 /* FIXME: Add
3405 D3DVTXPCAPS_TWEENING, D3DVTXPCAPS_TEXGEN_SPHEREMAP */
3406
3407 pCaps->MaxPrimitiveCount = 0xFFFFF; /* For now set 2^20-1 which is used by most >=Geforce3/Radeon8500 cards */
3408 pCaps->MaxVertexIndex = 0xFFFFF;
3409 pCaps->MaxStreams = MAX_STREAMS;
3410 pCaps->MaxStreamStride = 1024;
3411
3412 /* d3d9.dll sets D3DDEVCAPS2_CAN_STRETCHRECT_FROM_TEXTURES here because StretchRects is implemented in d3d9 */
3413 pCaps->DevCaps2 = WINED3DDEVCAPS2_STREAMOFFSET |
3414 WINED3DDEVCAPS2_VERTEXELEMENTSCANSHARESTREAMOFFSET;
3415 pCaps->MaxNpatchTessellationLevel = 0;
3416 pCaps->MasterAdapterOrdinal = 0;
3417 pCaps->AdapterOrdinalInGroup = 0;
3418 pCaps->NumberOfAdaptersInGroup = 1;
3419
3420 pCaps->NumSimultaneousRTs = GL_LIMITS(buffers);
3421
3422 pCaps->StretchRectFilterCaps = WINED3DPTFILTERCAPS_MINFPOINT |
3423 WINED3DPTFILTERCAPS_MAGFPOINT |
3424 WINED3DPTFILTERCAPS_MINFLINEAR |
3425 WINED3DPTFILTERCAPS_MAGFLINEAR;
3426 pCaps->VertexTextureFilterCaps = 0;
3427
3428 memset(&shader_caps, 0, sizeof(shader_caps));
3429 shader_backend = select_shader_backend(Adapter, DeviceType);
3430 shader_backend->shader_get_caps(DeviceType, &GLINFO_LOCATION, &shader_caps);
3431
3432 memset(&fragment_caps, 0, sizeof(fragment_caps));
3433 frag_pipeline = select_fragment_implementation(Adapter, DeviceType);
3434 frag_pipeline->get_caps(DeviceType, &GLINFO_LOCATION, &fragment_caps);
3435
3436 /* Add shader misc caps. Only some of them belong to the shader parts of the pipeline */
3437 pCaps->PrimitiveMiscCaps |= fragment_caps.PrimitiveMiscCaps;
3438
3439 /* This takes care for disabling vertex shader or pixel shader caps while leaving the other one enabled.
3440 * Ignore shader model capabilities if disabled in config
3441 */
3442 if(vs_selected_mode == SHADER_NONE) {
3443 TRACE_(d3d_caps)("Vertex shader disabled in config, reporting version 0.0\n");
3444 pCaps->VertexShaderVersion = WINED3DVS_VERSION(0,0);
3445 pCaps->MaxVertexShaderConst = 0;
3446 } else {
3447 pCaps->VertexShaderVersion = shader_caps.VertexShaderVersion;
3448 pCaps->MaxVertexShaderConst = shader_caps.MaxVertexShaderConst;
3449 }
3450
3451 if(ps_selected_mode == SHADER_NONE) {
3452 TRACE_(d3d_caps)("Pixel shader disabled in config, reporting version 0.0\n");
3453 pCaps->PixelShaderVersion = WINED3DPS_VERSION(0,0);
3454 pCaps->PixelShader1xMaxValue = 0.0;
3455 } else {
3456 pCaps->PixelShaderVersion = shader_caps.PixelShaderVersion;
3457 pCaps->PixelShader1xMaxValue = shader_caps.PixelShader1xMaxValue;
3458 }
3459
3460 pCaps->TextureOpCaps = fragment_caps.TextureOpCaps;
3461 pCaps->MaxTextureBlendStages = fragment_caps.MaxTextureBlendStages;
3462 pCaps->MaxSimultaneousTextures = fragment_caps.MaxSimultaneousTextures;
3463
3464 pCaps->VS20Caps = shader_caps.VS20Caps;
3465 pCaps->MaxVShaderInstructionsExecuted = shader_caps.MaxVShaderInstructionsExecuted;
3466 pCaps->MaxVertexShader30InstructionSlots= shader_caps.MaxVertexShader30InstructionSlots;
3467 pCaps->PS20Caps = shader_caps.PS20Caps;
3468 pCaps->MaxPShaderInstructionsExecuted = shader_caps.MaxPShaderInstructionsExecuted;
3469 pCaps->MaxPixelShader30InstructionSlots = shader_caps.MaxPixelShader30InstructionSlots;
3470
3471 /* The following caps are shader specific, but they are things we cannot detect, or which
3472 * are the same among all shader models. So to avoid code duplication set the shader version
3473 * specific, but otherwise constant caps here
3474 */
3475 if(pCaps->VertexShaderVersion == WINED3DVS_VERSION(3,0)) {
3476 /* Where possible set the caps based on OpenGL extensions and if they aren't set (in case of software rendering)
3477 use the VS 3.0 from MSDN or else if there's OpenGL spec use a hardcoded value minimum VS3.0 value. */
3478 pCaps->VS20Caps.Caps = WINED3DVS20CAPS_PREDICATION;
3479 pCaps->VS20Caps.DynamicFlowControlDepth = WINED3DVS20_MAX_DYNAMICFLOWCONTROLDEPTH; /* VS 3.0 requires MAX_DYNAMICFLOWCONTROLDEPTH (24) */
3480 pCaps->VS20Caps.NumTemps = max(32, GLINFO_LOCATION.vs_arb_max_temps);
3481 pCaps->VS20Caps.StaticFlowControlDepth = WINED3DVS20_MAX_STATICFLOWCONTROLDEPTH ; /* level of nesting in loops / if-statements; VS 3.0 requires MAX (4) */
3482
3483 pCaps->MaxVShaderInstructionsExecuted = 65535; /* VS 3.0 needs at least 65535, some cards even use 2^32-1 */
3484 pCaps->MaxVertexShader30InstructionSlots = max(512, GLINFO_LOCATION.vs_arb_max_instructions);
3485 } else if(pCaps->VertexShaderVersion == WINED3DVS_VERSION(2,0)) {
3486 pCaps->VS20Caps.Caps = 0;
3487 pCaps->VS20Caps.DynamicFlowControlDepth = WINED3DVS20_MIN_DYNAMICFLOWCONTROLDEPTH;
3488 pCaps->VS20Caps.NumTemps = max(12, GLINFO_LOCATION.vs_arb_max_temps);
3489 pCaps->VS20Caps.StaticFlowControlDepth = 1;
3490
3491 pCaps->MaxVShaderInstructionsExecuted = 65535;
3492 pCaps->MaxVertexShader30InstructionSlots = 0;
3493 } else { /* VS 1.x */
3494 pCaps->VS20Caps.Caps = 0;
3495 pCaps->VS20Caps.DynamicFlowControlDepth = 0;
3496 pCaps->VS20Caps.NumTemps = 0;
3497 pCaps->VS20Caps.StaticFlowControlDepth = 0;
3498
3499 pCaps->MaxVShaderInstructionsExecuted = 0;
3500 pCaps->MaxVertexShader30InstructionSlots = 0;
3501 }
3502
3503 if(pCaps->PixelShaderVersion == WINED3DPS_VERSION(3,0)) {
3504 /* Where possible set the caps based on OpenGL extensions and if they aren't set (in case of software rendering)
3505 use the PS 3.0 from MSDN or else if there's OpenGL spec use a hardcoded value minimum PS 3.0 value. */
3506
3507 /* 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 */
3508 pCaps->PS20Caps.Caps = WINED3DPS20CAPS_ARBITRARYSWIZZLE |
3509 WINED3DPS20CAPS_GRADIENTINSTRUCTIONS |
3510 WINED3DPS20CAPS_PREDICATION |
3511 WINED3DPS20CAPS_NODEPENDENTREADLIMIT |
3512 WINED3DPS20CAPS_NOTEXINSTRUCTIONLIMIT;
3513 pCaps->PS20Caps.DynamicFlowControlDepth = WINED3DPS20_MAX_DYNAMICFLOWCONTROLDEPTH; /* PS 3.0 requires MAX_DYNAMICFLOWCONTROLDEPTH (24) */
3514 pCaps->PS20Caps.NumTemps = max(32, GLINFO_LOCATION.ps_arb_max_temps);
3515 pCaps->PS20Caps.StaticFlowControlDepth = WINED3DPS20_MAX_STATICFLOWCONTROLDEPTH; /* PS 3.0 requires MAX_STATICFLOWCONTROLDEPTH (4) */
3516 pCaps->PS20Caps.NumInstructionSlots = WINED3DPS20_MAX_NUMINSTRUCTIONSLOTS; /* PS 3.0 requires MAX_NUMINSTRUCTIONSLOTS (512) */
3517
3518 pCaps->MaxPShaderInstructionsExecuted = 65535;
3519 pCaps->MaxPixelShader30InstructionSlots = max(WINED3DMIN30SHADERINSTRUCTIONS, GLINFO_LOCATION.ps_arb_max_instructions);
3520 } else if(pCaps->PixelShaderVersion == WINED3DPS_VERSION(2,0)) {
3521 /* Below we assume PS2.0 specs, not extended 2.0a(GeforceFX)/2.0b(Radeon R3xx) ones */
3522 pCaps->PS20Caps.Caps = 0;
3523 pCaps->PS20Caps.DynamicFlowControlDepth = 0; /* WINED3DVS20_MIN_DYNAMICFLOWCONTROLDEPTH = 0 */
3524 pCaps->PS20Caps.NumTemps = max(12, GLINFO_LOCATION.ps_arb_max_temps);
3525 pCaps->PS20Caps.StaticFlowControlDepth = WINED3DPS20_MIN_STATICFLOWCONTROLDEPTH; /* Minimum: 1 */
3526 pCaps->PS20Caps.NumInstructionSlots = WINED3DPS20_MIN_NUMINSTRUCTIONSLOTS; /* Minimum number (64 ALU + 32 Texture), a GeforceFX uses 512 */
3527
3528 pCaps->MaxPShaderInstructionsExecuted = 512; /* Minimum value, a GeforceFX uses 1024 */
3529 pCaps->MaxPixelShader30InstructionSlots = 0;
3530 } else { /* PS 1.x */
3531 pCaps->PS20Caps.Caps = 0;
3532 pCaps->PS20Caps.DynamicFlowControlDepth = 0;
3533 pCaps->PS20Caps.NumTemps = 0;
3534 pCaps->PS20Caps.StaticFlowControlDepth = 0;
3535 pCaps->PS20Caps.NumInstructionSlots = 0;
3536
3537 pCaps->MaxPShaderInstructionsExecuted = 0;
3538 pCaps->MaxPixelShader30InstructionSlots = 0;
3539 }
3540
3541 if(pCaps->VertexShaderVersion >= WINED3DVS_VERSION(2,0)) {
3542 /* OpenGL supports all the formats below, perhaps not always
3543 * without conversion, but it supports them.
3544 * Further GLSL doesn't seem to have an official unsigned type so
3545 * don't advertise it yet as I'm not sure how we handle it.
3546 * We might need to add some clamping in the shader engine to
3547 * support it.
3548 * TODO: WINED3DDTCAPS_USHORT2N, WINED3DDTCAPS_USHORT4N, WINED3DDTCAPS_UDEC3, WINED3DDTCAPS_DEC3N */
3549 pCaps->DeclTypes = WINED3DDTCAPS_UBYTE4 |
3550 WINED3DDTCAPS_UBYTE4N |
3551 WINED3DDTCAPS_SHORT2N |
3552 WINED3DDTCAPS_SHORT4N;
3553 if (GL_SUPPORT(NV_HALF_FLOAT)) {
3554 pCaps->DeclTypes |= WINED3DDTCAPS_FLOAT16_2 |
3555 WINED3DDTCAPS_FLOAT16_4;
3556 }
3557 } else
3558 pCaps->DeclTypes = 0;
3559
3560 /* Set DirectDraw helper Caps */
3561 ckey_caps = WINEDDCKEYCAPS_DESTBLT |
3562 WINEDDCKEYCAPS_SRCBLT;
3563 fx_caps = WINEDDFXCAPS_BLTALPHA |
3564 WINEDDFXCAPS_BLTMIRRORLEFTRIGHT |
3565 WINEDDFXCAPS_BLTMIRRORUPDOWN |
3566 WINEDDFXCAPS_BLTROTATION90 |
3567 WINEDDFXCAPS_BLTSHRINKX |
3568 WINEDDFXCAPS_BLTSHRINKXN |
3569 WINEDDFXCAPS_BLTSHRINKY |
3570 WINEDDFXCAPS_BLTSHRINKXN |
3571 WINEDDFXCAPS_BLTSTRETCHX |
3572 WINEDDFXCAPS_BLTSTRETCHXN |
3573 WINEDDFXCAPS_BLTSTRETCHY |
3574 WINEDDFXCAPS_BLTSTRETCHYN;
3575 blit_caps = WINEDDCAPS_BLT |
3576 WINEDDCAPS_BLTCOLORFILL |
3577 WINEDDCAPS_BLTDEPTHFILL |
3578 WINEDDCAPS_BLTSTRETCH |
3579 WINEDDCAPS_CANBLTSYSMEM |
3580 WINEDDCAPS_CANCLIP |
3581 WINEDDCAPS_CANCLIPSTRETCHED |
3582 WINEDDCAPS_COLORKEY |
3583 WINEDDCAPS_COLORKEYHWASSIST |
3584 WINEDDCAPS_ALIGNBOUNDARYSRC;
3585
3586 /* Fill the ddraw caps structure */
3587 pCaps->DirectDrawCaps.Caps = WINEDDCAPS_GDI |
3588 WINEDDCAPS_PALETTE |
3589 blit_caps;
3590 pCaps->DirectDrawCaps.Caps2 = WINEDDCAPS2_CERTIFIED |
3591 WINEDDCAPS2_NOPAGELOCKREQUIRED |
3592 WINEDDCAPS2_PRIMARYGAMMA |
3593 WINEDDCAPS2_WIDESURFACES |
3594 WINEDDCAPS2_CANRENDERWINDOWED;
3595 pCaps->DirectDrawCaps.SVBCaps = blit_caps;
3596 pCaps->DirectDrawCaps.SVBCKeyCaps = ckey_caps;
3597 pCaps->DirectDrawCaps.SVBFXCaps = fx_caps;
3598 pCaps->DirectDrawCaps.VSBCaps = blit_caps;
3599 pCaps->DirectDrawCaps.VSBCKeyCaps = ckey_caps;
3600 pCaps->DirectDrawCaps.VSBFXCaps = fx_caps;
3601 pCaps->DirectDrawCaps.SSBCaps = blit_caps;
3602 pCaps->DirectDrawCaps.SSBCKeyCaps = ckey_caps;
3603 pCaps->DirectDrawCaps.SSBFXCaps = fx_caps;
3604
3605 pCaps->DirectDrawCaps.ddsCaps = WINEDDSCAPS_ALPHA |
3606 WINEDDSCAPS_BACKBUFFER |
3607 WINEDDSCAPS_FLIP |
3608 WINEDDSCAPS_FRONTBUFFER |
3609 WINEDDSCAPS_OFFSCREENPLAIN |
3610 WINEDDSCAPS_PALETTE |
3611 WINEDDSCAPS_PRIMARYSURFACE |
3612 WINEDDSCAPS_SYSTEMMEMORY |
3613 WINEDDSCAPS_VIDEOMEMORY |
3614 WINEDDSCAPS_VISIBLE;
3615 pCaps->DirectDrawCaps.StrideAlign = DDRAW_PITCH_ALIGNMENT;
3616
3617 /* Set D3D caps if OpenGL is available. */
3618 if(Adapters[Adapter].opengl) {
3619 pCaps->DirectDrawCaps.ddsCaps |=WINEDDSCAPS_3DDEVICE |
3620 WINEDDSCAPS_MIPMAP |
3621 WINEDDSCAPS_TEXTURE |
3622 WINEDDSCAPS_ZBUFFER;
3623 pCaps->DirectDrawCaps.Caps |= WINEDDCAPS_3D;
3624 }
3625
3626 return WINED3D_OK;
3627 }
3628
3629 /* Note due to structure differences between dx8 and dx9 D3DPRESENT_PARAMETERS,
3630 and fields being inserted in the middle, a new structure is used in place */
3631 static HRESULT WINAPI IWineD3DImpl_CreateDevice(IWineD3D *iface, UINT Adapter,
3632 WINED3DDEVTYPE DeviceType, HWND hFocusWindow, DWORD BehaviourFlags, IUnknown *parent,
3633 IWineD3DDeviceParent *device_parent, IWineD3DDevice **ppReturnedDeviceInterface)
3634 {
3635 IWineD3DDeviceImpl *object = NULL;
3636 IWineD3DImpl *This = (IWineD3DImpl *)iface;
3637 WINED3DDISPLAYMODE mode;
3638 const struct fragment_pipeline *frag_pipeline = NULL;
3639 int i;
3640 struct fragment_caps ffp_caps;
3641 HRESULT hr;
3642
3643 /* Validate the adapter number. If no adapters are available(no GL), ignore the adapter
3644 * number and create a device without a 3D adapter for 2D only operation.
3645 */
3646 if (IWineD3D_GetAdapterCount(iface) && Adapter >= IWineD3D_GetAdapterCount(iface)) {
3647 return WINED3DERR_INVALIDCALL;
3648 }
3649
3650 /* Create a WineD3DDevice object */
3651 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IWineD3DDeviceImpl));
3652 *ppReturnedDeviceInterface = (IWineD3DDevice *)object;
3653 TRACE("Created WineD3DDevice object @ %p\n", object);
3654 if (NULL == object) {
3655 return WINED3DERR_OUTOFVIDEOMEMORY;
3656 }
3657
3658 /* Set up initial COM information */
3659 object->lpVtbl = &IWineD3DDevice_Vtbl;
3660 object->ref = 1;
3661 object->wineD3D = iface;
3662 object->adapter = numAdapters ? &Adapters[Adapter] : NULL;
3663 IWineD3D_AddRef(object->wineD3D);
3664 object->parent = parent;
3665 object->device_parent = device_parent;
3666 list_init(&object->resources);
3667 list_init(&object->shaders);
3668
3669 if(This->dxVersion == 7) {
3670 object->surface_alignment = DDRAW_PITCH_ALIGNMENT;
3671 } else {
3672 object->surface_alignment = D3D8_PITCH_ALIGNMENT;
3673 }
3674 object->posFixup[0] = 1.0; /* This is needed to get the x coord unmodified through a MAD */
3675
3676 /* Set the state up as invalid until the device is fully created */
3677 object->state = WINED3DERR_DRIVERINTERNALERROR;
3678
3679 TRACE("(%p)->(Adptr:%d, DevType: %x, FocusHwnd: %p, BehFlags: %x, RetDevInt: %p)\n", This, Adapter, DeviceType,
3680 hFocusWindow, BehaviourFlags, ppReturnedDeviceInterface);
3681
3682 /* Save the creation parameters */
3683 object->createParms.AdapterOrdinal = Adapter;
3684 object->createParms.DeviceType = DeviceType;
3685 object->createParms.hFocusWindow = hFocusWindow;
3686 object->createParms.BehaviorFlags = BehaviourFlags;
3687
3688 /* Initialize other useful values */
3689 object->adapterNo = Adapter;
3690 object->devType = DeviceType;
3691
3692 select_shader_mode(&GLINFO_LOCATION, DeviceType, &object->ps_selected_mode, &object->vs_selected_mode);
3693 object->shader_backend = select_shader_backend(Adapter, DeviceType);
3694
3695 memset(&ffp_caps, 0, sizeof(ffp_caps));
3696 frag_pipeline = select_fragment_implementation(Adapter, DeviceType);
3697 object->frag_pipe = frag_pipeline;
3698 frag_pipeline->get_caps(DeviceType, &GLINFO_LOCATION, &ffp_caps);
3699 object->max_ffp_textures = ffp_caps.MaxSimultaneousTextures;
3700 object->max_ffp_texture_stages = ffp_caps.MaxTextureBlendStages;
3701 hr = compile_state_table(object->StateTable, object->multistate_funcs, &GLINFO_LOCATION,
3702 ffp_vertexstate_template, frag_pipeline, misc_state_template);
3703
3704 if (FAILED(hr)) {
3705 IWineD3D_Release(object->wineD3D);
3706 HeapFree(GetProcessHeap(), 0, object);
3707
3708 return hr;
3709 }
3710
3711 object->blitter = select_blit_implementation(Adapter, DeviceType);
3712
3713 /* set the state of the device to valid */
3714 object->state = WINED3D_OK;
3715
3716 /* Get the initial screen setup for ddraw */
3717 IWineD3DImpl_GetAdapterDisplayMode(iface, Adapter, &mode);
3718
3719 object->ddraw_width = mode.Width;
3720 object->ddraw_height = mode.Height;
3721 object->ddraw_format = mode.Format;
3722
3723 for(i = 0; i < PATCHMAP_SIZE; i++) {
3724 list_init(&object->patches[i]);
3725 }
3726 return WINED3D_OK;
3727 }
3728 #undef GLINFO_LOCATION
3729
3730 static HRESULT WINAPI IWineD3DImpl_GetParent(IWineD3D *iface, IUnknown **pParent) {
3731 IWineD3DImpl *This = (IWineD3DImpl *)iface;
3732 IUnknown_AddRef(This->parent);
3733 *pParent = This->parent;
3734 return WINED3D_OK;
3735 }
3736
3737 ULONG WINAPI D3DCB_DefaultDestroySurface(IWineD3DSurface *pSurface) {
3738 IUnknown* surfaceParent;
3739 TRACE("(%p) call back\n", pSurface);
3740
3741 /* Now, release the parent, which will take care of cleaning up the surface for us */
3742 IWineD3DSurface_GetParent(pSurface, &surfaceParent);
3743 IUnknown_Release(surfaceParent);
3744 return IUnknown_Release(surfaceParent);
3745 }
3746
3747 ULONG WINAPI D3DCB_DefaultDestroyVolume(IWineD3DVolume *pVolume) {
3748 IUnknown* volumeParent;
3749 TRACE("(%p) call back\n", pVolume);
3750
3751 /* Now, release the parent, which will take care of cleaning up the volume for us */
3752 IWineD3DVolume_GetParent(pVolume, &volumeParent);
3753 IUnknown_Release(volumeParent);
3754 return IUnknown_Release(volumeParent);
3755 }
3756
3757 static BOOL implementation_is_apple(const WineD3D_GL_Info *gl_info)
3758 {
3759 /* MacOS has various specialities in the extensions it advertises. Some have to be loaded from
3760 * the opengl 1.2+ core, while other extensions are advertised, but software emulated. So try to
3761 * detect the Apple OpenGL implementation to apply some extension fixups afterwards.
3762 *
3763 * Detecting this isn't really easy. The vendor string doesn't mention Apple. Compile-time checks
3764 * aren't sufficient either because a Linux binary may display on a macos X server via remote X11.
3765 * So try to detect the GL implementation by looking at certain Apple extensions. Some extensions
3766 * like client storage might be supported on other implementations too, but GL_APPLE_flush_render
3767 * is specific to the Mac OS X window management, and GL_APPLE_ycbcr_422 is QuickTime specific. So
3768 * the chance that other implementations support them is rather small since Win32 QuickTime uses
3769 * DirectDraw, not OpenGL.
3770 */
3771 if(gl_info->supported[APPLE_FENCE] &&
3772 gl_info->supported[APPLE_CLIENT_STORAGE] &&
3773 gl_info->supported[APPLE_FLUSH_RENDER] &&
3774 gl_info->supported[APPLE_YCBCR_422]) {
3775 TRACE_(d3d_caps)("GL_APPLE_fence, GL_APPLE_client_storage, GL_APPLE_flush_render and GL_ycbcr_422 are supported\n");
3776 TRACE_(d3d_caps)("Activating MacOS fixups\n");
3777 return TRUE;
3778 } else {
3779 TRACE_(d3d_caps)("Apple extensions are not supported\n");
3780 TRACE_(d3d_caps)("Not activating MacOS fixups\n");
3781 return FALSE;
3782 }
3783 }
3784
3785 #define GLINFO_LOCATION (*gl_info)
3786 static void test_pbo_functionality(WineD3D_GL_Info *gl_info) {
3787 /* Some OpenGL implementations, namely Apple's Geforce 8 driver, advertises PBOs,
3788 * but glTexSubImage from a PBO fails miserably, with the first line repeated over
3789 * all the texture. This function detects this bug by its symptom and disables PBOs
3790 * if the test fails.
3791 *
3792 * The test uploads a 4x4 texture via the PBO in the "native" format GL_BGRA,
3793 * GL_UNSIGNED_INT_8_8_8_8_REV. This format triggers the bug, and it is what we use
3794 * for D3DFMT_A8R8G8B8. Then the texture is read back without any PBO and the data
3795 * read back is compared to the original. If they are equal PBOs are assumed to work,
3796 * otherwise the PBO extension is disabled.
3797 */
3798 GLuint texture, pbo;
3799 static const unsigned int pattern[] = {
3800 0x00000000, 0x000000ff, 0x0000ff00, 0x40ff0000,
3801 0x80ffffff, 0x40ffff00, 0x00ff00ff, 0x0000ffff,
3802 0x00ffff00, 0x00ff00ff, 0x0000ffff, 0x000000ff,
3803 0x80ff00ff, 0x0000ffff, 0x00ff00ff, 0x40ff00ff
3804 };
3805 unsigned int check[sizeof(pattern) / sizeof(pattern[0])];
3806
3807 if(!gl_info->supported[ARB_PIXEL_BUFFER_OBJECT]) {
3808 /* No PBO -> No point in testing them */
3809 return;
3810 }
3811
3812 while(glGetError());
3813 glGenTextures(1, &texture);
3814 glBindTexture(GL_TEXTURE_2D, texture);
3815 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 4, 4, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, 0);
3816 checkGLcall("Specifying the PBO test texture\n");
3817
3818 GL_EXTCALL(glGenBuffersARB(1, &pbo));
3819 GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, pbo));
3820 GL_EXTCALL(glBufferDataARB(GL_PIXEL_UNPACK_BUFFER_ARB, sizeof(pattern), pattern, GL_STREAM_DRAW_ARB));
3821 checkGLcall("Specifying the PBO test pbo\n");
3822
3823 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 4, 4, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL);
3824 checkGLcall("Loading the PBO test texture\n");
3825
3826 GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0));
3827 glFinish(); /* just to be sure */
3828
3829 memset(check, 0, sizeof(check));
3830 glGetTexImage(GL_TEXTURE_2D, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, check);
3831 checkGLcall("Reading back the PBO test texture\n");
3832
3833 glDeleteTextures(1, &texture);
3834 GL_EXTCALL(glDeleteBuffersARB(1, &pbo));
3835 checkGLcall("PBO test cleanup\n");
3836
3837 if(memcmp(check, pattern, sizeof(check)) != 0) {
3838 WARN_(d3d_caps)("PBO test failed, read back data doesn't match original\n");
3839 WARN_(d3d_caps)("Disabling PBOs. This may result in slower performance\n");
3840 gl_info->supported[ARB_PIXEL_BUFFER_OBJECT] = FALSE;
3841 } else {
3842 TRACE_(d3d_caps)("PBO test successful\n");
3843 }
3844 }
3845 #undef GLINFO_LOCATION
3846
3847 /* Certain applications(Steam) complain if we report an outdated driver version. In general,
3848 * reporting a driver version is moot because we are not the Windows driver, and we have different
3849 * bugs, features, etc.
3850 *
3851 * If a card is not found in this table, the gl driver version is reported
3852 */
3853 struct driver_version_information {
3854 WORD vendor; /* reported PCI card vendor ID */
3855 WORD card; /* reported PCI card device ID */
3856 WORD hipart_hi, hipart_lo; /* driver hiword to report */
3857 WORD lopart_hi, lopart_lo; /* driver loword to report */
3858 };
3859
3860 static const struct driver_version_information driver_version_table[] = {
3861 /* Nvidia drivers. Geforce6 and newer cards are supported by the current driver (177.x)*/
3862 /* GeforceFX support is up to 173.x, Geforce2MX/3/4 up to 96.x, TNT/Geforce1/2 up to 71.x */
3863 /* Note that version numbers >100 lets say 123.45 use >= x.y.11.2345 and not x.y.10.12345 */
3864 {VENDOR_NVIDIA, CARD_NVIDIA_GEFORCEFX_5200, 7, 15, 11, 7341 },
3865 {VENDOR_NVIDIA, CARD_NVIDIA_GEFORCEFX_5600, 7, 15, 11, 7341 },
3866 {VENDOR_NVIDIA, CARD_NVIDIA_GEFORCEFX_5800, 7, 15, 11, 7341 },
3867 {VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_6200, 7, 15, 11, 7341 },
3868 {VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_6600GT, 7, 15, 11, 7341 },
3869 {VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_6800, 7, 15, 11, 7341 },
3870 {VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_7400, 7, 15, 11, 7341 },
3871 {VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_7300, 7, 15, 11, 7341 },
3872 {VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_7600, 7, 15, 11, 7341 },
3873 {VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_7800GT, 7, 15, 11, 7341 },
3874 {VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_8300GS, 7, 15, 11, 7341 },
3875 {VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_8600GT, 7, 15, 11, 7341 },
3876 {VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_8600MGT, 7, 15, 11, 7341 },
3877 {VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_8800GTS, 7, 15, 11, 7341 },
3878 {VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_9600GT, 7, 15, 11, 7341 },
3879 {VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_9800GT, 7, 15, 11, 7341 },
3880 {VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX280, 7, 15, 11, 7341 },
3881
3882 /* ATI cards. The driver versions are somewhat similar, but not quite the same. Let's hardcode */
3883 {VENDOR_ATI, CARD_ATI_RADEON_9500, 6, 14, 10, 6764 },
3884 {VENDOR_ATI, CARD_ATI_RADEON_X700, 6, 14, 10, 6764 },
3885 {VENDOR_ATI, CARD_ATI_RADEON_X1600, 6, 14, 10, 6764 },
3886 {VENDOR_ATI, CARD_ATI_RADEON_HD2300, 6, 14, 10, 6764 },
3887 {VENDOR_ATI, CARD_ATI_RADEON_HD2600, 6, 14, 10, 6764 },
3888 {VENDOR_ATI, CARD_ATI_RADEON_HD2900, 6, 14, 10, 6764 },
3889
3890 /* TODO: Add information about legacy nvidia and ATI hardware, Intel and other cards */
3891 };
3892
3893 static void fixup_extensions(WineD3D_GL_Info *gl_info) {
3894 unsigned int i;
3895 BOOL apple = implementation_is_apple(gl_info);
3896
3897 if(apple) {
3898 /* MacOS advertises more GLSL vertex shader uniforms than supported by the hardware, and if more are
3899 * used it falls back to software. While the compiler can detect if the shader uses all declared
3900 * uniforms, the optimization fails if the shader uses relative addressing. So any GLSL shader
3901 * using relative addressing falls back to software.
3902 *
3903 * ARB vp gives the correct amount of uniforms, so use it instead of GLSL
3904 */
3905 if(gl_info->vs_glsl_constantsF <= gl_info->vs_arb_constantsF) {
3906 FIXME("GLSL doesn't advertise more vertex shader uniforms than ARB. Driver fixup outdated?\n");
3907 } else {
3908 TRACE("Driver claims %u GLSL vs uniforms, replacing with %u ARB vp uniforms\n",
3909 gl_info->vs_glsl_constantsF, gl_info->vs_arb_constantsF);
3910 gl_info->vs_glsl_constantsF = gl_info->vs_arb_constantsF;
3911 }
3912
3913 /* The Intel GPUs on MacOS set the .w register of texcoords to 0.0 by default, which causes problems
3914 * with fixed function fragment processing. Ideally this flag should be detected with a test shader
3915 * and OpenGL feedback mode, but some GL implementations (MacOS ATI at least, probably all MacOS ones)
3916 * do not like vertex shaders in feedback mode and return an error, even though it should be valid
3917 * according to the spec.
3918 *
3919 * We don't want to enable this on all cards, as it adds an extra instruction per texcoord used. This
3920 * makes the shader slower and eats instruction slots which should be available to the d3d app.
3921 *
3922 * ATI Radeon HD 2xxx cards on MacOS have the issue. Instead of checking for the buggy cards, blacklist
3923 * all radeon cards on Macs and whitelist the good ones. That way we're prepared for the future. If
3924 * this workaround is activated on cards that do not need it, it won't break things, just affect
3925 * performance negatively.
3926 */
3927 if(gl_info->gl_vendor == VENDOR_INTEL ||
3928 (gl_info->gl_vendor == VENDOR_ATI && gl_info->gl_card != CARD_ATI_RADEON_X1600)) {
3929 TRACE("Enabling vertex texture coord fixes in vertex shaders\n");
3930 gl_info->set_texcoord_w = TRUE;
3931 }
3932 }
3933
3934 /* MacOS advertises GL_ARB_texture_non_power_of_two on ATI r500 and earlier cards, although
3935 * these cards only support GL_ARB_texture_rectangle(D3DPTEXTURECAPS_NONPOW2CONDITIONAL).
3936 * If real NP2 textures are used, the driver falls back to software. We could just remove the
3937 * extension and use GL_ARB_texture_rectangle instead, but texture_rectangle is inconventient
3938 * due to the non-normalized texture coordinates. Thus set an internal extension flag,
3939 * GL_WINE_normalized_texrect, which signals the code that it can use non power of two textures
3940 * as per GL_ARB_texture_non_power_of_two, but has to stick to the texture_rectangle limits.
3941 *
3942 * fglrx doesn't advertise GL_ARB_texture_non_power_of_two, but it advertises opengl 2.0 which
3943 * has this extension promoted to core. The extension loading code sets this extension supported
3944 * due to that, so this code works on fglrx as well.
3945 */
3946 if(gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO] && gl_info->gl_vendor == VENDOR_ATI) {
3947 if(gl_info->gl_card == CARD_ATI_RADEON_X700 || gl_info->gl_card == CARD_ATI_RADEON_X1600 ||
3948 gl_info->gl_card == CARD_ATI_RADEON_9500 || gl_info->gl_card == CARD_ATI_RADEON_8500 ||
3949 gl_info->gl_card == CARD_ATI_RADEON_7200 || gl_info->gl_card == CARD_ATI_RAGE_128PRO) {
3950 TRACE("GL_ARB_texture_non_power_of_two advertised on R500 or earlier card, removing\n");
3951 gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO] = FALSE;
3952 gl_info->supported[WINE_NORMALIZED_TEXRECT] = TRUE;
3953 }
3954 }
3955
3956 /* The nVidia GeForceFX series reports OpenGL 2.0 capabilities with the latest drivers versions, but
3957 * doesn't explicitly advertise the ARB_tex_npot extension in the GL extension string.
3958 * This usually means that ARB_tex_npot is supported in hardware as long as the application is staying
3959 * within the limits enforced by the ARB_texture_rectangle extension. This however is not true for the
3960 * FX series, which instantly falls back to a slower software path as soon as ARB_tex_npot is used.
3961 * We therefore completely remove ARB_tex_npot from the list of supported extensions.
3962 *
3963 * Note that wine_normalized_texrect can't be used in this case because internally it uses ARB_tex_npot,
3964 * triggering the software fallback. There is not much we can do here apart from disabling the
3965 * software-emulated extension and reenable ARB_tex_rect (which was previously disabled
3966 * in IWineD3DImpl_FillGLCaps).
3967 * This fixup removes performance problems on both the FX 5900 and FX 5700 (e.g. for framebuffer
3968 * post-processing effects in the game "Max Payne 2").
3969 * The behaviour can be verified through a simple test app attached in bugreport #14724.
3970 */
3971 if(gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO] && gl_info->gl_vendor == VENDOR_NVIDIA) {
3972 if(gl_info->gl_card == CARD_NVIDIA_GEFORCEFX_5800 || gl_info->gl_card == CARD_NVIDIA_GEFORCEFX_5600) {
3973 TRACE("GL_ARB_texture_non_power_of_two advertised through OpenGL 2.0 on NV FX card, removing\n");
3974 gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO] = FALSE;
3975 gl_info->supported[ARB_TEXTURE_RECTANGLE] = TRUE;
3976 }
3977 }
3978
3979 /* Find out if PBOs work as they are supposed to */
3980 test_pbo_functionality(gl_info);
3981
3982 /* Fixup the driver version */
3983 for(i = 0; i < (sizeof(driver_version_table) / sizeof(driver_version_table[0])); i++) {
3984 if(gl_info->gl_vendor == driver_version_table[i].vendor &&
3985 gl_info->gl_card == driver_version_table[i].card) {
3986 TRACE_(d3d_caps)("Found card 0x%04x, 0x%04x in driver version DB\n", gl_info->gl_vendor, gl_info->gl_card);
3987
3988 gl_info->driver_version = MAKEDWORD_VERSION(driver_version_table[i].lopart_hi,
3989 driver_version_table[i].lopart_lo);
3990 gl_info->driver_version_hipart = MAKEDWORD_VERSION(driver_version_table[i].hipart_hi,
3991 driver_version_table[i].hipart_lo);
3992 break;
3993 }
3994 }
3995 }
3996
3997 static void WINE_GLAPI invalid_func(const void *data)
3998 {
3999 ERR("Invalid vertex attribute function called\n");
4000 DebugBreak();
4001 }
4002
4003 static void WINE_GLAPI invalid_texcoord_func(GLenum unit, const void *data)
4004 {
4005 ERR("Invalid texcoord function called\n");
4006 DebugBreak();
4007 }
4008
4009 #define GLINFO_LOCATION (Adapters[0].gl_info)
4010
4011 /* Helper functions for providing vertex data to opengl. The arrays are initialized based on
4012 * the extension detection and are used in drawStridedSlow
4013 */
4014 static void WINE_GLAPI position_d3dcolor(const void *data)
4015 {
4016 DWORD pos = *((const DWORD *)data);
4017
4018 FIXME("Add a test for fixed function position from d3dcolor type\n");
4019 glVertex4s(D3DCOLOR_B_R(pos),
4020 D3DCOLOR_B_G(pos),
4021 D3DCOLOR_B_B(pos),
4022 D3DCOLOR_B_A(pos));
4023 }
4024
4025 static void WINE_GLAPI position_float4(const void *data)
4026 {
4027 const GLfloat *pos = data;
4028
4029 if (pos[3] < eps && pos[3] > -eps)
4030 glVertex3fv(pos);
4031 else {
4032 float w = 1.0 / pos[3];
4033
4034 glVertex4f(pos[0] * w, pos[1] * w, pos[2] * w, w);
4035 }
4036 }
4037
4038 static void WINE_GLAPI diffuse_d3dcolor(const void *data)
4039 {
4040 DWORD diffuseColor = *((const DWORD *)data);
4041
4042 glColor4ub(D3DCOLOR_B_R(diffuseColor),
4043 D3DCOLOR_B_G(diffuseColor),
4044 D3DCOLOR_B_B(diffuseColor),
4045 D3DCOLOR_B_A(diffuseColor));
4046 }
4047
4048 static void WINE_GLAPI specular_d3dcolor(const void *data)
4049 {
4050 DWORD specularColor = *((const DWORD *)data);
4051
4052 GL_EXTCALL(glSecondaryColor3ubEXT)(D3DCOLOR_B_R(specularColor),
4053 D3DCOLOR_B_G(specularColor),
4054 D3DCOLOR_B_B(specularColor));
4055 }
4056
4057 static void WINE_GLAPI warn_no_specular_func(const void *data)
4058 {
4059 WARN("GL_EXT_secondary_color not supported\n");
4060 }
4061
4062 static void fillGLAttribFuncs(const WineD3D_GL_Info *gl_info)
4063 {
4064 position_funcs[WINED3DDECLTYPE_FLOAT1] = invalid_func;
4065 position_funcs[WINED3DDECLTYPE_FLOAT2] = invalid_func;
4066 position_funcs[WINED3DDECLTYPE_FLOAT3] = (glAttribFunc)glVertex3fv;
4067 position_funcs[WINED3DDECLTYPE_FLOAT4] = position_float4;
4068 position_funcs[WINED3DDECLTYPE_D3DCOLOR] = position_d3dcolor;
4069 position_funcs[WINED3DDECLTYPE_UBYTE4] = invalid_func;
4070 position_funcs[WINED3DDECLTYPE_SHORT2] = invalid_func;
4071 position_funcs[WINED3DDECLTYPE_SHORT4] = (glAttribFunc)glVertex2sv;
4072 position_funcs[WINED3DDECLTYPE_UBYTE4N] = invalid_func;
4073 position_funcs[WINED3DDECLTYPE_SHORT2N] = invalid_func;
4074 position_funcs[WINED3DDECLTYPE_SHORT4N] = invalid_func;
4075 position_funcs[WINED3DDECLTYPE_USHORT2N] = invalid_func;
4076 position_funcs[WINED3DDECLTYPE_USHORT4N] = invalid_func;
4077 position_funcs[WINED3DDECLTYPE_UDEC3] = invalid_func;
4078 position_funcs[WINED3DDECLTYPE_DEC3N] = invalid_func;
4079 position_funcs[WINED3DDECLTYPE_FLOAT16_2] = invalid_func;
4080 position_funcs[WINED3DDECLTYPE_FLOAT16_4] = invalid_func;
4081
4082 diffuse_funcs[WINED3DDECLTYPE_FLOAT1] = invalid_func;
4083 diffuse_funcs[WINED3DDECLTYPE_FLOAT2] = invalid_func;
4084 diffuse_funcs[WINED3DDECLTYPE_FLOAT3] = (glAttribFunc)glColor3fv;
4085 diffuse_funcs[WINED3DDECLTYPE_FLOAT4] = (glAttribFunc)glColor4fv;
4086 diffuse_funcs[WINED3DDECLTYPE_D3DCOLOR] = diffuse_d3dcolor;
4087 diffuse_funcs[WINED3DDECLTYPE_UBYTE4] = invalid_func;
4088 diffuse_funcs[WINED3DDECLTYPE_SHORT2] = invalid_func;
4089 diffuse_funcs[WINED3DDECLTYPE_SHORT4] = invalid_func;
4090 diffuse_funcs[WINED3DDECLTYPE_UBYTE4N] = (glAttribFunc)glColor4ubv;
4091 diffuse_funcs[WINED3DDECLTYPE_SHORT2N] = invalid_func;
4092 diffuse_funcs[WINED3DDECLTYPE_SHORT4N] = (glAttribFunc)glColor4sv;
4093 diffuse_funcs[WINED3DDECLTYPE_USHORT2N] = invalid_func;
4094 diffuse_funcs[WINED3DDECLTYPE_USHORT4N] = (glAttribFunc)glColor4usv;
4095 diffuse_funcs[WINED3DDECLTYPE_UDEC3] = invalid_func;
4096 diffuse_funcs[WINED3DDECLTYPE_DEC3N] = invalid_func;
4097 diffuse_funcs[WINED3DDECLTYPE_FLOAT16_2] = invalid_func;
4098 diffuse_funcs[WINED3DDECLTYPE_FLOAT16_4] = invalid_func;
4099
4100 /* No 4 component entry points here */
4101 specular_funcs[WINED3DDECLTYPE_FLOAT1] = invalid_func;
4102 specular_funcs[WINED3DDECLTYPE_FLOAT2] = invalid_func;
4103 if(GL_SUPPORT(EXT_SECONDARY_COLOR)) {
4104 specular_funcs[WINED3DDECLTYPE_FLOAT3] = (glAttribFunc)GL_EXTCALL(glSecondaryColor3fvEXT);
4105 } else {
4106 specular_funcs[WINED3DDECLTYPE_FLOAT3] = warn_no_specular_func;
4107 }
4108 specular_funcs[WINED3DDECLTYPE_FLOAT4] = invalid_func;
4109 if(GL_SUPPORT(EXT_SECONDARY_COLOR)) {
4110 specular_funcs[WINED3DDECLTYPE_D3DCOLOR] = specular_d3dcolor;
4111 } else {
4112 specular_funcs[WINED3DDECLTYPE_D3DCOLOR] = warn_no_specular_func;
4113 }
4114 specular_funcs[WINED3DDECLTYPE_UBYTE4] = invalid_func;
4115 specular_funcs[WINED3DDECLTYPE_SHORT2] = invalid_func;
4116 specular_funcs[WINED3DDECLTYPE_SHORT4] = invalid_func;
4117 specular_funcs[WINED3DDECLTYPE_UBYTE4N] = invalid_func;
4118 specular_funcs[WINED3DDECLTYPE_SHORT2N] = invalid_func;
4119 specular_funcs[WINED3DDECLTYPE_SHORT4N] = invalid_func;
4120 specular_funcs[WINED3DDECLTYPE_USHORT2N] = invalid_func;
4121 specular_funcs[WINED3DDECLTYPE_USHORT4N] = invalid_func;
4122 specular_funcs[WINED3DDECLTYPE_UDEC3] = invalid_func;
4123 specular_funcs[WINED3DDECLTYPE_DEC3N] = invalid_func;
4124 specular_funcs[WINED3DDECLTYPE_FLOAT16_2] = invalid_func;
4125 specular_funcs[WINED3DDECLTYPE_FLOAT16_4] = invalid_func;
4126
4127 /* Only 3 component entry points here. Test how others behave. Float4 normals are used
4128 * by one of our tests, trying to pass it to the pixel shader, which fails on Windows.
4129 */
4130 normal_funcs[WINED3DDECLTYPE_FLOAT1] = invalid_func;
4131 normal_funcs[WINED3DDECLTYPE_FLOAT2] = invalid_func;
4132 normal_funcs[WINED3DDECLTYPE_FLOAT3] = (glAttribFunc)glNormal3fv;
4133 normal_funcs[WINED3DDECLTYPE_FLOAT4] = (glAttribFunc)glNormal3fv; /* Just ignore the 4th value */
4134 normal_funcs[WINED3DDECLTYPE_D3DCOLOR] = invalid_func;
4135 normal_funcs[WINED3DDECLTYPE_UBYTE4] = invalid_func;
4136 normal_funcs[WINED3DDECLTYPE_SHORT2] = invalid_func;
4137 normal_funcs[WINED3DDECLTYPE_SHORT4] = invalid_func;
4138 normal_funcs[WINED3DDECLTYPE_UBYTE4N] = invalid_func;
4139 normal_funcs[WINED3DDECLTYPE_SHORT2N] = invalid_func;
4140 normal_funcs[WINED3DDECLTYPE_SHORT4N] = invalid_func;
4141 normal_funcs[WINED3DDECLTYPE_USHORT2N] = invalid_func;
4142 normal_funcs[WINED3DDECLTYPE_USHORT4N] = invalid_func;
4143 normal_funcs[WINED3DDECLTYPE_UDEC3] = invalid_func;
4144 normal_funcs[WINED3DDECLTYPE_DEC3N] = invalid_func;
4145 normal_funcs[WINED3DDECLTYPE_FLOAT16_2] = invalid_func;
4146 normal_funcs[WINED3DDECLTYPE_FLOAT16_4] = invalid_func;
4147
4148 multi_texcoord_funcs[WINED3DDECLTYPE_FLOAT1] = (glMultiTexCoordFunc)GL_EXTCALL(glMultiTexCoord1fvARB);
4149 multi_texcoord_funcs[WINED3DDECLTYPE_FLOAT2] = (glMultiTexCoordFunc)GL_EXTCALL(glMultiTexCoord2fvARB);
4150 multi_texcoord_funcs[WINED3DDECLTYPE_FLOAT3] = (glMultiTexCoordFunc)GL_EXTCALL(glMultiTexCoord3fvARB);
4151 multi_texcoord_funcs[WINED3DDECLTYPE_FLOAT4] = (glMultiTexCoordFunc)GL_EXTCALL(glMultiTexCoord4fvARB);
4152 multi_texcoord_funcs[WINED3DDECLTYPE_D3DCOLOR] = invalid_texcoord_func;
4153 multi_texcoord_funcs[WINED3DDECLTYPE_UBYTE4] = invalid_texcoord_func;
4154 multi_texcoord_funcs[WINED3DDECLTYPE_SHORT2] = (glMultiTexCoordFunc)GL_EXTCALL(glMultiTexCoord2svARB);
4155 multi_texcoord_funcs[WINED3DDECLTYPE_SHORT4] = (glMultiTexCoordFunc)GL_EXTCALL(glMultiTexCoord4svARB);
4156 multi_texcoord_funcs[WINED3DDECLTYPE_UBYTE4N] = invalid_texcoord_func;
4157 multi_texcoord_funcs[WINED3DDECLTYPE_SHORT2N] = invalid_texcoord_func;
4158 multi_texcoord_funcs[WINED3DDECLTYPE_SHORT4N] = invalid_texcoord_func;
4159 multi_texcoord_funcs[WINED3DDECLTYPE_USHORT2N] = invalid_texcoord_func;
4160 multi_texcoord_funcs[WINED3DDECLTYPE_USHORT4N] = invalid_texcoord_func;
4161 multi_texcoord_funcs[WINED3DDECLTYPE_UDEC3] = invalid_texcoord_func;
4162 multi_texcoord_funcs[WINED3DDECLTYPE_DEC3N] = invalid_texcoord_func;
4163 if (GL_SUPPORT(NV_HALF_FLOAT))
4164 {
4165 multi_texcoord_funcs[WINED3DDECLTYPE_FLOAT16_2] = (glMultiTexCoordFunc)GL_EXTCALL(glMultiTexCoord2hvNV);
4166 multi_texcoord_funcs[WINED3DDECLTYPE_FLOAT16_4] = (glMultiTexCoordFunc)GL_EXTCALL(glMultiTexCoord4hvNV);
4167 } else {
4168 multi_texcoord_funcs[WINED3DDECLTYPE_FLOAT16_2] = invalid_texcoord_func;
4169 multi_texcoord_funcs[WINED3DDECLTYPE_FLOAT16_4] = invalid_texcoord_func;
4170 }
4171 }
4172
4173 #define PUSH1(att) attribs[nAttribs++] = (att);
4174 BOOL InitAdapters(void) {
4175 static HMODULE mod_gl;
4176 BOOL ret;
4177 int ps_selected_mode, vs_selected_mode;
4178
4179 /* No need to hold any lock. The calling library makes sure only one thread calls
4180 * wined3d simultaneously
4181 */
4182 if(numAdapters > 0) return Adapters[0].opengl;
4183
4184 TRACE("Initializing adapters\n");
4185
4186 if(!mod_gl) {
4187 #ifdef USE_WIN32_OPENGL
4188 #define USE_GL_FUNC(pfn) pfn = (void*)GetProcAddress(mod_gl, #pfn);
4189 mod_gl = LoadLibraryA("opengl32.dll");
4190 if(!mod_gl) {
4191 ERR("Can't load opengl32.dll!\n");
4192 goto nogl_adapter;
4193 }
4194 #else
4195 #define USE_GL_FUNC(pfn) pfn = (void*)pwglGetProcAddress(#pfn);
4196 /* To bypass the opengl32 thunks load wglGetProcAddress from gdi32 (glXGetProcAddress wrapper) instead of opengl32's */
4197 mod_gl = GetModuleHandleA("gdi32.dll");
4198 #endif
4199 }
4200
4201 /* Load WGL core functions from opengl32.dll */
4202 #define USE_WGL_FUNC(pfn) p##pfn = (void*)GetProcAddress(mod_gl, #pfn);
4203 WGL_FUNCS_GEN;
4204 #undef USE_WGL_FUNC
4205
4206 if(!pwglGetProcAddress) {
4207 ERR("Unable to load wglGetProcAddress!\n");
4208 goto nogl_adapter;
4209 }
4210
4211 /* Dynamically load all GL core functions */
4212 GL_FUNCS_GEN;
4213 #undef USE_GL_FUNC
4214
4215 /* Load glFinish and glFlush from opengl32.dll even if we're not using WIN32 opengl
4216 * otherwise because we have to use winex11.drv's override
4217 */
4218 #ifdef USE_WIN32_OPENGL
4219 glFinish = (void*)GetProcAddress(mod_gl, "glFinish");
4220 glFlush = (void*)GetProcAddress(mod_gl, "glFlush");
4221 #else
4222 glFinish = (void*)pwglGetProcAddress("wglFinish");
4223 glFlush = (void*)pwglGetProcAddress("wglFlush");
4224 #endif
4225
4226 glEnableWINE = glEnable;
4227 glDisableWINE = glDisable;
4228
4229 /* For now only one default adapter */
4230 {
4231 int iPixelFormat;
4232 int attribs[10];
4233 int values[10];
4234 int nAttribs = 0;
4235 int res;
4236 int i;
4237 WineD3D_PixelFormat *cfgs;
4238 int attribute;
4239 DISPLAY_DEVICEW DisplayDevice;
4240 HDC hdc;
4241
4242 TRACE("Initializing default adapter\n");
4243 Adapters[0].num = 0;
4244 Adapters[0].monitorPoint.x = -1;
4245 Adapters[0].monitorPoint.y = -1;
4246
4247 if (!WineD3D_CreateFakeGLContext()) {
4248 ERR("Failed to get a gl context for default adapter\n");
4249 WineD3D_ReleaseFakeGLContext();
4250 goto nogl_adapter;
4251 }
4252
4253 ret = IWineD3DImpl_FillGLCaps(&Adapters[0].gl_info);
4254 if(!ret) {
4255 ERR("Failed to initialize gl caps for default adapter\n");
4256 WineD3D_ReleaseFakeGLContext();
4257 goto nogl_adapter;
4258 }
4259 ret = initPixelFormats(&Adapters[0].gl_info);
4260 if(!ret) {
4261 ERR("Failed to init gl formats\n");
4262 WineD3D_ReleaseFakeGLContext();
4263 goto nogl_adapter;
4264 }
4265
4266 hdc = pwglGetCurrentDC();
4267 if(!hdc) {
4268 ERR("Failed to get gl HDC\n");
4269 WineD3D_ReleaseFakeGLContext();
4270 goto nogl_adapter;
4271 }
4272
4273 Adapters[0].driver = "Display";
4274 Adapters[0].description = "Direct3D HAL";
4275
4276 /* Use the VideoRamSize registry setting when set */
4277 if(wined3d_settings.emulated_textureram)
4278 Adapters[0].TextureRam = wined3d_settings.emulated_textureram;
4279 else
4280 Adapters[0].TextureRam = Adapters[0].gl_info.vidmem;
4281 Adapters[0].UsedTextureRam = 0;
4282 TRACE("Emulating %dMB of texture ram\n", Adapters[0].TextureRam/(1024*1024));
4283
4284 /* Initialize the Adapter's DeviceName which is required for ChangeDisplaySettings and friends */
4285 DisplayDevice.cb = sizeof(DisplayDevice);
4286 EnumDisplayDevicesW(NULL, 0 /* Adapter 0 = iDevNum 0 */, &DisplayDevice, 0);
4287 TRACE("DeviceName: %s\n", debugstr_w(DisplayDevice.DeviceName));
4288 strcpyW(Adapters[0].DeviceName, DisplayDevice.DeviceName);
4289
4290 attribute = WGL_NUMBER_PIXEL_FORMATS_ARB;
4291 GL_EXTCALL(wglGetPixelFormatAttribivARB(hdc, 0, 0, 1, &attribute, &Adapters[0].nCfgs));
4292
4293 Adapters[0].cfgs = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, Adapters[0].nCfgs *sizeof(WineD3D_PixelFormat));
4294 cfgs = Adapters[0].cfgs;
4295 PUSH1(WGL_RED_BITS_ARB)
4296 PUSH1(WGL_GREEN_BITS_ARB)
4297 PUSH1(WGL_BLUE_BITS_ARB)
4298 PUSH1(WGL_ALPHA_BITS_ARB)
4299 PUSH1(WGL_DEPTH_BITS_ARB)
4300 PUSH1(WGL_STENCIL_BITS_ARB)
4301 PUSH1(WGL_DRAW_TO_WINDOW_ARB)
4302 PUSH1(WGL_PIXEL_TYPE_ARB)
4303 PUSH1(WGL_DOUBLE_BUFFER_ARB)
4304 PUSH1(WGL_AUX_BUFFERS_ARB)
4305
4306 for(iPixelFormat=1; iPixelFormat<=Adapters[0].nCfgs; iPixelFormat++) {
4307 res = GL_EXTCALL(wglGetPixelFormatAttribivARB(hdc, iPixelFormat, 0, nAttribs, attribs, values));
4308
4309 if(!res)
4310 continue;
4311
4312 /* Cache the pixel format */
4313 cfgs->iPixelFormat = iPixelFormat;
4314 cfgs->redSize = values[0];
4315 cfgs->greenSize = values[1];
4316 cfgs->blueSize = values[2];
4317 cfgs->alphaSize = values[3];
4318 cfgs->depthSize = values[4];
4319 cfgs->stencilSize = values[5];
4320 cfgs->windowDrawable = values[6];
4321 cfgs->iPixelType = values[7];
4322 cfgs->doubleBuffer = values[8];
4323 cfgs->auxBuffers = values[9];
4324
4325 cfgs->pbufferDrawable = FALSE;
4326 /* Check for pbuffer support when it is around as wglGetPixelFormatAttribiv fails for unknown attributes. */
4327 if(GL_SUPPORT(WGL_ARB_PBUFFER)) {
4328 int attrib = WGL_DRAW_TO_PBUFFER_ARB;
4329 int value;
4330 if(GL_EXTCALL(wglGetPixelFormatAttribivARB(hdc, iPixelFormat, 0, 1, &attrib, &value)))
4331 cfgs->pbufferDrawable = value;
4332 }
4333
4334 cfgs->numSamples = 0;
4335 /* Check multisample support */
4336 if(GL_SUPPORT(ARB_MULTISAMPLE)) {
4337 int attrib[2] = {WGL_SAMPLE_BUFFERS_ARB, WGL_SAMPLES_ARB};
4338 int value[2];
4339 if(GL_EXTCALL(wglGetPixelFormatAttribivARB(hdc, iPixelFormat, 0, 2, attrib, value))) {
4340 /* value[0] = WGL_SAMPLE_BUFFERS_ARB which tells whether multisampling is supported.
4341 * value[1] = number of multi sample buffers*/
4342 if(value[0])
4343 cfgs->numSamples = value[1];
4344 }
4345 }
4346
4347 TRACE("iPixelFormat=%d, iPixelType=%#x, doubleBuffer=%d, RGBA=%d/%d/%d/%d, depth=%d, stencil=%d, windowDrawable=%d, pbufferDrawable=%d\n", cfgs->iPixelFormat, cfgs->iPixelType, cfgs->doubleBuffer, cfgs->redSize, cfgs->greenSize, cfgs->blueSize, cfgs->alphaSize, cfgs->depthSize, cfgs->stencilSize, cfgs->windowDrawable, cfgs->pbufferDrawable);
4348 cfgs++;
4349 }
4350
4351 /* D16, D24X8 and D24S8 are common depth / depth+stencil formats. All drivers support them though this doesn't
4352 * mean that the format is offered in hardware. For instance Geforce8 cards don't have offer D16 in hardware
4353 * but just fake it using D24(X8?) which is fine. D3D also allows that.
4354 * Some display drivers (i915 on Linux) only report mixed depth+stencil formats like D24S8. MSDN clearly mentions
4355 * that only on lockable formats (e.g. D16_locked) the bit order is guaranteed and that on other formats the
4356 * driver is allowed to consume more bits EXCEPT for stencil bits.
4357 *
4358 * Mark an adapter with this broken stencil behavior.
4359 */
4360 Adapters[0].brokenStencil = TRUE;
4361 for(i=0, cfgs=Adapters[0].cfgs; i<Adapters[0].nCfgs; i++) {
4362 /* Nearly all drivers offer depth formats without stencil, only on i915 this if-statement won't be entered. */
4363 if(cfgs[i].depthSize && !cfgs[i].stencilSize) {
4364 Adapters[0].brokenStencil = FALSE;
4365 break;
4366 }
4367 }
4368
4369 fixup_extensions(&Adapters[0].gl_info);
4370 add_gl_compat_wrappers(&Adapters[0].gl_info);
4371
4372 WineD3D_ReleaseFakeGLContext();
4373
4374 select_shader_mode(&Adapters[0].gl_info, WINED3DDEVTYPE_HAL, &ps_selected_mode, &vs_selected_mode);
4375 select_shader_max_constants(ps_selected_mode, vs_selected_mode, &Adapters[0].gl_info);
4376 fillGLAttribFuncs(&Adapters[0].gl_info);
4377 init_type_lookup(&Adapters[0].gl_info);
4378 Adapters[0].opengl = TRUE;
4379 }
4380 numAdapters = 1;
4381 TRACE("%d adapters successfully initialized\n", numAdapters);
4382
4383 return TRUE;
4384
4385 nogl_adapter:
4386 /* Initialize an adapter for ddraw-only memory counting */
4387 memset(Adapters, 0, sizeof(Adapters));
4388 Adapters[0].num = 0;
4389 Adapters[0].opengl = FALSE;
4390 Adapters[0].monitorPoint.x = -1;
4391 Adapters[0].monitorPoint.y = -1;
4392
4393 Adapters[0].driver = "Display";
4394 Adapters[0].description = "WineD3D DirectDraw Emulation";
4395 if(wined3d_settings.emulated_textureram) {
4396 Adapters[0].TextureRam = wined3d_settings.emulated_textureram;
4397 } else {
4398 Adapters[0].TextureRam = 8 * 1024 * 1024; /* This is plenty for a DDraw-only card */
4399 }
4400
4401 numAdapters = 1;
4402 return FALSE;
4403 }
4404 #undef PUSH1
4405 #undef GLINFO_LOCATION
4406
4407 /**********************************************************
4408 * IWineD3D VTbl follows
4409 **********************************************************/
4410
4411 const IWineD3DVtbl IWineD3D_Vtbl =
4412 {
4413 /* IUnknown */
4414 IWineD3DImpl_QueryInterface,
4415 IWineD3DImpl_AddRef,
4416 IWineD3DImpl_Release,
4417 /* IWineD3D */
4418 IWineD3DImpl_GetParent,
4419 IWineD3DImpl_GetAdapterCount,
4420 IWineD3DImpl_RegisterSoftwareDevice,
4421 IWineD3DImpl_GetAdapterMonitor,
4422 IWineD3DImpl_GetAdapterModeCount,
4423 IWineD3DImpl_EnumAdapterModes,
4424 IWineD3DImpl_GetAdapterDisplayMode,
4425 IWineD3DImpl_GetAdapterIdentifier,
4426 IWineD3DImpl_CheckDeviceMultiSampleType,
4427 IWineD3DImpl_CheckDepthStencilMatch,
4428 IWineD3DImpl_CheckDeviceType,
4429 IWineD3DImpl_CheckDeviceFormat,
4430 IWineD3DImpl_CheckDeviceFormatConversion,
4431 IWineD3DImpl_GetDeviceCaps,
4432 IWineD3DImpl_CreateDevice
4433 };