2 * IWineD3D implementation
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 * Copyright 2009 Henri Verbeet for CodeWeavers
11 * This library is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU Lesser General Public
13 * License as published by the Free Software Foundation; either
14 * version 2.1 of the License, or (at your option) any later version.
16 * This library is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * Lesser General Public License for more details.
21 * You should have received a copy of the GNU Lesser General Public
22 * License along with this library; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
28 #include "wined3d_private.h"
30 WINE_DEFAULT_DEBUG_CHANNEL(d3d);
31 WINE_DECLARE_DEBUG_CHANNEL(d3d_caps);
33 #define WINE_DEFAULT_VIDMEM (64 * 1024 * 1024)
35 /* The d3d device ID */
36 static const GUID IID_D3DDEVICE_D3DUID = { 0xaeb2cdd4, 0x6e41, 0x43ea, { 0x94,0x1c,0x83,0x61,0xcc,0x76,0x07,0x81 } };
38 /* Extension detection */
40 const char *extension_string;
41 GL_SupportedExt extension;
45 {"GL_APPLE_client_storage", APPLE_CLIENT_STORAGE, 0 },
46 {"GL_APPLE_fence", APPLE_FENCE, 0 },
47 {"GL_APPLE_float_pixels", APPLE_FLOAT_PIXELS, 0 },
48 {"GL_APPLE_flush_buffer_range", APPLE_FLUSH_BUFFER_RANGE, 0 },
49 {"GL_APPLE_flush_render", APPLE_FLUSH_RENDER, 0 },
50 {"GL_APPLE_ycbcr_422", APPLE_YCBCR_422, 0 },
53 {"GL_ARB_color_buffer_float", ARB_COLOR_BUFFER_FLOAT, 0 },
54 {"GL_ARB_depth_buffer_float", ARB_DEPTH_BUFFER_FLOAT, 0 },
55 {"GL_ARB_depth_clamp", ARB_DEPTH_CLAMP, 0 },
56 {"GL_ARB_depth_texture", ARB_DEPTH_TEXTURE, 0 },
57 {"GL_ARB_draw_buffers", ARB_DRAW_BUFFERS, 0 },
58 {"GL_ARB_fragment_program", ARB_FRAGMENT_PROGRAM, 0 },
59 {"GL_ARB_fragment_shader", ARB_FRAGMENT_SHADER, 0 },
60 {"GL_ARB_framebuffer_object", ARB_FRAMEBUFFER_OBJECT, 0 },
61 {"GL_ARB_geometry_shader4", ARB_GEOMETRY_SHADER4, 0 },
62 {"GL_ARB_half_float_pixel", ARB_HALF_FLOAT_PIXEL, 0 },
63 {"GL_ARB_half_float_vertex", ARB_HALF_FLOAT_VERTEX, 0 },
64 {"GL_ARB_imaging", ARB_IMAGING, 0 },
65 {"GL_ARB_map_buffer_range", ARB_MAP_BUFFER_RANGE, 0 },
66 {"GL_ARB_multisample", ARB_MULTISAMPLE, 0 }, /* needs GLX_ARB_MULTISAMPLE as well */
67 {"GL_ARB_multitexture", ARB_MULTITEXTURE, 0 },
68 {"GL_ARB_occlusion_query", ARB_OCCLUSION_QUERY, 0 },
69 {"GL_ARB_pixel_buffer_object", ARB_PIXEL_BUFFER_OBJECT, 0 },
70 {"GL_ARB_point_parameters", ARB_POINT_PARAMETERS, 0 },
71 {"GL_ARB_point_sprite", ARB_POINT_SPRITE, 0 },
72 {"GL_ARB_provoking_vertex", ARB_PROVOKING_VERTEX, 0 },
73 {"GL_ARB_shader_objects", ARB_SHADER_OBJECTS, 0 },
74 {"GL_ARB_shader_texture_lod", ARB_SHADER_TEXTURE_LOD, 0 },
75 {"GL_ARB_shading_language_100", ARB_SHADING_LANGUAGE_100, 0 },
76 {"GL_ARB_shadow", ARB_SHADOW, 0 },
77 {"GL_ARB_sync", ARB_SYNC, 0 },
78 {"GL_ARB_texture_border_clamp", ARB_TEXTURE_BORDER_CLAMP, 0 },
79 {"GL_ARB_texture_compression", ARB_TEXTURE_COMPRESSION, 0 },
80 {"GL_ARB_texture_compression_rgtc", ARB_TEXTURE_COMPRESSION_RGTC, 0 },
81 {"GL_ARB_texture_cube_map", ARB_TEXTURE_CUBE_MAP, 0 },
82 {"GL_ARB_texture_env_add", ARB_TEXTURE_ENV_ADD, 0 },
83 {"GL_ARB_texture_env_combine", ARB_TEXTURE_ENV_COMBINE, 0 },
84 {"GL_ARB_texture_env_dot3", ARB_TEXTURE_ENV_DOT3, 0 },
85 {"GL_ARB_texture_float", ARB_TEXTURE_FLOAT, 0 },
86 {"GL_ARB_texture_mirrored_repeat", ARB_TEXTURE_MIRRORED_REPEAT, 0 },
87 {"GL_ARB_texture_non_power_of_two", ARB_TEXTURE_NON_POWER_OF_TWO, MAKEDWORD_VERSION(2, 0) },
88 {"GL_ARB_texture_rectangle", ARB_TEXTURE_RECTANGLE, 0 },
89 {"GL_ARB_texture_rg", ARB_TEXTURE_RG, 0 },
90 {"GL_ARB_vertex_array_bgra", ARB_VERTEX_ARRAY_BGRA, 0 },
91 {"GL_ARB_vertex_blend", ARB_VERTEX_BLEND, 0 },
92 {"GL_ARB_vertex_buffer_object", ARB_VERTEX_BUFFER_OBJECT, 0 },
93 {"GL_ARB_vertex_program", ARB_VERTEX_PROGRAM, 0 },
94 {"GL_ARB_vertex_shader", ARB_VERTEX_SHADER, 0 },
97 {"GL_ATI_fragment_shader", ATI_FRAGMENT_SHADER, 0 },
98 {"GL_ATI_separate_stencil", ATI_SEPARATE_STENCIL, 0 },
99 {"GL_ATI_texture_compression_3dc", ATI_TEXTURE_COMPRESSION_3DC, 0 },
100 {"GL_ATI_texture_env_combine3", ATI_TEXTURE_ENV_COMBINE3, 0 },
101 {"GL_ATI_texture_mirror_once", ATI_TEXTURE_MIRROR_ONCE, 0 },
104 {"GL_EXT_blend_color", EXT_BLEND_COLOR, 0 },
105 {"GL_EXT_blend_equation_separate", EXT_BLEND_EQUATION_SEPARATE, 0 },
106 {"GL_EXT_blend_func_separate", EXT_BLEND_FUNC_SEPARATE, 0 },
107 {"GL_EXT_blend_minmax", EXT_BLEND_MINMAX, 0 },
108 {"GL_EXT_depth_bounds_test", EXT_DEPTH_BOUNDS_TEST, 0 },
109 {"GL_EXT_draw_buffers2", EXT_DRAW_BUFFERS2, 0 },
110 {"GL_EXT_fog_coord", EXT_FOG_COORD, 0 },
111 {"GL_EXT_framebuffer_blit", EXT_FRAMEBUFFER_BLIT, 0 },
112 {"GL_EXT_framebuffer_multisample", EXT_FRAMEBUFFER_MULTISAMPLE, 0 },
113 {"GL_EXT_framebuffer_object", EXT_FRAMEBUFFER_OBJECT, 0 },
114 {"GL_EXT_gpu_program_parameters", EXT_GPU_PROGRAM_PARAMETERS, 0 },
115 {"GL_EXT_gpu_shader4", EXT_GPU_SHADER4, 0 },
116 {"GL_EXT_packed_depth_stencil", EXT_PACKED_DEPTH_STENCIL, 0 },
117 {"GL_EXT_paletted_texture", EXT_PALETTED_TEXTURE, 0 },
118 {"GL_EXT_point_parameters", EXT_POINT_PARAMETERS, 0 },
119 {"GL_EXT_provoking_vertex", EXT_PROVOKING_VERTEX, 0 },
120 {"GL_EXT_secondary_color", EXT_SECONDARY_COLOR, 0 },
121 {"GL_EXT_stencil_two_side", EXT_STENCIL_TWO_SIDE, 0 },
122 {"GL_EXT_stencil_wrap", EXT_STENCIL_WRAP, 0 },
123 {"GL_EXT_texture3D", EXT_TEXTURE3D, MAKEDWORD_VERSION(1, 2) },
124 {"GL_EXT_texture_compression_rgtc", EXT_TEXTURE_COMPRESSION_RGTC, 0 },
125 {"GL_EXT_texture_compression_s3tc", EXT_TEXTURE_COMPRESSION_S3TC, 0 },
126 {"GL_EXT_texture_env_add", EXT_TEXTURE_ENV_ADD, 0 },
127 {"GL_EXT_texture_env_combine", EXT_TEXTURE_ENV_COMBINE, 0 },
128 {"GL_EXT_texture_env_dot3", EXT_TEXTURE_ENV_DOT3, 0 },
129 {"GL_EXT_texture_filter_anisotropic", EXT_TEXTURE_FILTER_ANISOTROPIC, 0 },
130 {"GL_EXT_texture_lod_bias", EXT_TEXTURE_LOD_BIAS, 0 },
131 {"GL_EXT_texture_sRGB", EXT_TEXTURE_SRGB, 0 },
132 {"GL_EXT_vertex_array_bgra", EXT_VERTEX_ARRAY_BGRA, 0 },
135 {"GL_NV_depth_clamp", NV_DEPTH_CLAMP, 0 },
136 {"GL_NV_fence", NV_FENCE, 0 },
137 {"GL_NV_fog_distance", NV_FOG_DISTANCE, 0 },
138 {"GL_NV_fragment_program", NV_FRAGMENT_PROGRAM, 0 },
139 {"GL_NV_fragment_program2", NV_FRAGMENT_PROGRAM2, 0 },
140 {"GL_NV_fragment_program_option", NV_FRAGMENT_PROGRAM_OPTION, 0 },
141 {"GL_NV_half_float", NV_HALF_FLOAT, 0 },
142 {"GL_NV_light_max_exponent", NV_LIGHT_MAX_EXPONENT, 0 },
143 {"GL_NV_point_sprite", NV_POINT_SPRITE, 0 },
144 {"GL_NV_register_combiners", NV_REGISTER_COMBINERS, 0 },
145 {"GL_NV_register_combiners2", NV_REGISTER_COMBINERS2, 0 },
146 {"GL_NV_texgen_reflection", NV_TEXGEN_REFLECTION, 0 },
147 {"GL_NV_texture_env_combine4", NV_TEXTURE_ENV_COMBINE4, 0 },
148 {"GL_NV_texture_shader", NV_TEXTURE_SHADER, 0 },
149 {"GL_NV_texture_shader2", NV_TEXTURE_SHADER2, 0 },
150 {"GL_NV_vertex_program", NV_VERTEX_PROGRAM, 0 },
151 {"GL_NV_vertex_program1_1", NV_VERTEX_PROGRAM1_1, 0 },
152 {"GL_NV_vertex_program2", NV_VERTEX_PROGRAM2, 0 },
153 {"GL_NV_vertex_program2_option", NV_VERTEX_PROGRAM2_OPTION, 0 },
154 {"GL_NV_vertex_program3", NV_VERTEX_PROGRAM3, 0 },
157 {"GL_SGIS_generate_mipmap", SGIS_GENERATE_MIPMAP, 0 },
160 /**********************************************************
161 * Utility functions follow
162 **********************************************************/
164 const struct min_lookup minMipLookup[] =
166 /* NONE POINT LINEAR */
167 {{GL_NEAREST, GL_NEAREST, GL_NEAREST}}, /* NONE */
168 {{GL_NEAREST, GL_NEAREST_MIPMAP_NEAREST, GL_NEAREST_MIPMAP_LINEAR}}, /* POINT*/
169 {{GL_LINEAR, GL_LINEAR_MIPMAP_NEAREST, GL_LINEAR_MIPMAP_LINEAR}}, /* LINEAR */
172 const struct min_lookup minMipLookup_noFilter[] =
174 /* NONE POINT LINEAR */
175 {{GL_NEAREST, GL_NEAREST, GL_NEAREST}}, /* NONE */
176 {{GL_NEAREST, GL_NEAREST, GL_NEAREST}}, /* POINT */
177 {{GL_NEAREST, GL_NEAREST, GL_NEAREST}}, /* LINEAR */
180 const struct min_lookup minMipLookup_noMip[] =
182 /* NONE POINT LINEAR */
183 {{GL_NEAREST, GL_NEAREST, GL_NEAREST}}, /* NONE */
184 {{GL_NEAREST, GL_NEAREST, GL_NEAREST}}, /* POINT */
185 {{GL_LINEAR, GL_LINEAR, GL_LINEAR }}, /* LINEAR */
188 const GLenum magLookup[] =
190 /* NONE POINT LINEAR */
191 GL_NEAREST, GL_NEAREST, GL_LINEAR,
194 const GLenum magLookup_noFilter[] =
196 /* NONE POINT LINEAR */
197 GL_NEAREST, GL_NEAREST, GL_NEAREST,
200 /* drawStridedSlow attributes */
201 glAttribFunc position_funcs[WINED3D_FFP_EMIT_COUNT];
202 glAttribFunc diffuse_funcs[WINED3D_FFP_EMIT_COUNT];
203 glAttribFunc specular_func_3ubv;
204 glAttribFunc specular_funcs[WINED3D_FFP_EMIT_COUNT];
205 glAttribFunc normal_funcs[WINED3D_FFP_EMIT_COUNT];
206 glMultiTexCoordFunc multi_texcoord_funcs[WINED3D_FFP_EMIT_COUNT];
209 * Note: GL seems to trap if GetDeviceCaps is called before any HWND's created,
210 * i.e., there is no GL Context - Get a default rendering context to enable the
211 * function query some info from GL.
214 struct wined3d_fake_gl_ctx
220 HGLRC restore_gl_ctx;
223 static void WineD3D_ReleaseFakeGLContext(struct wined3d_fake_gl_ctx *ctx)
225 TRACE_(d3d_caps)("Destroying fake GL context.\n");
227 if (!pwglMakeCurrent(NULL, NULL))
229 ERR_(d3d_caps)("Failed to disable fake GL context.\n");
232 if (!pwglDeleteContext(ctx->gl_ctx))
234 DWORD err = GetLastError();
235 ERR("wglDeleteContext(%p) failed, last error %#x.\n", ctx->gl_ctx, err);
238 ReleaseDC(ctx->wnd, ctx->dc);
239 DestroyWindow(ctx->wnd);
241 if (ctx->restore_gl_ctx && !pwglMakeCurrent(ctx->restore_dc, ctx->restore_gl_ctx))
243 ERR_(d3d_caps)("Failed to restore previous GL context.\n");
247 /* Do not call while under the GL lock. */
248 static BOOL WineD3D_CreateFakeGLContext(struct wined3d_fake_gl_ctx *ctx)
250 PIXELFORMATDESCRIPTOR pfd;
253 TRACE("getting context...\n");
255 ctx->restore_dc = pwglGetCurrentDC();
256 ctx->restore_gl_ctx = pwglGetCurrentContext();
258 /* We need a fake window as a hdc retrieved using GetDC(0) can't be used for much GL purposes. */
259 ctx->wnd = CreateWindowA(WINED3D_OPENGL_WINDOW_CLASS_NAME, "WineD3D fake window",
260 WS_OVERLAPPEDWINDOW, 10, 10, 10, 10, NULL, NULL, NULL, NULL);
263 ERR_(d3d_caps)("Failed to create a window.\n");
267 ctx->dc = GetDC(ctx->wnd);
270 ERR_(d3d_caps)("Failed to get a DC.\n");
274 /* PixelFormat selection */
275 ZeroMemory(&pfd, sizeof(pfd));
276 pfd.nSize = sizeof(pfd);
278 pfd.dwFlags = PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER | PFD_DRAW_TO_WINDOW; /* PFD_GENERIC_ACCELERATED */
279 pfd.iPixelType = PFD_TYPE_RGBA;
281 pfd.iLayerType = PFD_MAIN_PLANE;
283 iPixelFormat = ChoosePixelFormat(ctx->dc, &pfd);
286 /* If this happens something is very wrong as ChoosePixelFormat barely fails. */
287 ERR_(d3d_caps)("Can't find a suitable iPixelFormat.\n");
290 DescribePixelFormat(ctx->dc, iPixelFormat, sizeof(pfd), &pfd);
291 SetPixelFormat(ctx->dc, iPixelFormat, &pfd);
293 /* Create a GL context. */
294 ctx->gl_ctx = pwglCreateContext(ctx->dc);
297 WARN_(d3d_caps)("Error creating default context for capabilities initialization.\n");
301 /* Make it the current GL context. */
302 if (!context_set_current(NULL))
304 ERR_(d3d_caps)("Failed to clear current D3D context.\n");
307 if (!pwglMakeCurrent(ctx->dc, ctx->gl_ctx))
309 ERR_(d3d_caps)("Failed to make fake GL context current.\n");
316 if (ctx->gl_ctx) pwglDeleteContext(ctx->gl_ctx);
318 if (ctx->dc) ReleaseDC(ctx->wnd, ctx->dc);
320 if (ctx->wnd) DestroyWindow(ctx->wnd);
322 if (ctx->restore_gl_ctx && !pwglMakeCurrent(ctx->restore_dc, ctx->restore_gl_ctx))
324 ERR_(d3d_caps)("Failed to restore previous GL context.\n");
330 /* Adjust the amount of used texture memory */
331 unsigned int WineD3DAdapterChangeGLRam(IWineD3DDeviceImpl *device, unsigned int glram)
333 struct wined3d_adapter *adapter = device->adapter;
335 adapter->UsedTextureRam += glram;
336 TRACE("Adjusted gl ram by %d to %d\n", glram, adapter->UsedTextureRam);
337 return adapter->UsedTextureRam;
340 static void wined3d_adapter_cleanup(struct wined3d_adapter *adapter)
342 HeapFree(GetProcessHeap(), 0, adapter->gl_info.formats);
343 HeapFree(GetProcessHeap(), 0, adapter->cfgs);
346 /**********************************************************
347 * IUnknown parts follows
348 **********************************************************/
350 static HRESULT WINAPI IWineD3DImpl_QueryInterface(IWineD3D *iface,REFIID riid,LPVOID *ppobj)
352 IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
354 TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(riid),ppobj);
355 if (IsEqualGUID(riid, &IID_IUnknown)
356 || IsEqualGUID(riid, &IID_IWineD3DBase)
357 || IsEqualGUID(riid, &IID_IWineD3DDevice)) {
358 IUnknown_AddRef(iface);
363 return E_NOINTERFACE;
366 static ULONG WINAPI IWineD3DImpl_AddRef(IWineD3D *iface) {
367 IWineD3DImpl *This = (IWineD3DImpl *)iface;
368 ULONG refCount = InterlockedIncrement(&This->ref);
370 TRACE("(%p) : AddRef increasing from %d\n", This, refCount - 1);
374 static ULONG WINAPI IWineD3DImpl_Release(IWineD3D *iface) {
375 IWineD3DImpl *This = (IWineD3DImpl *)iface;
377 TRACE("(%p) : Releasing from %d\n", This, This->ref);
378 ref = InterlockedDecrement(&This->ref);
384 for (i = 0; i < This->adapter_count; ++i)
386 wined3d_adapter_cleanup(&This->adapters[i]);
388 HeapFree(GetProcessHeap(), 0, This);
394 /**********************************************************
395 * IWineD3D parts follows
396 **********************************************************/
398 /* GL locking is done by the caller */
399 static inline BOOL test_arb_vs_offset_limit(const struct wined3d_gl_info *gl_info)
403 const char *testcode =
405 "PARAM C[66] = { program.env[0..65] };\n"
407 "PARAM zero = {0.0, 0.0, 0.0, 0.0};\n"
408 "ARL A0.x, zero.x;\n"
409 "MOV result.position, C[A0.x + 65];\n"
413 GL_EXTCALL(glGenProgramsARB(1, &prog));
415 ERR("Failed to create an ARB offset limit test program\n");
417 GL_EXTCALL(glBindProgramARB(GL_VERTEX_PROGRAM_ARB, prog));
418 GL_EXTCALL(glProgramStringARB(GL_VERTEX_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB,
419 strlen(testcode), testcode));
422 TRACE("OpenGL implementation does not allow indirect addressing offsets > 63\n");
423 TRACE("error: %s\n", debugstr_a((const char *)glGetString(GL_PROGRAM_ERROR_STRING_ARB)));
425 } else TRACE("OpenGL implementation allows offsets > 63\n");
427 GL_EXTCALL(glBindProgramARB(GL_VERTEX_PROGRAM_ARB, 0));
428 GL_EXTCALL(glDeleteProgramsARB(1, &prog));
429 checkGLcall("ARB vp offset limit test cleanup");
434 static DWORD ver_for_ext(GL_SupportedExt ext)
437 for (i = 0; i < (sizeof(EXTENSION_MAP) / sizeof(*EXTENSION_MAP)); ++i) {
438 if(EXTENSION_MAP[i].extension == ext) {
439 return EXTENSION_MAP[i].version;
445 static BOOL match_ati_r300_to_500(const struct wined3d_gl_info *gl_info, const char *gl_renderer,
446 enum wined3d_gl_vendor gl_vendor, enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device)
448 if (card_vendor != HW_VENDOR_ATI) return FALSE;
449 if (device == CARD_ATI_RADEON_9500) return TRUE;
450 if (device == CARD_ATI_RADEON_X700) return TRUE;
451 if (device == CARD_ATI_RADEON_X1600) return TRUE;
455 static BOOL match_geforce5(const struct wined3d_gl_info *gl_info, const char *gl_renderer,
456 enum wined3d_gl_vendor gl_vendor, enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device)
458 if (card_vendor == HW_VENDOR_NVIDIA)
460 if (device == CARD_NVIDIA_GEFORCEFX_5200 ||
461 device == CARD_NVIDIA_GEFORCEFX_5600 ||
462 device == CARD_NVIDIA_GEFORCEFX_5800)
470 static BOOL match_apple(const struct wined3d_gl_info *gl_info, const char *gl_renderer,
471 enum wined3d_gl_vendor gl_vendor, enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device)
473 /* MacOS has various specialities in the extensions it advertises. Some have to be loaded from
474 * the opengl 1.2+ core, while other extensions are advertised, but software emulated. So try to
475 * detect the Apple OpenGL implementation to apply some extension fixups afterwards.
477 * Detecting this isn't really easy. The vendor string doesn't mention Apple. Compile-time checks
478 * aren't sufficient either because a Linux binary may display on a macos X server via remote X11.
479 * So try to detect the GL implementation by looking at certain Apple extensions. Some extensions
480 * like client storage might be supported on other implementations too, but GL_APPLE_flush_render
481 * is specific to the Mac OS X window management, and GL_APPLE_ycbcr_422 is QuickTime specific. So
482 * the chance that other implementations support them is rather small since Win32 QuickTime uses
483 * DirectDraw, not OpenGL.
485 * This test has been moved into wined3d_guess_gl_vendor()
487 if (gl_vendor == GL_VENDOR_APPLE)
494 /* Context activation is done by the caller. */
495 static void test_pbo_functionality(struct wined3d_gl_info *gl_info)
497 /* Some OpenGL implementations, namely Apple's Geforce 8 driver, advertises PBOs,
498 * but glTexSubImage from a PBO fails miserably, with the first line repeated over
499 * all the texture. This function detects this bug by its symptom and disables PBOs
502 * The test uploads a 4x4 texture via the PBO in the "native" format GL_BGRA,
503 * GL_UNSIGNED_INT_8_8_8_8_REV. This format triggers the bug, and it is what we use
504 * for D3DFMT_A8R8G8B8. Then the texture is read back without any PBO and the data
505 * read back is compared to the original. If they are equal PBOs are assumed to work,
506 * otherwise the PBO extension is disabled. */
508 static const unsigned int pattern[] =
510 0x00000000, 0x000000ff, 0x0000ff00, 0x40ff0000,
511 0x80ffffff, 0x40ffff00, 0x00ff00ff, 0x0000ffff,
512 0x00ffff00, 0x00ff00ff, 0x0000ffff, 0x000000ff,
513 0x80ff00ff, 0x0000ffff, 0x00ff00ff, 0x40ff00ff
515 unsigned int check[sizeof(pattern) / sizeof(pattern[0])];
517 /* No PBO -> No point in testing them. */
518 if (!gl_info->supported[ARB_PIXEL_BUFFER_OBJECT]) return;
522 while (glGetError());
523 glGenTextures(1, &texture);
524 glBindTexture(GL_TEXTURE_2D, texture);
526 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
527 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 4, 4, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, 0);
528 checkGLcall("Specifying the PBO test texture");
530 GL_EXTCALL(glGenBuffersARB(1, &pbo));
531 GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, pbo));
532 GL_EXTCALL(glBufferDataARB(GL_PIXEL_UNPACK_BUFFER_ARB, sizeof(pattern), pattern, GL_STREAM_DRAW_ARB));
533 checkGLcall("Specifying the PBO test pbo");
535 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 4, 4, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL);
536 checkGLcall("Loading the PBO test texture");
538 GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0));
541 wglFinish(); /* just to be sure */
543 memset(check, 0, sizeof(check));
545 glGetTexImage(GL_TEXTURE_2D, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, check);
546 checkGLcall("Reading back the PBO test texture");
548 glDeleteTextures(1, &texture);
549 GL_EXTCALL(glDeleteBuffersARB(1, &pbo));
550 checkGLcall("PBO test cleanup");
554 if (memcmp(check, pattern, sizeof(check)))
556 WARN_(d3d_caps)("PBO test failed, read back data doesn't match original.\n");
557 WARN_(d3d_caps)("Disabling PBOs. This may result in slower performance.\n");
558 gl_info->supported[ARB_PIXEL_BUFFER_OBJECT] = FALSE;
562 TRACE_(d3d_caps)("PBO test successful.\n");
566 static BOOL match_apple_intel(const struct wined3d_gl_info *gl_info, const char *gl_renderer,
567 enum wined3d_gl_vendor gl_vendor, enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device)
569 return (card_vendor == HW_VENDOR_INTEL) && (gl_vendor == GL_VENDOR_APPLE);
572 static BOOL match_apple_nonr500ati(const struct wined3d_gl_info *gl_info, const char *gl_renderer,
573 enum wined3d_gl_vendor gl_vendor, enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device)
575 if (gl_vendor != GL_VENDOR_APPLE) return FALSE;
576 if (card_vendor != HW_VENDOR_ATI) return FALSE;
577 if (device == CARD_ATI_RADEON_X1600) return FALSE;
581 static BOOL match_fglrx(const struct wined3d_gl_info *gl_info, const char *gl_renderer,
582 enum wined3d_gl_vendor gl_vendor, enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device)
584 return gl_vendor == GL_VENDOR_FGLRX;
588 static BOOL match_dx10_capable(const struct wined3d_gl_info *gl_info, const char *gl_renderer,
589 enum wined3d_gl_vendor gl_vendor, enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device)
591 /* DX9 cards support 40 single float varyings in hardware, most drivers report 32. ATI misreports
592 * 44 varyings. So assume that if we have more than 44 varyings we have a dx10 card.
593 * This detection is for the gl_ClipPos varying quirk. If a d3d9 card really supports more than 44
594 * varyings and we subtract one in dx9 shaders its not going to hurt us because the dx9 limit is
597 * dx10 cards usually have 64 varyings */
598 return gl_info->limits.glsl_varyings > 44;
601 /* A GL context is provided by the caller */
602 static BOOL match_allows_spec_alpha(const struct wined3d_gl_info *gl_info, const char *gl_renderer,
603 enum wined3d_gl_vendor gl_vendor, enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device)
608 if (!gl_info->supported[EXT_SECONDARY_COLOR]) return FALSE;
612 GL_EXTCALL(glSecondaryColorPointerEXT)(4, GL_UNSIGNED_BYTE, 4, data);
613 error = glGetError();
616 if(error == GL_NO_ERROR)
618 TRACE("GL Implementation accepts 4 component specular color pointers\n");
623 TRACE("GL implementation does not accept 4 component specular colors, error %s\n",
624 debug_glerror(error));
629 static BOOL match_apple_nvts(const struct wined3d_gl_info *gl_info, const char *gl_renderer,
630 enum wined3d_gl_vendor gl_vendor, enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device)
632 if (!match_apple(gl_info, gl_renderer, gl_vendor, card_vendor, device)) return FALSE;
633 return gl_info->supported[NV_TEXTURE_SHADER];
636 /* A GL context is provided by the caller */
637 static BOOL match_broken_nv_clip(const struct wined3d_gl_info *gl_info, const char *gl_renderer,
638 enum wined3d_gl_vendor gl_vendor, enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device)
643 const char *testcode =
645 "OPTION NV_vertex_program2;\n"
646 "MOV result.clip[0], 0.0;\n"
647 "MOV result.position, 0.0;\n"
650 if (!gl_info->supported[NV_VERTEX_PROGRAM2_OPTION]) return FALSE;
655 GL_EXTCALL(glGenProgramsARB(1, &prog));
658 ERR("Failed to create the NVvp clip test program\n");
662 GL_EXTCALL(glBindProgramARB(GL_VERTEX_PROGRAM_ARB, prog));
663 GL_EXTCALL(glProgramStringARB(GL_VERTEX_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB,
664 strlen(testcode), testcode));
665 glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB, &pos);
668 WARN("GL_NV_vertex_program2_option result.clip[] test failed\n");
669 TRACE("error: %s\n", debugstr_a((const char *)glGetString(GL_PROGRAM_ERROR_STRING_ARB)));
673 else TRACE("GL_NV_vertex_program2_option result.clip[] test passed\n");
675 GL_EXTCALL(glBindProgramARB(GL_VERTEX_PROGRAM_ARB, 0));
676 GL_EXTCALL(glDeleteProgramsARB(1, &prog));
677 checkGLcall("GL_NV_vertex_program2_option result.clip[] test cleanup");
683 /* Context activation is done by the caller. */
684 static BOOL match_fbo_tex_update(const struct wined3d_gl_info *gl_info, const char *gl_renderer,
685 enum wined3d_gl_vendor gl_vendor, enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device)
687 char data[4 * 4 * 4];
691 if (wined3d_settings.offscreen_rendering_mode != ORM_FBO) return FALSE;
693 memset(data, 0xcc, sizeof(data));
697 glGenTextures(1, &tex);
698 glBindTexture(GL_TEXTURE_2D, tex);
699 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
700 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
701 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 4, 4, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL);
702 checkGLcall("glTexImage2D");
704 gl_info->fbo_ops.glGenFramebuffers(1, &fbo);
705 gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, fbo);
706 gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
707 checkGLcall("glFramebufferTexture2D");
709 status = gl_info->fbo_ops.glCheckFramebufferStatus(GL_FRAMEBUFFER);
710 if (status != GL_FRAMEBUFFER_COMPLETE) ERR("FBO status %#x\n", status);
711 checkGLcall("glCheckFramebufferStatus");
713 memset(data, 0x11, sizeof(data));
714 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 4, 4, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, data);
715 checkGLcall("glTexSubImage2D");
717 glClearColor(0.996f, 0.729f, 0.745f, 0.792f);
718 glClear(GL_COLOR_BUFFER_BIT);
719 checkGLcall("glClear");
721 glGetTexImage(GL_TEXTURE_2D, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, data);
722 checkGLcall("glGetTexImage");
724 gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
725 gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, 0);
726 glBindTexture(GL_TEXTURE_2D, 0);
727 checkGLcall("glBindTexture");
729 gl_info->fbo_ops.glDeleteFramebuffers(1, &fbo);
730 glDeleteTextures(1, &tex);
731 checkGLcall("glDeleteTextures");
735 return *(DWORD *)data == 0x11111111;
738 static void quirk_arb_constants(struct wined3d_gl_info *gl_info)
740 TRACE_(d3d_caps)("Using ARB vs constant limit(=%u) for GLSL.\n", gl_info->limits.arb_vs_native_constants);
741 gl_info->limits.glsl_vs_float_constants = gl_info->limits.arb_vs_native_constants;
742 TRACE_(d3d_caps)("Using ARB ps constant limit(=%u) for GLSL.\n", gl_info->limits.arb_ps_native_constants);
743 gl_info->limits.glsl_ps_float_constants = gl_info->limits.arb_ps_native_constants;
746 static void quirk_apple_glsl_constants(struct wined3d_gl_info *gl_info)
748 quirk_arb_constants(gl_info);
749 /* MacOS needs uniforms for relative addressing offsets. This can accumulate to quite a few uniforms.
750 * Beyond that the general uniform isn't optimal, so reserve a number of uniforms. 12 vec4's should
751 * allow 48 different offsets or other helper immediate values. */
752 TRACE_(d3d_caps)("Reserving 12 GLSL constants for compiler private use.\n");
753 gl_info->reserved_glsl_constants = max(gl_info->reserved_glsl_constants, 12);
756 /* fglrx crashes with a very bad kernel panic if GL_POINT_SPRITE_ARB is set to GL_COORD_REPLACE_ARB
757 * on more than one texture unit. This means that the d3d9 visual point size test will cause a
758 * kernel panic on any machine running fglrx 9.3(latest that supports r300 to r500 cards). This
759 * quirk only enables point sprites on the first texture unit. This keeps point sprites working in
760 * most games, but avoids the crash
762 * A more sophisticated way would be to find all units that need texture coordinates and enable
763 * point sprites for one if only one is found, and software emulate point sprites in drawStridedSlow
764 * if more than one unit needs texture coordinates(This requires software ffp and vertex shaders though)
766 * Note that disabling the extension entirely does not gain predictability because there is no point
767 * sprite capability flag in d3d, so the potential rendering bugs are the same if we disable the extension. */
768 static void quirk_one_point_sprite(struct wined3d_gl_info *gl_info)
770 if (gl_info->supported[ARB_POINT_SPRITE])
772 TRACE("Limiting point sprites to one texture unit.\n");
773 gl_info->limits.point_sprite_units = 1;
777 static void quirk_ati_dx9(struct wined3d_gl_info *gl_info)
779 quirk_arb_constants(gl_info);
781 /* MacOS advertises GL_ARB_texture_non_power_of_two on ATI r500 and earlier cards, although
782 * these cards only support GL_ARB_texture_rectangle(D3DPTEXTURECAPS_NONPOW2CONDITIONAL).
783 * If real NP2 textures are used, the driver falls back to software. We could just remove the
784 * extension and use GL_ARB_texture_rectangle instead, but texture_rectangle is inconventient
785 * due to the non-normalized texture coordinates. Thus set an internal extension flag,
786 * GL_WINE_normalized_texrect, which signals the code that it can use non power of two textures
787 * as per GL_ARB_texture_non_power_of_two, but has to stick to the texture_rectangle limits.
789 * fglrx doesn't advertise GL_ARB_texture_non_power_of_two, but it advertises opengl 2.0 which
790 * has this extension promoted to core. The extension loading code sets this extension supported
791 * due to that, so this code works on fglrx as well. */
792 if(gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO])
794 TRACE("GL_ARB_texture_non_power_of_two advertised on R500 or earlier card, removing.\n");
795 gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO] = FALSE;
796 gl_info->supported[WINED3D_GL_NORMALIZED_TEXRECT] = TRUE;
799 /* fglrx has the same structural issues as the one described in quirk_apple_glsl_constants, although
800 * it is generally more efficient. Reserve just 8 constants. */
801 TRACE_(d3d_caps)("Reserving 8 GLSL constants for compiler private use.\n");
802 gl_info->reserved_glsl_constants = max(gl_info->reserved_glsl_constants, 8);
805 static void quirk_no_np2(struct wined3d_gl_info *gl_info)
807 /* The nVidia GeForceFX series reports OpenGL 2.0 capabilities with the latest drivers versions, but
808 * doesn't explicitly advertise the ARB_tex_npot extension in the GL extension string.
809 * This usually means that ARB_tex_npot is supported in hardware as long as the application is staying
810 * within the limits enforced by the ARB_texture_rectangle extension. This however is not true for the
811 * FX series, which instantly falls back to a slower software path as soon as ARB_tex_npot is used.
812 * We therefore completely remove ARB_tex_npot from the list of supported extensions.
814 * Note that wine_normalized_texrect can't be used in this case because internally it uses ARB_tex_npot,
815 * triggering the software fallback. There is not much we can do here apart from disabling the
816 * software-emulated extension and reenable ARB_tex_rect (which was previously disabled
817 * in IWineD3DImpl_FillGLCaps).
818 * This fixup removes performance problems on both the FX 5900 and FX 5700 (e.g. for framebuffer
819 * post-processing effects in the game "Max Payne 2").
820 * The behaviour can be verified through a simple test app attached in bugreport #14724. */
821 TRACE("GL_ARB_texture_non_power_of_two advertised through OpenGL 2.0 on NV FX card, removing.\n");
822 gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO] = FALSE;
823 gl_info->supported[ARB_TEXTURE_RECTANGLE] = TRUE;
826 static void quirk_texcoord_w(struct wined3d_gl_info *gl_info)
828 /* The Intel GPUs on MacOS set the .w register of texcoords to 0.0 by default, which causes problems
829 * with fixed function fragment processing. Ideally this flag should be detected with a test shader
830 * and OpenGL feedback mode, but some GL implementations (MacOS ATI at least, probably all MacOS ones)
831 * do not like vertex shaders in feedback mode and return an error, even though it should be valid
832 * according to the spec.
834 * We don't want to enable this on all cards, as it adds an extra instruction per texcoord used. This
835 * makes the shader slower and eats instruction slots which should be available to the d3d app.
837 * ATI Radeon HD 2xxx cards on MacOS have the issue. Instead of checking for the buggy cards, blacklist
838 * all radeon cards on Macs and whitelist the good ones. That way we're prepared for the future. If
839 * this workaround is activated on cards that do not need it, it won't break things, just affect
840 * performance negatively. */
841 TRACE("Enabling vertex texture coord fixes in vertex shaders.\n");
842 gl_info->quirks |= WINED3D_QUIRK_SET_TEXCOORD_W;
845 static void quirk_clip_varying(struct wined3d_gl_info *gl_info)
847 gl_info->quirks |= WINED3D_QUIRK_GLSL_CLIP_VARYING;
850 static void quirk_allows_specular_alpha(struct wined3d_gl_info *gl_info)
852 gl_info->quirks |= WINED3D_QUIRK_ALLOWS_SPECULAR_ALPHA;
855 static void quirk_apple_nvts(struct wined3d_gl_info *gl_info)
857 gl_info->supported[NV_TEXTURE_SHADER] = FALSE;
858 gl_info->supported[NV_TEXTURE_SHADER2] = FALSE;
861 static void quirk_disable_nvvp_clip(struct wined3d_gl_info *gl_info)
863 gl_info->quirks |= WINED3D_QUIRK_NV_CLIP_BROKEN;
866 static void quirk_fbo_tex_update(struct wined3d_gl_info *gl_info)
868 gl_info->quirks |= WINED3D_QUIRK_FBO_TEX_UPDATE;
873 BOOL (*match)(const struct wined3d_gl_info *gl_info, const char *gl_renderer,
874 enum wined3d_gl_vendor gl_vendor, enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device);
875 void (*apply)(struct wined3d_gl_info *gl_info);
876 const char *description;
879 static const struct driver_quirk quirk_table[] =
882 match_ati_r300_to_500,
884 "ATI GLSL constant and normalized texrect quirk"
886 /* MacOS advertises more GLSL vertex shader uniforms than supported by the hardware, and if more are
887 * used it falls back to software. While the compiler can detect if the shader uses all declared
888 * uniforms, the optimization fails if the shader uses relative addressing. So any GLSL shader
889 * using relative addressing falls back to software.
891 * ARB vp gives the correct amount of uniforms, so use it instead of GLSL. */
894 quirk_apple_glsl_constants,
895 "Apple GLSL uniform override"
900 "Geforce 5 NP2 disable"
905 "Init texcoord .w for Apple Intel GPU driver"
908 match_apple_nonr500ati,
910 "Init texcoord .w for Apple ATI >= r600 GPU driver"
914 quirk_one_point_sprite,
915 "Fglrx point sprite crash workaround"
920 "Reserved varying for gl_ClipPos"
923 /* GL_EXT_secondary_color does not allow 4 component secondary colors, but most
924 * GL implementations accept it. The Mac GL is the only implementation known to
927 * If we can pass 4 component specular colors, do it, because (a) we don't have
928 * to screw around with the data, and (b) the D3D fixed function vertex pipeline
929 * passes specular alpha to the pixel shader if any is used. Otherwise the
930 * specular alpha is used to pass the fog coordinate, which we pass to opengl
931 * via GL_EXT_fog_coord.
933 match_allows_spec_alpha,
934 quirk_allows_specular_alpha,
935 "Allow specular alpha quirk"
938 /* The pixel formats provided by GL_NV_texture_shader are broken on OSX
943 "Apple NV_texture_shader disable"
946 match_broken_nv_clip,
947 quirk_disable_nvvp_clip,
948 "Apple NV_vertex_program clip bug quirk"
951 match_fbo_tex_update,
952 quirk_fbo_tex_update,
953 "FBO rebind for attachment updates"
957 /* Certain applications (Steam) complain if we report an outdated driver version. In general,
958 * reporting a driver version is moot because we are not the Windows driver, and we have different
959 * bugs, features, etc.
961 * The driver version has the form "x.y.z.w".
963 * "x" is the Windows version the driver is meant for:
970 * "y" is the maximum Direct3D version the driver supports.
971 * y -> d3d version mapping:
980 * "z" is the subversion number.
982 * "w" is the vendor specific driver build number.
985 struct driver_version_information
987 enum wined3d_display_driver driver;
988 enum wined3d_driver_model driver_model;
989 const char *driver_name; /* name of Windows driver */
990 WORD version; /* version word ('y'), contained in low word of DriverVersion.HighPart */
991 WORD subversion; /* subversion word ('z'), contained in high word of DriverVersion.LowPart */
992 WORD build; /* build number ('w'), contained in low word of DriverVersion.LowPart */
995 /* The driver version table contains driver information for different devices on several OS versions. */
996 static const struct driver_version_information driver_version_table[] =
999 * - Radeon HD2x00 (R600) and up supported by current drivers.
1000 * - Radeon 9500 (R300) - X1*00 (R5xx) supported up to Catalyst 9.3 (Linux) and 10.2 (XP/Vista/Win7)
1001 * - Radeon 7xxx (R100) - 9250 (RV250) supported up to Catalyst 6.11 (XP)
1002 * - Rage 128 supported up to XP, latest official build 6.13.3279 dated October 2001 */
1003 {DRIVER_ATI_RAGE_128PRO, DRIVER_MODEL_NT5X, "ati2dvaa.dll", 13, 3279, 0},
1004 {DRIVER_ATI_R100, DRIVER_MODEL_NT5X, "ati2dvag.dll", 14, 10, 6614},
1005 {DRIVER_ATI_R300, DRIVER_MODEL_NT5X, "ati2dvag.dll", 14, 10, 6764},
1006 {DRIVER_ATI_R600, DRIVER_MODEL_NT5X, "ati2dvag.dll", 14, 10, 8681},
1007 {DRIVER_ATI_R300, DRIVER_MODEL_NT6X, "atiumdag.dll", 14, 10, 741 },
1008 {DRIVER_ATI_R600, DRIVER_MODEL_NT6X, "atiumdag.dll", 14, 10, 741 },
1011 * The drivers are unified but not all versions support all GPUs. At some point the 2k/xp
1012 * drivers used ialmrnt5.dll for GMA800/GMA900 but at some point the file was renamed to
1013 * igxprd32.dll but the GMA800 driver was never updated. */
1014 {DRIVER_INTEL_GMA800, DRIVER_MODEL_NT5X, "ialmrnt5.dll", 14, 10, 3889},
1015 {DRIVER_INTEL_GMA900, DRIVER_MODEL_NT5X, "igxprd32.dll", 14, 10, 4764},
1016 {DRIVER_INTEL_GMA950, DRIVER_MODEL_NT5X, "igxprd32.dll", 14, 10, 4926},
1017 {DRIVER_INTEL_GMA3000, DRIVER_MODEL_NT5X, "igxprd32.dll", 14, 10, 5218},
1018 {DRIVER_INTEL_GMA950, DRIVER_MODEL_NT6X, "igdumd32.dll", 14, 10, 1504},
1019 {DRIVER_INTEL_GMA3000, DRIVER_MODEL_NT6X, "igdumd32.dll", 15, 10, 1666},
1022 * - Geforce6 and newer cards are supported by the current driver (197.x) on XP-Win7
1023 * - GeforceFX support is up to 173.x on <= XP
1024 * - Geforce2MX/3/4 up to 96.x on <= XP
1025 * - TNT/Geforce1/2 up to 71.x on <= XP
1026 * All version numbers used below are from the Linux nvidia drivers. */
1027 {DRIVER_NVIDIA_TNT, DRIVER_MODEL_NT5X, "nv4_disp.dll", 14, 10, 7186},
1028 {DRIVER_NVIDIA_GEFORCE2MX, DRIVER_MODEL_NT5X, "nv4_disp.dll", 14, 10, 9371},
1029 {DRIVER_NVIDIA_GEFORCEFX, DRIVER_MODEL_NT5X, "nv4_disp.dll", 14, 11, 7516},
1030 {DRIVER_NVIDIA_GEFORCE6, DRIVER_MODEL_NT5X, "nv4_disp.dll", 15, 11, 9745},
1031 {DRIVER_NVIDIA_GEFORCE6, DRIVER_MODEL_NT6X, "nvd3dum.dll", 15, 11, 9745},
1034 struct gpu_description
1036 WORD vendor; /* reported PCI card vendor ID */
1037 WORD card; /* reported PCI card device ID */
1038 const char *description; /* Description of the card e.g. NVIDIA RIVA TNT */
1039 enum wined3d_display_driver driver;
1040 unsigned int vidmem;
1043 /* The amount of video memory stored in the gpu description table is the minimum amount of video memory
1044 * found on a board containing a specific GPU. */
1045 static const struct gpu_description gpu_description_table[] =
1048 {HW_VENDOR_NVIDIA, CARD_NVIDIA_RIVA_TNT, "NVIDIA RIVA TNT", DRIVER_NVIDIA_TNT, 16 },
1049 {HW_VENDOR_NVIDIA, CARD_NVIDIA_RIVA_TNT2, "NVIDIA RIVA TNT2/TNT2 Pro", DRIVER_NVIDIA_TNT, 32 },
1050 {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE, "NVIDIA GeForce 256", DRIVER_NVIDIA_TNT, 32 },
1051 {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE2, "NVIDIA GeForce2 GTS/GeForce2 Pro", DRIVER_NVIDIA_TNT, 32 },
1052 {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE2_MX, "NVIDIA GeForce2 MX/MX 400", DRIVER_NVIDIA_GEFORCE2MX,32 },
1053 {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE3, "NVIDIA GeForce3", DRIVER_NVIDIA_GEFORCE2MX,64 },
1054 {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE4_MX, "NVIDIA GeForce4 MX 460", DRIVER_NVIDIA_GEFORCE2MX,64 },
1055 {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE4_TI4200, "NVIDIA GeForce4 Ti 4200", DRIVER_NVIDIA_GEFORCE2MX,64, },
1056 {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCEFX_5200, "NVIDIA GeForce FX 5200", DRIVER_NVIDIA_GEFORCEFX, 64 },
1057 {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCEFX_5600, "NVIDIA GeForce FX 5600", DRIVER_NVIDIA_GEFORCEFX, 128 },
1058 {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCEFX_5800, "NVIDIA GeForce FX 5800", DRIVER_NVIDIA_GEFORCEFX, 256 },
1059 {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_6200, "NVIDIA GeForce 6200", DRIVER_NVIDIA_GEFORCE6, 64 },
1060 {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_6600GT, "NVIDIA GeForce 6600 GT", DRIVER_NVIDIA_GEFORCE6, 128 },
1061 {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_6800, "NVIDIA GeForce 6800", DRIVER_NVIDIA_GEFORCE6, 128 },
1062 {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_7300, "NVIDIA GeForce Go 7300", DRIVER_NVIDIA_GEFORCE6, 256 },
1063 {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_7400, "NVIDIA GeForce Go 7400", DRIVER_NVIDIA_GEFORCE6, 256 },
1064 {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_7600, "NVIDIA GeForce 7600 GT", DRIVER_NVIDIA_GEFORCE6, 256 },
1065 {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_7800GT, "NVIDIA GeForce 7800 GT", DRIVER_NVIDIA_GEFORCE6, 256 },
1066 {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_8300GS, "NVIDIA GeForce 8300 GS", DRIVER_NVIDIA_GEFORCE6, 128 },
1067 {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_8400GS, "NVIDIA GeForce 8400 GS", DRIVER_NVIDIA_GEFORCE6, 128 },
1068 {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_8600GT, "NVIDIA GeForce 8600 GT", DRIVER_NVIDIA_GEFORCE6, 256 },
1069 {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_8600MGT, "NVIDIA GeForce 8600M GT", DRIVER_NVIDIA_GEFORCE6, 512 },
1070 {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_8800GTS, "NVIDIA GeForce 8800 GTS", DRIVER_NVIDIA_GEFORCE6, 320 },
1071 {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_8800GTX, "NVIDIA GeForce 8800 GTX", DRIVER_NVIDIA_GEFORCE6, 768 },
1072 {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_9200, "NVIDIA GeForce 9200", DRIVER_NVIDIA_GEFORCE6, 256 },
1073 {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_9400GT, "NVIDIA GeForce 9400 GT", DRIVER_NVIDIA_GEFORCE6, 256 },
1074 {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_9500GT, "NVIDIA GeForce 9500 GT", DRIVER_NVIDIA_GEFORCE6, 256 },
1075 {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_9600GT, "NVIDIA GeForce 9600 GT", DRIVER_NVIDIA_GEFORCE6, 384 },
1076 {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_9800GT, "NVIDIA GeForce 9800 GT", DRIVER_NVIDIA_GEFORCE6, 512 },
1077 {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_210, "NVIDIA GeForce 210", DRIVER_NVIDIA_GEFORCE6, 512 },
1078 {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GT220, "NVIDIA GeForce GT 220", DRIVER_NVIDIA_GEFORCE6, 512 },
1079 {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GT240, "NVIDIA GeForce GT 240", DRIVER_NVIDIA_GEFORCE6, 512 },
1080 {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX260, "NVIDIA GeForce GTX 260", DRIVER_NVIDIA_GEFORCE6, 1024},
1081 {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX275, "NVIDIA GeForce GTX 275", DRIVER_NVIDIA_GEFORCE6, 896 },
1082 {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX280, "NVIDIA GeForce GTX 280", DRIVER_NVIDIA_GEFORCE6, 1024},
1083 {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GT325M, "NVIDIA GeForce GT 325M", DRIVER_NVIDIA_GEFORCE6, 1024},
1084 {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTS350M, "NVIDIA GeForce GTS 350M", DRIVER_NVIDIA_GEFORCE6, 1024},
1085 {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX460, "NVIDIA GeForce GTX 460", DRIVER_NVIDIA_GEFORCE6, 768 },
1086 {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX465, "NVIDIA GeForce GTX 465", DRIVER_NVIDIA_GEFORCE6, 1024},
1087 {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX470, "NVIDIA GeForce GTX 470", DRIVER_NVIDIA_GEFORCE6, 1280},
1088 {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX480, "NVIDIA GeForce GTX 480", DRIVER_NVIDIA_GEFORCE6, 1536},
1090 {HW_VENDOR_ATI, CARD_ATI_RAGE_128PRO, "ATI Rage Fury", DRIVER_ATI_RAGE_128PRO, 16 },
1091 {HW_VENDOR_ATI, CARD_ATI_RADEON_7200, "ATI RADEON 7200 SERIES", DRIVER_ATI_R100, 32 },
1092 {HW_VENDOR_ATI, CARD_ATI_RADEON_8500, "ATI RADEON 8500 SERIES", DRIVER_ATI_R100, 64 },
1093 {HW_VENDOR_ATI, CARD_ATI_RADEON_9500, "ATI Radeon 9500", DRIVER_ATI_R300, 64 },
1094 {HW_VENDOR_ATI, CARD_ATI_RADEON_XPRESS_200M, "ATI RADEON XPRESS 200M Series", DRIVER_ATI_R300, 64 },
1095 {HW_VENDOR_ATI, CARD_ATI_RADEON_X700, "ATI Radeon X700 SE", DRIVER_ATI_R300, 128 },
1096 {HW_VENDOR_ATI, CARD_ATI_RADEON_X1600, "ATI Radeon X1600 Series", DRIVER_ATI_R300, 128 },
1097 {HW_VENDOR_ATI, CARD_ATI_RADEON_HD2350, "ATI Mobility Radeon HD 2350", DRIVER_ATI_R600, 256 },
1098 {HW_VENDOR_ATI, CARD_ATI_RADEON_HD2600, "ATI Mobility Radeon HD 2600", DRIVER_ATI_R600, 256 },
1099 {HW_VENDOR_ATI, CARD_ATI_RADEON_HD2900, "ATI Radeon HD 2900 XT", DRIVER_ATI_R600, 512 },
1100 {HW_VENDOR_ATI, CARD_ATI_RADEON_HD3200, "ATI Radeon HD 3200 Graphics", DRIVER_ATI_R600, 128 },
1101 {HW_VENDOR_ATI, CARD_ATI_RADEON_HD4350, "ATI Radeon HD 4350", DRIVER_ATI_R600, 256 },
1102 {HW_VENDOR_ATI, CARD_ATI_RADEON_HD4600, "ATI Radeon HD 4600 Series", DRIVER_ATI_R600, 512 },
1103 {HW_VENDOR_ATI, CARD_ATI_RADEON_HD4700, "ATI Radeon HD 4700 Series", DRIVER_ATI_R600, 512 },
1104 {HW_VENDOR_ATI, CARD_ATI_RADEON_HD4800, "ATI Radeon HD 4800 Series", DRIVER_ATI_R600, 512 },
1105 {HW_VENDOR_ATI, CARD_ATI_RADEON_HD5400, "ATI Radeon HD 5400 Series", DRIVER_ATI_R600, 512 },
1106 {HW_VENDOR_ATI, CARD_ATI_RADEON_HD5600, "ATI Radeon HD 5600 Series", DRIVER_ATI_R600, 512 },
1107 {HW_VENDOR_ATI, CARD_ATI_RADEON_HD5700, "ATI Radeon HD 5700 Series", DRIVER_ATI_R600, 512 },
1108 {HW_VENDOR_ATI, CARD_ATI_RADEON_HD5800, "ATI Radeon HD 5800 Series", DRIVER_ATI_R600, 1024},
1109 {HW_VENDOR_ATI, CARD_ATI_RADEON_HD5900, "ATI Radeon HD 5900 Series", DRIVER_ATI_R600, 1024},
1111 {HW_VENDOR_INTEL, CARD_INTEL_I830G, "Intel(R) 82830M Graphics Controller", DRIVER_INTEL_GMA800, 32 },
1112 {HW_VENDOR_INTEL, CARD_INTEL_I855G, "Intel(R) 82852/82855 GM/GME Graphics Controller", DRIVER_INTEL_GMA800, 32 },
1113 {HW_VENDOR_INTEL, CARD_INTEL_I865G, "Intel(R) 82865G Graphics Controller", DRIVER_INTEL_GMA800, 32 },
1114 {HW_VENDOR_INTEL, CARD_INTEL_I915G, "Intel(R) 82915G/GV/910GL Express Chipset Family", DRIVER_INTEL_GMA900, 64 },
1115 {HW_VENDOR_INTEL, CARD_INTEL_I915GM, "Mobile Intel(R) 915GM/GMS,910GML Express Chipset Family", DRIVER_INTEL_GMA900, 64 },
1116 {HW_VENDOR_INTEL, CARD_INTEL_I945GM, "Mobile Intel(R) 945GM Express Chipset Family", DRIVER_INTEL_GMA950, 64 },
1117 {HW_VENDOR_INTEL, CARD_INTEL_X3100, "Mobile Intel(R) 965 Express Chipset Family", DRIVER_INTEL_GMA3000, 128}
1120 static const struct driver_version_information *get_driver_version_info(enum wined3d_display_driver driver,
1121 enum wined3d_driver_model driver_model)
1125 TRACE("Looking up version info for driver=%d driver_model=%d\n", driver, driver_model);
1126 for (i = 0; i < (sizeof(driver_version_table) / sizeof(driver_version_table[0])); i++)
1128 const struct driver_version_information *entry = &driver_version_table[i];
1130 if (entry->driver == driver && entry->driver_model == driver_model)
1132 TRACE_(d3d_caps)("Found driver '%s' version=%d subversion=%d build=%d\n",
1133 entry->driver_name, entry->version, entry->subversion, entry->build);
1141 static void init_driver_info(struct wined3d_driver_info *driver_info,
1142 enum wined3d_pci_vendor vendor, enum wined3d_pci_device device)
1144 OSVERSIONINFOW os_version;
1145 WORD driver_os_version;
1147 enum wined3d_display_driver driver = DRIVER_UNKNOWN;
1148 enum wined3d_driver_model driver_model;
1149 const struct driver_version_information *version_info;
1151 if (wined3d_settings.pci_vendor_id != PCI_VENDOR_NONE)
1153 TRACE_(d3d_caps)("Overriding PCI vendor ID with: %04x\n", wined3d_settings.pci_vendor_id);
1154 vendor = wined3d_settings.pci_vendor_id;
1156 driver_info->vendor = vendor;
1158 if (wined3d_settings.pci_device_id != PCI_DEVICE_NONE)
1160 TRACE_(d3d_caps)("Overriding PCI device ID with: %04x\n", wined3d_settings.pci_device_id);
1161 device = wined3d_settings.pci_device_id;
1163 driver_info->device = device;
1165 /* Set a default amount of video memory (64MB). In general this code isn't used unless the user
1166 * overrides the pci ids to a card which is not in our database. */
1167 driver_info->vidmem = WINE_DEFAULT_VIDMEM;
1169 memset(&os_version, 0, sizeof(os_version));
1170 os_version.dwOSVersionInfoSize = sizeof(os_version);
1171 if (!GetVersionExW(&os_version))
1173 ERR("Failed to get OS version, reporting 2000/XP.\n");
1174 driver_os_version = 6;
1175 driver_model = DRIVER_MODEL_NT5X;
1179 TRACE("OS version %u.%u.\n", os_version.dwMajorVersion, os_version.dwMinorVersion);
1180 switch (os_version.dwMajorVersion)
1183 /* If needed we could distinguish between 9x and NT4, but this code won't make
1184 * sense for NT4 since it had no way to obtain this info through DirectDraw 3.0.
1186 driver_os_version = 4;
1187 driver_model = DRIVER_MODEL_WIN9X;
1191 driver_os_version = 6;
1192 driver_model = DRIVER_MODEL_NT5X;
1196 if (os_version.dwMinorVersion == 0)
1198 driver_os_version = 7;
1199 driver_model = DRIVER_MODEL_NT6X;
1203 if (os_version.dwMinorVersion > 1)
1205 FIXME("Unhandled OS version %u.%u, reporting Win 7.\n",
1206 os_version.dwMajorVersion, os_version.dwMinorVersion);
1208 driver_os_version = 8;
1209 driver_model = DRIVER_MODEL_NT6X;
1214 FIXME("Unhandled OS version %u.%u, reporting 2000/XP.\n",
1215 os_version.dwMajorVersion, os_version.dwMinorVersion);
1216 driver_os_version = 6;
1217 driver_model = DRIVER_MODEL_NT5X;
1222 /* When we reach this stage we always have a vendor or device id (it can be a default one).
1223 * This means that unless the ids are overriden, we will always find a GPU description. */
1224 for (i = 0; i < (sizeof(gpu_description_table) / sizeof(gpu_description_table[0])); i++)
1226 if (vendor == gpu_description_table[i].vendor && device == gpu_description_table[i].card)
1228 TRACE_(d3d_caps)("Found card %04x:%04x in driver DB.\n", vendor, device);
1230 driver_info->description = gpu_description_table[i].description;
1231 driver_info->vidmem = gpu_description_table[i].vidmem * 1024*1024;
1232 driver = gpu_description_table[i].driver;
1237 if (wined3d_settings.emulated_textureram)
1239 TRACE_(d3d_caps)("Overriding amount of video memory with: %d byte\n", wined3d_settings.emulated_textureram);
1240 driver_info->vidmem = wined3d_settings.emulated_textureram;
1243 /* Try to obtain driver version information for the current Windows version. This fails in
1245 * - the gpu is not available on the currently selected OS version:
1246 * - Geforce GTX480 on Win98. When running applications in compatibility mode on Windows,
1247 * version information for the current Windows version is returned instead of faked info.
1248 * We do the same and assume the default Windows version to emulate is WinXP.
1250 * - Videocard is a Riva TNT but winver is set to win7 (there are no drivers for this beast)
1251 * For now return the XP driver info. Perhaps later on we should return VESA.
1253 * - the gpu is not in our database (can happen when the user overrides the vendor_id / device_id)
1254 * This could be an indication that our database is not up to date, so this should be fixed.
1256 version_info = get_driver_version_info(driver, driver_model);
1259 driver_info->name = version_info->driver_name;
1260 driver_info->version_high = MAKEDWORD_VERSION(driver_os_version, version_info->version);
1261 driver_info->version_low = MAKEDWORD_VERSION(version_info->subversion, version_info->build);
1265 version_info = get_driver_version_info(driver, DRIVER_MODEL_NT5X);
1268 driver_info->name = version_info->driver_name;
1269 driver_info->version_high = MAKEDWORD_VERSION(driver_os_version, version_info->version);
1270 driver_info->version_low = MAKEDWORD_VERSION(version_info->subversion, version_info->build);
1274 driver_info->description = "Direct3D HAL";
1275 driver_info->name = "Display";
1276 driver_info->version_high = MAKEDWORD_VERSION(driver_os_version, 15);
1277 driver_info->version_low = MAKEDWORD_VERSION(8, 6); /* Nvidia RIVA TNT, arbitrary */
1279 FIXME("Unable to find a driver/device info for vendor_id=%#x device_id=%#x for driver_model=%d\n",
1280 vendor, device, driver_model);
1284 TRACE_(d3d_caps)("Reporting (fake) driver version 0x%08x-0x%08x.\n",
1285 driver_info->version_high, driver_info->version_low);
1288 /* Context activation is done by the caller. */
1289 static void fixup_extensions(struct wined3d_gl_info *gl_info, const char *gl_renderer,
1290 enum wined3d_gl_vendor gl_vendor, enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device)
1294 for (i = 0; i < (sizeof(quirk_table) / sizeof(*quirk_table)); ++i)
1296 if (!quirk_table[i].match(gl_info, gl_renderer, gl_vendor, card_vendor, device)) continue;
1297 TRACE_(d3d_caps)("Applying driver quirk \"%s\".\n", quirk_table[i].description);
1298 quirk_table[i].apply(gl_info);
1301 /* Find out if PBOs work as they are supposed to. */
1302 test_pbo_functionality(gl_info);
1305 static DWORD wined3d_parse_gl_version(const char *gl_version)
1307 const char *ptr = gl_version;
1311 if (major <= 0) ERR_(d3d_caps)("Invalid opengl major version: %d.\n", major);
1313 while (isdigit(*ptr)) ++ptr;
1314 if (*ptr++ != '.') ERR_(d3d_caps)("Invalid opengl version string: %s.\n", debugstr_a(gl_version));
1318 TRACE_(d3d_caps)("Found OpenGL version: %d.%d.\n", major, minor);
1320 return MAKEDWORD_VERSION(major, minor);
1323 static enum wined3d_gl_vendor wined3d_guess_gl_vendor(struct wined3d_gl_info *gl_info, const char *gl_vendor_string, const char *gl_renderer)
1326 /* MacOS has various specialities in the extensions it advertises. Some have to be loaded from
1327 * the opengl 1.2+ core, while other extensions are advertised, but software emulated. So try to
1328 * detect the Apple OpenGL implementation to apply some extension fixups afterwards.
1330 * Detecting this isn't really easy. The vendor string doesn't mention Apple. Compile-time checks
1331 * aren't sufficient either because a Linux binary may display on a macos X server via remote X11.
1332 * So try to detect the GL implementation by looking at certain Apple extensions. Some extensions
1333 * like client storage might be supported on other implementations too, but GL_APPLE_flush_render
1334 * is specific to the Mac OS X window management, and GL_APPLE_ycbcr_422 is QuickTime specific. So
1335 * the chance that other implementations support them is rather small since Win32 QuickTime uses
1336 * DirectDraw, not OpenGL. */
1337 if (gl_info->supported[APPLE_FENCE]
1338 && gl_info->supported[APPLE_CLIENT_STORAGE]
1339 && gl_info->supported[APPLE_FLUSH_RENDER]
1340 && gl_info->supported[APPLE_YCBCR_422])
1341 return GL_VENDOR_APPLE;
1343 if (strstr(gl_vendor_string, "NVIDIA"))
1344 return GL_VENDOR_NVIDIA;
1346 if (strstr(gl_vendor_string, "ATI"))
1347 return GL_VENDOR_FGLRX;
1349 if (strstr(gl_vendor_string, "Intel(R)")
1350 /* Intel switched from Intel(R) to Intel® recently, so just match Intel. */
1351 || strstr(gl_renderer, "Intel")
1352 || strstr(gl_vendor_string, "Intel Inc."))
1353 return GL_VENDOR_INTEL;
1355 if (strstr(gl_vendor_string, "Mesa")
1356 || strstr(gl_vendor_string, "Advanced Micro Devices, Inc.")
1357 || strstr(gl_vendor_string, "DRI R300 Project")
1358 || strstr(gl_vendor_string, "X.Org R300 Project")
1359 || strstr(gl_vendor_string, "Tungsten Graphics, Inc")
1360 || strstr(gl_vendor_string, "VMware, Inc.")
1361 || strstr(gl_renderer, "Mesa")
1362 || strstr(gl_renderer, "Gallium"))
1363 return GL_VENDOR_MESA;
1365 FIXME_(d3d_caps)("Received unrecognized GL_VENDOR %s. Returning GL_VENDOR_UNKNOWN.\n",
1366 debugstr_a(gl_vendor_string));
1368 return GL_VENDOR_UNKNOWN;
1371 static enum wined3d_pci_vendor wined3d_guess_card_vendor(const char *gl_vendor_string, const char *gl_renderer)
1373 if (strstr(gl_vendor_string, "NVIDIA"))
1374 return HW_VENDOR_NVIDIA;
1376 if (strstr(gl_vendor_string, "ATI")
1377 || strstr(gl_vendor_string, "Advanced Micro Devices, Inc.")
1378 || strstr(gl_vendor_string, "X.Org R300 Project")
1379 || strstr(gl_renderer, "AMD")
1380 || strstr(gl_renderer, "R100")
1381 || strstr(gl_renderer, "R200")
1382 || strstr(gl_renderer, "R300")
1383 || strstr(gl_renderer, "R600")
1384 || strstr(gl_renderer, "R700"))
1385 return HW_VENDOR_ATI;
1387 if (strstr(gl_vendor_string, "Intel(R)")
1388 /* Intel switched from Intel(R) to Intel® recently, so just match Intel. */
1389 || strstr(gl_renderer, "Intel")
1390 || strstr(gl_vendor_string, "Intel Inc."))
1391 return HW_VENDOR_INTEL;
1393 if (strstr(gl_vendor_string, "Mesa")
1394 || strstr(gl_vendor_string, "Tungsten Graphics, Inc")
1395 || strstr(gl_vendor_string, "VMware, Inc."))
1396 return HW_VENDOR_SOFTWARE;
1398 FIXME_(d3d_caps)("Received unrecognized GL_VENDOR %s. Returning HW_VENDOR_NVIDIA.\n", debugstr_a(gl_vendor_string));
1400 return HW_VENDOR_NVIDIA;
1405 static enum wined3d_pci_device select_card_nvidia_binary(const struct wined3d_gl_info *gl_info,
1406 const char *gl_renderer)
1408 if (WINE_D3D10_CAPABLE(gl_info))
1410 /* Geforce 400 - highend */
1411 if (strstr(gl_renderer, "GTX 480"))
1413 return CARD_NVIDIA_GEFORCE_GTX480;
1416 /* Geforce 400 - midend high */
1417 if (strstr(gl_renderer, "GTX 470"))
1419 return CARD_NVIDIA_GEFORCE_GTX470;
1422 /* Geforce 400 - midend */
1423 if (strstr(gl_renderer, "GTX 465"))
1425 return CARD_NVIDIA_GEFORCE_GTX465;
1428 /* Geforce 400 - midend */
1429 if (strstr(gl_renderer, "GTX 460"))
1431 return CARD_NVIDIA_GEFORCE_GTX460;
1434 /* Geforce 300 highend mobile */
1435 if (strstr(gl_renderer, "GTS 350M")
1436 || strstr(gl_renderer, "GTS 360M"))
1438 return CARD_NVIDIA_GEFORCE_GTS350M;
1441 /* Geforce 300 midend mobile (Geforce GT 325M/330M use the same core) */
1442 if (strstr(gl_renderer, "GT 325M")
1443 || strstr(gl_renderer, "GT 330M"))
1445 return CARD_NVIDIA_GEFORCE_GT325M;
1448 /* Geforce 200 - highend */
1449 if (strstr(gl_renderer, "GTX 280")
1450 || strstr(gl_renderer, "GTX 285")
1451 || strstr(gl_renderer, "GTX 295"))
1453 return CARD_NVIDIA_GEFORCE_GTX280;
1456 /* Geforce 200 - midend high */
1457 if (strstr(gl_renderer, "GTX 275"))
1459 return CARD_NVIDIA_GEFORCE_GTX275;
1462 /* Geforce 200 - midend */
1463 if (strstr(gl_renderer, "GTX 260"))
1465 return CARD_NVIDIA_GEFORCE_GTX260;
1467 /* Geforce 200 - midend */
1468 if (strstr(gl_renderer, "GT 240"))
1470 return CARD_NVIDIA_GEFORCE_GT240;
1473 /* Geforce 200 lowend */
1474 if (strstr(gl_renderer, "GT 220"))
1476 return CARD_NVIDIA_GEFORCE_GT220;
1478 /* Geforce 200 lowend (Geforce 305/310 use the same core) */
1479 if (strstr(gl_renderer, "Geforce 210")
1480 || strstr(gl_renderer, "G 210")
1481 || strstr(gl_renderer, "Geforce 305")
1482 || strstr(gl_renderer, "Geforce 310"))
1484 return CARD_NVIDIA_GEFORCE_210;
1487 /* Geforce9 - highend / Geforce 200 - midend (GTS 150/250 are based on the same core) */
1488 if (strstr(gl_renderer, "9800")
1489 || strstr(gl_renderer, "GTS 150")
1490 || strstr(gl_renderer, "GTS 250"))
1492 return CARD_NVIDIA_GEFORCE_9800GT;
1495 /* Geforce9 - midend (GT 140 uses the same core as the 9600GT) */
1496 if (strstr(gl_renderer, "9600")
1497 || strstr(gl_renderer, "GT 140"))
1499 return CARD_NVIDIA_GEFORCE_9600GT;
1502 /* Geforce9 - midend low / Geforce 200 - low */
1503 if (strstr(gl_renderer, "9500")
1504 || strstr(gl_renderer, "GT 120")
1505 || strstr(gl_renderer, "GT 130"))
1507 return CARD_NVIDIA_GEFORCE_9500GT;
1510 /* Geforce9 - lowend */
1511 if (strstr(gl_renderer, "9400"))
1513 return CARD_NVIDIA_GEFORCE_9400GT;
1516 /* Geforce9 - lowend low */
1517 if (strstr(gl_renderer, "9100")
1518 || strstr(gl_renderer, "9200")
1519 || strstr(gl_renderer, "9300")
1520 || strstr(gl_renderer, "G 100"))
1522 return CARD_NVIDIA_GEFORCE_9200;
1525 /* Geforce8 - highend high*/
1526 if (strstr(gl_renderer, "8800 GTX"))
1528 return CARD_NVIDIA_GEFORCE_8800GTX;
1531 /* Geforce8 - highend */
1532 if (strstr(gl_renderer, "8800"))
1534 return CARD_NVIDIA_GEFORCE_8800GTS;
1537 /* Geforce8 - midend mobile */
1538 if (strstr(gl_renderer, "8600 M"))
1540 return CARD_NVIDIA_GEFORCE_8600MGT;
1543 /* Geforce8 - midend */
1544 if (strstr(gl_renderer, "8600")
1545 || strstr(gl_renderer, "8700"))
1547 return CARD_NVIDIA_GEFORCE_8600GT;
1550 /* Geforce8 - mid-lowend */
1551 if (strstr(gl_renderer, "8400")
1552 || strstr(gl_renderer, "8500"))
1554 return CARD_NVIDIA_GEFORCE_8400GS;
1557 /* Geforce8 - lowend */
1558 if (strstr(gl_renderer, "8100")
1559 || strstr(gl_renderer, "8200")
1560 || strstr(gl_renderer, "8300"))
1562 return CARD_NVIDIA_GEFORCE_8300GS;
1565 /* Geforce8-compatible fall back if the GPU is not in the list yet */
1566 return CARD_NVIDIA_GEFORCE_8300GS;
1569 /* Both the GeforceFX, 6xxx and 7xxx series support D3D9. The last two types have more
1570 * shader capabilities, so we use the shader capabilities to distinguish between FX and 6xxx/7xxx.
1572 if (WINE_D3D9_CAPABLE(gl_info) && gl_info->supported[NV_VERTEX_PROGRAM3])
1574 /* Geforce7 - highend */
1575 if (strstr(gl_renderer, "7800")
1576 || strstr(gl_renderer, "7900")
1577 || strstr(gl_renderer, "7950")
1578 || strstr(gl_renderer, "Quadro FX 4")
1579 || strstr(gl_renderer, "Quadro FX 5"))
1581 return CARD_NVIDIA_GEFORCE_7800GT;
1584 /* Geforce7 midend */
1585 if (strstr(gl_renderer, "7600")
1586 || strstr(gl_renderer, "7700"))
1588 return CARD_NVIDIA_GEFORCE_7600;
1591 /* Geforce7 lower medium */
1592 if (strstr(gl_renderer, "7400"))
1594 return CARD_NVIDIA_GEFORCE_7400;
1597 /* Geforce7 lowend */
1598 if (strstr(gl_renderer, "7300"))
1600 return CARD_NVIDIA_GEFORCE_7300;
1603 /* Geforce6 highend */
1604 if (strstr(gl_renderer, "6800"))
1606 return CARD_NVIDIA_GEFORCE_6800;
1609 /* Geforce6 - midend */
1610 if (strstr(gl_renderer, "6600")
1611 || strstr(gl_renderer, "6610")
1612 || strstr(gl_renderer, "6700"))
1614 return CARD_NVIDIA_GEFORCE_6600GT;
1617 /* Geforce6/7 lowend */
1618 return CARD_NVIDIA_GEFORCE_6200; /* Geforce 6100/6150/6200/7300/7400/7500 */
1621 if (WINE_D3D9_CAPABLE(gl_info))
1623 /* GeforceFX - highend */
1624 if (strstr(gl_renderer, "5800")
1625 || strstr(gl_renderer, "5900")
1626 || strstr(gl_renderer, "5950")
1627 || strstr(gl_renderer, "Quadro FX"))
1629 return CARD_NVIDIA_GEFORCEFX_5800;
1632 /* GeforceFX - midend */
1633 if (strstr(gl_renderer, "5600")
1634 || strstr(gl_renderer, "5650")
1635 || strstr(gl_renderer, "5700")
1636 || strstr(gl_renderer, "5750"))
1638 return CARD_NVIDIA_GEFORCEFX_5600;
1641 /* GeforceFX - lowend */
1642 return CARD_NVIDIA_GEFORCEFX_5200; /* GeforceFX 5100/5200/5250/5300/5500 */
1645 if (WINE_D3D8_CAPABLE(gl_info))
1647 if (strstr(gl_renderer, "GeForce4 Ti") || strstr(gl_renderer, "Quadro4"))
1649 return CARD_NVIDIA_GEFORCE4_TI4200; /* Geforce4 Ti4200/Ti4400/Ti4600/Ti4800, Quadro4 */
1652 return CARD_NVIDIA_GEFORCE3; /* Geforce3 standard/Ti200/Ti500, Quadro DCC */
1655 if (WINE_D3D7_CAPABLE(gl_info))
1657 if (strstr(gl_renderer, "GeForce4 MX"))
1659 return CARD_NVIDIA_GEFORCE4_MX; /* MX420/MX440/MX460/MX4000 */
1662 if (strstr(gl_renderer, "GeForce2 MX") || strstr(gl_renderer, "Quadro2 MXR"))
1664 return CARD_NVIDIA_GEFORCE2_MX; /* Geforce2 standard/MX100/MX200/MX400, Quadro2 MXR */
1667 if (strstr(gl_renderer, "GeForce2") || strstr(gl_renderer, "Quadro2"))
1669 return CARD_NVIDIA_GEFORCE2; /* Geforce2 GTS/Pro/Ti/Ultra, Quadro2 */
1672 return CARD_NVIDIA_GEFORCE; /* Geforce 256/DDR, Quadro */
1675 if (strstr(gl_renderer, "TNT2"))
1677 return CARD_NVIDIA_RIVA_TNT2; /* Riva TNT2 standard/M64/Pro/Ultra */
1680 return CARD_NVIDIA_RIVA_TNT; /* Riva TNT, Vanta */
1683 static enum wined3d_pci_device select_card_ati_binary(const struct wined3d_gl_info *gl_info,
1684 const char *gl_renderer)
1686 /* See http://developer.amd.com/drivers/pc_vendor_id/Pages/default.aspx
1688 * Beware: renderer string do not match exact card model,
1689 * eg HD 4800 is returned for multiple cards, even for RV790 based ones. */
1690 if (WINE_D3D10_CAPABLE(gl_info))
1692 /* Radeon EG CYPRESS XT / PRO HD5800 - highend */
1693 if (strstr(gl_renderer, "HD 5800") /* Radeon EG CYPRESS HD58xx generic renderer string */
1694 || strstr(gl_renderer, "HD 5850") /* Radeon EG CYPRESS XT */
1695 || strstr(gl_renderer, "HD 5870")) /* Radeon EG CYPRESS PRO */
1697 return CARD_ATI_RADEON_HD5800;
1700 /* Radeon EG JUNIPER XT / LE HD5700 - midend */
1701 if (strstr(gl_renderer, "HD 5700") /* Radeon EG JUNIPER HD57xx generic renderer string */
1702 || strstr(gl_renderer, "HD 5750") /* Radeon EG JUNIPER LE */
1703 || strstr(gl_renderer, "HD 5770")) /* Radeon EG JUNIPER XT */
1705 return CARD_ATI_RADEON_HD5700;
1708 /* Radeon R7xx HD4800 - highend */
1709 if (strstr(gl_renderer, "HD 4800") /* Radeon RV7xx HD48xx generic renderer string */
1710 || strstr(gl_renderer, "HD 4830") /* Radeon RV770 */
1711 || strstr(gl_renderer, "HD 4850") /* Radeon RV770 */
1712 || strstr(gl_renderer, "HD 4870") /* Radeon RV770 */
1713 || strstr(gl_renderer, "HD 4890")) /* Radeon RV790 */
1715 return CARD_ATI_RADEON_HD4800;
1718 /* Radeon R740 HD4700 - midend */
1719 if (strstr(gl_renderer, "HD 4700") /* Radeon RV770 */
1720 || strstr(gl_renderer, "HD 4770")) /* Radeon RV740 */
1722 return CARD_ATI_RADEON_HD4700;
1725 /* Radeon R730 HD4600 - midend */
1726 if (strstr(gl_renderer, "HD 4600") /* Radeon RV730 */
1727 || strstr(gl_renderer, "HD 4650") /* Radeon RV730 */
1728 || strstr(gl_renderer, "HD 4670")) /* Radeon RV730 */
1730 return CARD_ATI_RADEON_HD4600;
1733 /* Radeon R710 HD4500/HD4350 - lowend */
1734 if (strstr(gl_renderer, "HD 4350") /* Radeon RV710 */
1735 || strstr(gl_renderer, "HD 4550")) /* Radeon RV710 */
1737 return CARD_ATI_RADEON_HD4350;
1740 /* Radeon R6xx HD2900/HD3800 - highend */
1741 if (strstr(gl_renderer, "HD 2900")
1742 || strstr(gl_renderer, "HD 3870")
1743 || strstr(gl_renderer, "HD 3850"))
1745 return CARD_ATI_RADEON_HD2900;
1748 /* Radeon R6xx HD2600/HD3600 - midend; HD3830 is China-only midend */
1749 if (strstr(gl_renderer, "HD 2600")
1750 || strstr(gl_renderer, "HD 3830")
1751 || strstr(gl_renderer, "HD 3690")
1752 || strstr(gl_renderer, "HD 3650"))
1754 return CARD_ATI_RADEON_HD2600;
1757 /* Radeon R6xx HD2350/HD2400/HD3400 - lowend
1758 * Note HD2300=DX9, HD2350=DX10 */
1759 if (strstr(gl_renderer, "HD 2350")
1760 || strstr(gl_renderer, "HD 2400")
1761 || strstr(gl_renderer, "HD 3470")
1762 || strstr(gl_renderer, "HD 3450")
1763 || strstr(gl_renderer, "HD 3430")
1764 || strstr(gl_renderer, "HD 3400"))
1766 return CARD_ATI_RADEON_HD2350;
1769 /* Radeon R6xx/R7xx integrated */
1770 if (strstr(gl_renderer, "HD 3100")
1771 || strstr(gl_renderer, "HD 3200")
1772 || strstr(gl_renderer, "HD 3300"))
1774 return CARD_ATI_RADEON_HD3200;
1777 /* Default for when no GPU has been found */
1778 return CARD_ATI_RADEON_HD3200;
1781 if (WINE_D3D8_CAPABLE(gl_info))
1784 if (strstr(gl_renderer, "X1600")
1785 || strstr(gl_renderer, "X1650")
1786 || strstr(gl_renderer, "X1800")
1787 || strstr(gl_renderer, "X1900")
1788 || strstr(gl_renderer, "X1950"))
1790 return CARD_ATI_RADEON_X1600;
1793 /* Radeon R4xx + X1300/X1400/X1450/X1550/X2300/X2500/HD2300 (lowend R5xx)
1794 * Note X2300/X2500/HD2300 are R5xx GPUs with a 2xxx naming but they are still DX9-only */
1795 if (strstr(gl_renderer, "X700")
1796 || strstr(gl_renderer, "X800")
1797 || strstr(gl_renderer, "X850")
1798 || strstr(gl_renderer, "X1300")
1799 || strstr(gl_renderer, "X1400")
1800 || strstr(gl_renderer, "X1450")
1801 || strstr(gl_renderer, "X1550")
1802 || strstr(gl_renderer, "X2300")
1803 || strstr(gl_renderer, "X2500")
1804 || strstr(gl_renderer, "HD 2300")
1807 return CARD_ATI_RADEON_X700;
1810 /* Radeon Xpress Series - onboard, DX9b, Shader 2.0, 300-400MHz */
1811 if (strstr(gl_renderer, "Radeon Xpress"))
1813 return CARD_ATI_RADEON_XPRESS_200M;
1817 return CARD_ATI_RADEON_9500; /* Radeon 9500/9550/9600/9700/9800/X300/X550/X600 */
1820 if (WINE_D3D8_CAPABLE(gl_info))
1822 return CARD_ATI_RADEON_8500; /* Radeon 8500/9000/9100/9200/9300 */
1825 if (WINE_D3D7_CAPABLE(gl_info))
1827 return CARD_ATI_RADEON_7200; /* Radeon 7000/7100/7200/7500 */
1830 return CARD_ATI_RAGE_128PRO;
1833 static enum wined3d_pci_device select_card_intel(const struct wined3d_gl_info *gl_info,
1834 const char *gl_renderer)
1836 if (strstr(gl_renderer, "X3100") || strstr(gl_renderer, "965GM"))
1838 /* MacOS calls the card GMA X3100, otherwise known as GM965/GL960 */
1839 return CARD_INTEL_X3100;
1842 if (strstr(gl_renderer, "GMA 950") || strstr(gl_renderer, "945GM"))
1844 /* MacOS calls the card GMA 950, but everywhere else the PCI ID is named 945GM */
1845 return CARD_INTEL_I945GM;
1848 if (strstr(gl_renderer, "915GM")) return CARD_INTEL_I915GM;
1849 if (strstr(gl_renderer, "915G")) return CARD_INTEL_I915G;
1850 if (strstr(gl_renderer, "865G")) return CARD_INTEL_I865G;
1851 if (strstr(gl_renderer, "855G")) return CARD_INTEL_I855G;
1852 if (strstr(gl_renderer, "830G")) return CARD_INTEL_I830G;
1853 return CARD_INTEL_I915G;
1857 static enum wined3d_pci_device select_card_ati_mesa(const struct wined3d_gl_info *gl_info,
1858 const char *gl_renderer)
1860 /* See http://developer.amd.com/drivers/pc_vendor_id/Pages/default.aspx
1862 * Beware: renderer string do not match exact card model,
1863 * eg HD 4800 is returned for multiple cards, even for RV790 based ones. */
1864 if (strstr(gl_renderer, "Gallium"))
1866 if (strstr(gl_renderer, "HEMLOCK"))
1867 return CARD_ATI_RADEON_HD5900;
1868 if (strstr(gl_renderer, "CYPRESS"))
1869 return CARD_ATI_RADEON_HD5800;
1870 if (strstr(gl_renderer, "JUNIPER"))
1871 return CARD_ATI_RADEON_HD5700;
1872 if (strstr(gl_renderer, "REDWOOD"))
1873 return CARD_ATI_RADEON_HD5600;
1874 if (strstr(gl_renderer, "CEDAR"))
1875 return CARD_ATI_RADEON_HD5400;
1877 /* Radeon R7xx HD4800 - highend */
1878 if (strstr(gl_renderer, "R700") /* Radeon R7xx HD48xx generic renderer string */
1879 || strstr(gl_renderer, "RV770") /* Radeon RV770 */
1880 || strstr(gl_renderer, "RV790")) /* Radeon RV790 */
1882 return CARD_ATI_RADEON_HD4800;
1885 /* Radeon R740 HD4700 - midend */
1886 if (strstr(gl_renderer, "RV740")) /* Radeon RV740 */
1888 return CARD_ATI_RADEON_HD4700;
1891 /* Radeon R730 HD4600 - midend */
1892 if (strstr(gl_renderer, "RV730")) /* Radeon RV730 */
1894 return CARD_ATI_RADEON_HD4600;
1897 /* Radeon R710 HD4500/HD4350 - lowend */
1898 if (strstr(gl_renderer, "RV710")) /* Radeon RV710 */
1900 return CARD_ATI_RADEON_HD4350;
1903 /* Radeon R6xx HD2900/HD3800 - highend */
1904 if (strstr(gl_renderer, "R600")
1905 || strstr(gl_renderer, "RV670")
1906 || strstr(gl_renderer, "R680"))
1908 return CARD_ATI_RADEON_HD2900;
1911 /* Radeon R6xx HD2600/HD3600 - midend; HD3830 is China-only midend */
1912 if (strstr(gl_renderer, "RV630")
1913 || strstr(gl_renderer, "RV635"))
1915 return CARD_ATI_RADEON_HD2600;
1918 /* Radeon R6xx HD2350/HD2400/HD3400 - lowend */
1919 if (strstr(gl_renderer, "RV610")
1920 || strstr(gl_renderer, "RV620"))
1922 return CARD_ATI_RADEON_HD2350;
1925 /* Radeon R6xx/R7xx integrated */
1926 if (strstr(gl_renderer, "RS780")
1927 || strstr(gl_renderer, "RS880"))
1929 return CARD_ATI_RADEON_HD3200;
1933 if (strstr(gl_renderer, "RV530")
1934 || strstr(gl_renderer, "RV535")
1935 || strstr(gl_renderer, "RV560")
1936 || strstr(gl_renderer, "R520")
1937 || strstr(gl_renderer, "RV570")
1938 || strstr(gl_renderer, "R580"))
1940 return CARD_ATI_RADEON_X1600;
1943 /* Radeon R4xx + X1300/X1400/X1450/X1550/X2300 (lowend R5xx) */
1944 if (strstr(gl_renderer, "R410")
1945 || strstr(gl_renderer, "R420")
1946 || strstr(gl_renderer, "R423")
1947 || strstr(gl_renderer, "R430")
1948 || strstr(gl_renderer, "R480")
1949 || strstr(gl_renderer, "R481")
1950 || strstr(gl_renderer, "RV410")
1951 || strstr(gl_renderer, "RV515")
1952 || strstr(gl_renderer, "RV516"))
1954 return CARD_ATI_RADEON_X700;
1957 /* Radeon Xpress Series - onboard, DX9b, Shader 2.0, 300-400MHz */
1958 if (strstr(gl_renderer, "RS400")
1959 || strstr(gl_renderer, "RS480")
1960 || strstr(gl_renderer, "RS482")
1961 || strstr(gl_renderer, "RS485")
1962 || strstr(gl_renderer, "RS600")
1963 || strstr(gl_renderer, "RS690")
1964 || strstr(gl_renderer, "RS740"))
1966 return CARD_ATI_RADEON_XPRESS_200M;
1970 if (strstr(gl_renderer, "R300")
1971 || strstr(gl_renderer, "RV350")
1972 || strstr(gl_renderer, "RV351")
1973 || strstr(gl_renderer, "RV360")
1974 || strstr(gl_renderer, "RV370")
1975 || strstr(gl_renderer, "R350")
1976 || strstr(gl_renderer, "R360"))
1978 return CARD_ATI_RADEON_9500; /* Radeon 9500/9550/9600/9700/9800/X300/X550/X600 */
1982 if (WINE_D3D9_CAPABLE(gl_info))
1984 /* Radeon R7xx HD4800 - highend */
1985 if (strstr(gl_renderer, "(R700") /* Radeon R7xx HD48xx generic renderer string */
1986 || strstr(gl_renderer, "(RV770") /* Radeon RV770 */
1987 || strstr(gl_renderer, "(RV790")) /* Radeon RV790 */
1989 return CARD_ATI_RADEON_HD4800;
1992 /* Radeon R740 HD4700 - midend */
1993 if (strstr(gl_renderer, "(RV740")) /* Radeon RV740 */
1995 return CARD_ATI_RADEON_HD4700;
1998 /* Radeon R730 HD4600 - midend */
1999 if (strstr(gl_renderer, "(RV730")) /* Radeon RV730 */
2001 return CARD_ATI_RADEON_HD4600;
2004 /* Radeon R710 HD4500/HD4350 - lowend */
2005 if (strstr(gl_renderer, "(RV710")) /* Radeon RV710 */
2007 return CARD_ATI_RADEON_HD4350;
2010 /* Radeon R6xx HD2900/HD3800 - highend */
2011 if (strstr(gl_renderer, "(R600")
2012 || strstr(gl_renderer, "(RV670")
2013 || strstr(gl_renderer, "(R680"))
2015 return CARD_ATI_RADEON_HD2900;
2018 /* Radeon R6xx HD2600/HD3600 - midend; HD3830 is China-only midend */
2019 if (strstr(gl_renderer, "(RV630")
2020 || strstr(gl_renderer, "(RV635"))
2022 return CARD_ATI_RADEON_HD2600;
2025 /* Radeon R6xx HD2300/HD2400/HD3400 - lowend */
2026 if (strstr(gl_renderer, "(RV610")
2027 || strstr(gl_renderer, "(RV620"))
2029 return CARD_ATI_RADEON_HD2350;
2032 /* Radeon R6xx/R7xx integrated */
2033 if (strstr(gl_renderer, "(RS780")
2034 || strstr(gl_renderer, "(RS880"))
2036 return CARD_ATI_RADEON_HD3200;
2040 if (WINE_D3D8_CAPABLE(gl_info))
2042 return CARD_ATI_RADEON_8500; /* Radeon 8500/9000/9100/9200/9300 */
2045 if (WINE_D3D7_CAPABLE(gl_info))
2047 return CARD_ATI_RADEON_7200; /* Radeon 7000/7100/7200/7500 */
2050 return CARD_ATI_RAGE_128PRO;
2053 static enum wined3d_pci_device select_card_nvidia_mesa(const struct wined3d_gl_info *gl_info,
2054 const char *gl_renderer)
2056 FIXME_(d3d_caps)("Card selection not handled for Mesa Nouveau driver\n");
2057 if (WINE_D3D9_CAPABLE(gl_info)) return CARD_NVIDIA_GEFORCEFX_5600;
2058 if (WINE_D3D8_CAPABLE(gl_info)) return CARD_NVIDIA_GEFORCE3;
2059 if (WINE_D3D7_CAPABLE(gl_info)) return CARD_NVIDIA_GEFORCE;
2060 if (WINE_D3D6_CAPABLE(gl_info)) return CARD_NVIDIA_RIVA_TNT;
2061 return CARD_NVIDIA_RIVA_128;
2065 struct vendor_card_selection
2067 enum wined3d_gl_vendor gl_vendor;
2068 enum wined3d_pci_vendor card_vendor;
2069 const char *description; /* Description of the card selector i.e. Apple OS/X Intel */
2070 enum wined3d_pci_device (*select_card)(const struct wined3d_gl_info *gl_info, const char *gl_renderer);
2073 static const struct vendor_card_selection vendor_card_select_table[] =
2075 {GL_VENDOR_NVIDIA, HW_VENDOR_NVIDIA, "Nvidia binary driver", select_card_nvidia_binary},
2076 {GL_VENDOR_APPLE, HW_VENDOR_NVIDIA, "Apple OSX NVidia binary driver", select_card_nvidia_binary},
2077 {GL_VENDOR_APPLE, HW_VENDOR_ATI, "Apple OSX AMD/ATI binary driver", select_card_ati_binary},
2078 {GL_VENDOR_APPLE, HW_VENDOR_INTEL, "Apple OSX Intel binary driver", select_card_intel},
2079 {GL_VENDOR_FGLRX, HW_VENDOR_ATI, "AMD/ATI binary driver", select_card_ati_binary},
2080 {GL_VENDOR_MESA, HW_VENDOR_ATI, "Mesa AMD/ATI driver", select_card_ati_mesa},
2081 {GL_VENDOR_MESA, HW_VENDOR_NVIDIA, "Mesa Nouveau driver", select_card_nvidia_mesa},
2082 {GL_VENDOR_MESA, HW_VENDOR_INTEL, "Mesa Intel driver", select_card_intel},
2083 {GL_VENDOR_INTEL, HW_VENDOR_INTEL, "Mesa Intel driver", select_card_intel}
2087 static enum wined3d_pci_device wined3d_guess_card(const struct wined3d_gl_info *gl_info, const char *gl_renderer,
2088 enum wined3d_gl_vendor *gl_vendor, enum wined3d_pci_vendor *card_vendor)
2090 /* Above is a list of Nvidia and ATI GPUs. Both vendors have dozens of
2091 * different GPUs with roughly the same features. In most cases GPUs from a
2092 * certain family differ in clockspeeds, the amount of video memory and the
2093 * number of shader pipelines.
2095 * A Direct3D device object contains the PCI id (vendor + device) of the
2096 * videocard which is used for rendering. Various applications use this
2097 * information to get a rough estimation of the features of the card and
2098 * some might use it for enabling 3d effects only on certain types of
2099 * videocards. In some cases games might even use it to work around bugs
2100 * which happen on certain videocards/driver combinations. The problem is
2101 * that OpenGL only exposes a rendering string containing the name of the
2102 * videocard and not the PCI id.
2104 * Various games depend on the PCI id, so somehow we need to provide one.
2105 * A simple option is to parse the renderer string and translate this to
2106 * the right PCI id. This is a lot of work because there are more than 200
2107 * GPUs just for Nvidia. Various cards share the same renderer string, so
2108 * the amount of code might be 'small' but there are quite a number of
2109 * exceptions which would make this a pain to maintain. Another way would
2110 * be to query the PCI id from the operating system (assuming this is the
2111 * videocard which is used for rendering which is not always the case).
2112 * This would work but it is not very portable. Second it would not work
2113 * well in, let's say, a remote X situation in which the amount of 3d
2114 * features which can be used is limited.
2116 * As said most games only use the PCI id to get an indication of the
2117 * capabilities of the card. It doesn't really matter if the given id is
2118 * the correct one if we return the id of a card with similar 3d features.
2120 * The code below checks the OpenGL capabilities of a videocard and matches
2121 * that to a certain level of Direct3D functionality. Once a card passes
2122 * the Direct3D9 check, we know that the card (in case of Nvidia) is at
2123 * least a GeforceFX. To give a better estimate we do a basic check on the
2124 * renderer string but if that won't pass we return a default card. This
2125 * way is better than maintaining a full card database as even without a
2126 * full database we can return a card with similar features. Second the
2127 * size of the database can be made quite small because when you know what
2128 * type of 3d functionality a card has, you know to which GPU family the
2129 * GPU must belong. Because of this you only have to check a small part of
2130 * the renderer string to distinguishes between different models from that
2133 * The code also selects a default amount of video memory which we will
2134 * use for an estimation of the amount of free texture memory. In case of
2135 * real D3D the amount of texture memory includes video memory and system
2136 * memory (to be specific AGP memory or in case of PCIE TurboCache /
2137 * HyperMemory). We don't know how much system memory can be addressed by
2138 * the system but we can make a reasonable estimation about the amount of
2139 * video memory. If the value is slightly wrong it doesn't matter as we
2140 * didn't include AGP-like memory which makes the amount of addressable
2141 * memory higher and second OpenGL isn't that critical it moves to system
2142 * memory behind our backs if really needed. Note that the amount of video
2143 * memory can be overruled using a registry setting. */
2147 for (i = 0; i < (sizeof(vendor_card_select_table) / sizeof(*vendor_card_select_table)); ++i)
2149 if ((vendor_card_select_table[i].gl_vendor != *gl_vendor)
2150 || (vendor_card_select_table[i].card_vendor != *card_vendor))
2152 TRACE_(d3d_caps)("Applying card_selector \"%s\".\n", vendor_card_select_table[i].description);
2153 return vendor_card_select_table[i].select_card(gl_info, gl_renderer);
2156 FIXME_(d3d_caps)("No card selector available for GL vendor %d and card vendor %04x.\n",
2157 *gl_vendor, *card_vendor);
2159 /* Default to generic Nvidia hardware based on the supported OpenGL extensions. The choice
2160 * for Nvidia was because the hardware and drivers they make are of good quality. This makes
2161 * them a good generic choice. */
2162 *card_vendor = HW_VENDOR_NVIDIA;
2163 if (WINE_D3D9_CAPABLE(gl_info)) return CARD_NVIDIA_GEFORCEFX_5600;
2164 if (WINE_D3D8_CAPABLE(gl_info)) return CARD_NVIDIA_GEFORCE3;
2165 if (WINE_D3D7_CAPABLE(gl_info)) return CARD_NVIDIA_GEFORCE;
2166 if (WINE_D3D6_CAPABLE(gl_info)) return CARD_NVIDIA_RIVA_TNT;
2167 return CARD_NVIDIA_RIVA_128;
2170 static const struct fragment_pipeline *select_fragment_implementation(struct wined3d_adapter *adapter)
2172 const struct wined3d_gl_info *gl_info = &adapter->gl_info;
2173 int vs_selected_mode, ps_selected_mode;
2175 select_shader_mode(gl_info, &ps_selected_mode, &vs_selected_mode);
2176 if ((ps_selected_mode == SHADER_ARB || ps_selected_mode == SHADER_GLSL)
2177 && gl_info->supported[ARB_FRAGMENT_PROGRAM]) return &arbfp_fragment_pipeline;
2178 else if (ps_selected_mode == SHADER_ATI) return &atifs_fragment_pipeline;
2179 else if (gl_info->supported[NV_REGISTER_COMBINERS]
2180 && gl_info->supported[NV_TEXTURE_SHADER2]) return &nvts_fragment_pipeline;
2181 else if (gl_info->supported[NV_REGISTER_COMBINERS]) return &nvrc_fragment_pipeline;
2182 else return &ffp_fragment_pipeline;
2185 static const shader_backend_t *select_shader_backend(struct wined3d_adapter *adapter)
2187 int vs_selected_mode, ps_selected_mode;
2189 select_shader_mode(&adapter->gl_info, &ps_selected_mode, &vs_selected_mode);
2190 if (vs_selected_mode == SHADER_GLSL || ps_selected_mode == SHADER_GLSL) return &glsl_shader_backend;
2191 if (vs_selected_mode == SHADER_ARB || ps_selected_mode == SHADER_ARB) return &arb_program_shader_backend;
2192 return &none_shader_backend;
2195 static const struct blit_shader *select_blit_implementation(struct wined3d_adapter *adapter)
2197 const struct wined3d_gl_info *gl_info = &adapter->gl_info;
2198 int vs_selected_mode, ps_selected_mode;
2200 select_shader_mode(gl_info, &ps_selected_mode, &vs_selected_mode);
2201 if ((ps_selected_mode == SHADER_ARB || ps_selected_mode == SHADER_GLSL)
2202 && gl_info->supported[ARB_FRAGMENT_PROGRAM]) return &arbfp_blit;
2203 else return &ffp_blit;
2206 static void load_gl_funcs(struct wined3d_gl_info *gl_info, DWORD gl_version)
2210 #define USE_GL_FUNC(type, pfn, ext, replace) \
2211 if (gl_info->supported[ext]) gl_info->pfn = (type)pwglGetProcAddress(#pfn); \
2212 else if ((ver = ver_for_ext(ext)) && ver <= gl_version) gl_info->pfn = (type)pwglGetProcAddress(#replace); \
2213 else gl_info->pfn = NULL;
2218 #define USE_GL_FUNC(type, pfn, ext, replace) gl_info->pfn = (type)pwglGetProcAddress(#pfn);
2223 /* Context activation is done by the caller. */
2224 static BOOL IWineD3DImpl_FillGLCaps(struct wined3d_adapter *adapter)
2226 struct wined3d_driver_info *driver_info = &adapter->driver_info;
2227 struct wined3d_gl_info *gl_info = &adapter->gl_info;
2228 const char *GL_Extensions = NULL;
2229 const char *WGL_Extensions = NULL;
2230 const char *gl_vendor_str, *gl_renderer_str, *gl_version_str;
2231 struct fragment_caps fragment_caps;
2232 enum wined3d_gl_vendor gl_vendor;
2233 enum wined3d_pci_vendor card_vendor;
2234 enum wined3d_pci_device device;
2236 GLfloat gl_floatv[2];
2242 TRACE_(d3d_caps)("(%p)\n", gl_info);
2246 gl_renderer_str = (const char *)glGetString(GL_RENDERER);
2247 TRACE_(d3d_caps)("GL_RENDERER: %s.\n", debugstr_a(gl_renderer_str));
2248 if (!gl_renderer_str)
2251 ERR_(d3d_caps)("Received a NULL GL_RENDERER.\n");
2255 gl_vendor_str = (const char *)glGetString(GL_VENDOR);
2256 TRACE_(d3d_caps)("GL_VENDOR: %s.\n", debugstr_a(gl_vendor_str));
2260 ERR_(d3d_caps)("Received a NULL GL_VENDOR.\n");
2264 /* Parse the GL_VERSION field into major and minor information */
2265 gl_version_str = (const char *)glGetString(GL_VERSION);
2266 TRACE_(d3d_caps)("GL_VERSION: %s.\n", debugstr_a(gl_version_str));
2267 if (!gl_version_str)
2270 ERR_(d3d_caps)("Received a NULL GL_VERSION.\n");
2273 gl_version = wined3d_parse_gl_version(gl_version_str);
2276 * Initialize openGL extension related variables
2277 * with Default values
2279 memset(gl_info->supported, 0, sizeof(gl_info->supported));
2280 gl_info->limits.blends = 1;
2281 gl_info->limits.buffers = 1;
2282 gl_info->limits.textures = 1;
2283 gl_info->limits.fragment_samplers = 1;
2284 gl_info->limits.vertex_samplers = 0;
2285 gl_info->limits.combined_samplers = gl_info->limits.fragment_samplers + gl_info->limits.vertex_samplers;
2286 gl_info->limits.sampler_stages = 1;
2287 gl_info->limits.glsl_vs_float_constants = 0;
2288 gl_info->limits.glsl_ps_float_constants = 0;
2289 gl_info->limits.arb_vs_float_constants = 0;
2290 gl_info->limits.arb_vs_native_constants = 0;
2291 gl_info->limits.arb_vs_instructions = 0;
2292 gl_info->limits.arb_vs_temps = 0;
2293 gl_info->limits.arb_ps_float_constants = 0;
2294 gl_info->limits.arb_ps_local_constants = 0;
2295 gl_info->limits.arb_ps_instructions = 0;
2296 gl_info->limits.arb_ps_temps = 0;
2298 /* Retrieve opengl defaults */
2299 glGetIntegerv(GL_MAX_CLIP_PLANES, &gl_max);
2300 gl_info->limits.clipplanes = min(WINED3DMAXUSERCLIPPLANES, gl_max);
2301 TRACE_(d3d_caps)("ClipPlanes support - num Planes=%d\n", gl_max);
2303 glGetIntegerv(GL_MAX_LIGHTS, &gl_max);
2304 gl_info->limits.lights = gl_max;
2305 TRACE_(d3d_caps)("Lights support - max lights=%d\n", gl_max);
2307 glGetIntegerv(GL_MAX_TEXTURE_SIZE, &gl_max);
2308 gl_info->limits.texture_size = gl_max;
2309 TRACE_(d3d_caps)("Maximum texture size support - max texture size=%d\n", gl_max);
2311 glGetFloatv(GL_ALIASED_POINT_SIZE_RANGE, gl_floatv);
2312 gl_info->limits.pointsize_min = gl_floatv[0];
2313 gl_info->limits.pointsize_max = gl_floatv[1];
2314 TRACE_(d3d_caps)("Maximum point size support - max point size=%f\n", gl_floatv[1]);
2316 /* Parse the gl supported features, in theory enabling parts of our code appropriately. */
2317 GL_Extensions = (const char *)glGetString(GL_EXTENSIONS);
2321 ERR_(d3d_caps)("Received a NULL GL_EXTENSIONS.\n");
2327 TRACE_(d3d_caps)("GL_Extensions reported:\n");
2329 gl_info->supported[WINED3D_GL_EXT_NONE] = TRUE;
2331 while (*GL_Extensions)
2335 while (isspace(*GL_Extensions)) ++GL_Extensions;
2336 start = GL_Extensions;
2337 while (!isspace(*GL_Extensions) && *GL_Extensions) ++GL_Extensions;
2339 len = GL_Extensions - start;
2342 TRACE_(d3d_caps)("- %s\n", debugstr_an(start, len));
2344 for (i = 0; i < (sizeof(EXTENSION_MAP) / sizeof(*EXTENSION_MAP)); ++i)
2346 if (len == strlen(EXTENSION_MAP[i].extension_string)
2347 && !memcmp(start, EXTENSION_MAP[i].extension_string, len))
2349 TRACE_(d3d_caps)(" FOUND: %s support.\n", EXTENSION_MAP[i].extension_string);
2350 gl_info->supported[EXTENSION_MAP[i].extension] = TRUE;
2356 /* Now work out what GL support this card really has */
2357 load_gl_funcs( gl_info, gl_version );
2361 /* Now mark all the extensions supported which are included in the opengl core version. Do this *after*
2362 * loading the functions, otherwise the code above will load the extension entry points instead of the
2363 * core functions, which may not work. */
2364 for (i = 0; i < (sizeof(EXTENSION_MAP) / sizeof(*EXTENSION_MAP)); ++i)
2366 if (!gl_info->supported[EXTENSION_MAP[i].extension]
2367 && EXTENSION_MAP[i].version <= gl_version && EXTENSION_MAP[i].version)
2369 TRACE_(d3d_caps)(" GL CORE: %s support.\n", EXTENSION_MAP[i].extension_string);
2370 gl_info->supported[EXTENSION_MAP[i].extension] = TRUE;
2374 if (gl_version >= MAKEDWORD_VERSION(2, 0)) gl_info->supported[WINED3D_GL_VERSION_2_0] = TRUE;
2376 if (gl_info->supported[APPLE_FENCE])
2378 /* GL_NV_fence and GL_APPLE_fence provide the same functionality basically.
2379 * The apple extension interacts with some other apple exts. Disable the NV
2380 * extension if the apple one is support to prevent confusion in other parts
2382 gl_info->supported[NV_FENCE] = FALSE;
2384 if (gl_info->supported[APPLE_FLOAT_PIXELS])
2386 /* GL_APPLE_float_pixels == GL_ARB_texture_float + GL_ARB_half_float_pixel
2388 * The enums are the same:
2389 * GL_RGBA16F_ARB = GL_RGBA_FLOAT16_APPLE = 0x881A
2390 * GL_RGB16F_ARB = GL_RGB_FLOAT16_APPLE = 0x881B
2391 * GL_RGBA32F_ARB = GL_RGBA_FLOAT32_APPLE = 0x8814
2392 * GL_RGB32F_ARB = GL_RGB_FLOAT32_APPLE = 0x8815
2393 * GL_HALF_FLOAT_ARB = GL_HALF_APPLE = 0x140B
2395 if (!gl_info->supported[ARB_TEXTURE_FLOAT])
2397 TRACE_(d3d_caps)(" IMPLIED: GL_ARB_texture_float support(from GL_APPLE_float_pixels.\n");
2398 gl_info->supported[ARB_TEXTURE_FLOAT] = TRUE;
2400 if (!gl_info->supported[ARB_HALF_FLOAT_PIXEL])
2402 TRACE_(d3d_caps)(" IMPLIED: GL_ARB_half_float_pixel support(from GL_APPLE_float_pixels.\n");
2403 gl_info->supported[ARB_HALF_FLOAT_PIXEL] = TRUE;
2406 if (gl_info->supported[ARB_MAP_BUFFER_RANGE])
2408 /* GL_ARB_map_buffer_range and GL_APPLE_flush_buffer_range provide the same
2409 * functionality. Prefer the ARB extension */
2410 gl_info->supported[APPLE_FLUSH_BUFFER_RANGE] = FALSE;
2412 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
2414 TRACE_(d3d_caps)(" IMPLIED: NVIDIA (NV) Texture Gen Reflection support.\n");
2415 gl_info->supported[NV_TEXGEN_REFLECTION] = TRUE;
2417 if (!gl_info->supported[ARB_DEPTH_CLAMP] && gl_info->supported[NV_DEPTH_CLAMP])
2419 TRACE_(d3d_caps)(" IMPLIED: ARB_depth_clamp support (by NV_depth_clamp).\n");
2420 gl_info->supported[ARB_DEPTH_CLAMP] = TRUE;
2422 if (!gl_info->supported[ARB_VERTEX_ARRAY_BGRA] && gl_info->supported[EXT_VERTEX_ARRAY_BGRA])
2424 TRACE_(d3d_caps)(" IMPLIED: ARB_vertex_array_bgra support (by EXT_vertex_array_bgra).\n");
2425 gl_info->supported[ARB_VERTEX_ARRAY_BGRA] = TRUE;
2427 if (!gl_info->supported[ARB_TEXTURE_COMPRESSION_RGTC] && gl_info->supported[EXT_TEXTURE_COMPRESSION_RGTC])
2429 TRACE_(d3d_caps)(" IMPLIED: ARB_texture_compression_rgtc support (by EXT_texture_compression_rgtc).\n");
2430 gl_info->supported[ARB_TEXTURE_COMPRESSION_RGTC] = TRUE;
2432 if (gl_info->supported[NV_TEXTURE_SHADER2])
2434 if (gl_info->supported[NV_REGISTER_COMBINERS])
2436 /* Also disable ATI_FRAGMENT_SHADER if register combiners and texture_shader2
2437 * are supported. The nv extensions provide the same functionality as the
2438 * ATI one, and a bit more(signed pixelformats). */
2439 gl_info->supported[ATI_FRAGMENT_SHADER] = FALSE;
2443 if (gl_info->supported[NV_REGISTER_COMBINERS])
2445 glGetIntegerv(GL_MAX_GENERAL_COMBINERS_NV, &gl_max);
2446 gl_info->limits.general_combiners = gl_max;
2447 TRACE_(d3d_caps)("Max general combiners: %d.\n", gl_max);
2449 if (gl_info->supported[ARB_DRAW_BUFFERS])
2451 glGetIntegerv(GL_MAX_DRAW_BUFFERS_ARB, &gl_max);
2452 gl_info->limits.buffers = gl_max;
2453 TRACE_(d3d_caps)("Max draw buffers: %u.\n", gl_max);
2455 if (gl_info->supported[ARB_MULTITEXTURE])
2457 glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, &gl_max);
2458 gl_info->limits.textures = min(MAX_TEXTURES, gl_max);
2459 TRACE_(d3d_caps)("Max textures: %d.\n", gl_info->limits.textures);
2461 if (gl_info->supported[ARB_FRAGMENT_PROGRAM])
2464 glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS_ARB, &tmp);
2465 gl_info->limits.fragment_samplers = min(MAX_FRAGMENT_SAMPLERS, tmp);
2469 gl_info->limits.fragment_samplers = max(gl_info->limits.fragment_samplers, gl_max);
2471 TRACE_(d3d_caps)("Max fragment samplers: %d.\n", gl_info->limits.fragment_samplers);
2473 if (gl_info->supported[ARB_VERTEX_SHADER])
2476 glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB, &tmp);
2477 gl_info->limits.vertex_samplers = tmp;
2478 glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB, &tmp);
2479 gl_info->limits.combined_samplers = tmp;
2481 /* Loading GLSL sampler uniforms is much simpler if we can assume that the sampler setup
2482 * is known at shader link time. In a vertex shader + pixel shader combination this isn't
2483 * an issue because then the sampler setup only depends on the two shaders. If a pixel
2484 * shader is used with fixed function vertex processing we're fine too because fixed function
2485 * vertex processing doesn't use any samplers. If fixed function fragment processing is
2486 * used we have to make sure that all vertex sampler setups are valid together with all
2487 * possible fixed function fragment processing setups. This is true if vsamplers + MAX_TEXTURES
2488 * <= max_samplers. This is true on all d3d9 cards that support vtf(gf 6 and gf7 cards).
2489 * dx9 radeon cards do not support vertex texture fetch. DX10 cards have 128 samplers, and
2490 * dx9 is limited to 8 fixed function texture stages and 4 vertex samplers. DX10 does not have
2491 * a fixed function pipeline anymore.
2493 * So this is just a check to check that our assumption holds true. If not, write a warning
2494 * and reduce the number of vertex samplers or probably disable vertex texture fetch. */
2495 if (gl_info->limits.vertex_samplers && gl_info->limits.combined_samplers < 12
2496 && MAX_TEXTURES + gl_info->limits.vertex_samplers > gl_info->limits.combined_samplers)
2498 FIXME("OpenGL implementation supports %u vertex samplers and %u total samplers.\n",
2499 gl_info->limits.vertex_samplers, gl_info->limits.combined_samplers);
2500 FIXME("Expected vertex samplers + MAX_TEXTURES(=8) > combined_samplers.\n");
2501 if (gl_info->limits.combined_samplers > MAX_TEXTURES)
2502 gl_info->limits.vertex_samplers = gl_info->limits.combined_samplers - MAX_TEXTURES;
2504 gl_info->limits.vertex_samplers = 0;
2509 gl_info->limits.combined_samplers = gl_info->limits.fragment_samplers;
2511 TRACE_(d3d_caps)("Max vertex samplers: %u.\n", gl_info->limits.vertex_samplers);
2512 TRACE_(d3d_caps)("Max combined samplers: %u.\n", gl_info->limits.combined_samplers);
2514 if (gl_info->supported[ARB_VERTEX_BLEND])
2516 glGetIntegerv(GL_MAX_VERTEX_UNITS_ARB, &gl_max);
2517 gl_info->limits.blends = gl_max;
2518 TRACE_(d3d_caps)("Max blends: %u.\n", gl_info->limits.blends);
2520 if (gl_info->supported[EXT_TEXTURE3D])
2522 glGetIntegerv(GL_MAX_3D_TEXTURE_SIZE_EXT, &gl_max);
2523 gl_info->limits.texture3d_size = gl_max;
2524 TRACE_(d3d_caps)("Max texture3D size: %d.\n", gl_info->limits.texture3d_size);
2526 if (gl_info->supported[EXT_TEXTURE_FILTER_ANISOTROPIC])
2528 glGetIntegerv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &gl_max);
2529 gl_info->limits.anisotropy = gl_max;
2530 TRACE_(d3d_caps)("Max anisotropy: %d.\n", gl_info->limits.anisotropy);
2532 if (gl_info->supported[ARB_FRAGMENT_PROGRAM])
2534 GL_EXTCALL(glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_ENV_PARAMETERS_ARB, &gl_max));
2535 gl_info->limits.arb_ps_float_constants = gl_max;
2536 TRACE_(d3d_caps)("Max ARB_FRAGMENT_PROGRAM float constants: %d.\n", gl_info->limits.arb_ps_float_constants);
2537 GL_EXTCALL(glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB, &gl_max));
2538 gl_info->limits.arb_ps_native_constants = gl_max;
2539 TRACE_(d3d_caps)("Max ARB_FRAGMENT_PROGRAM native float constants: %d.\n",
2540 gl_info->limits.arb_ps_native_constants);
2541 GL_EXTCALL(glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB, &gl_max));
2542 gl_info->limits.arb_ps_temps = gl_max;
2543 TRACE_(d3d_caps)("Max ARB_FRAGMENT_PROGRAM native temporaries: %d.\n", gl_info->limits.arb_ps_temps);
2544 GL_EXTCALL(glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB, &gl_max));
2545 gl_info->limits.arb_ps_instructions = gl_max;
2546 TRACE_(d3d_caps)("Max ARB_FRAGMENT_PROGRAM native instructions: %d.\n", gl_info->limits.arb_ps_instructions);
2547 GL_EXTCALL(glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB, &gl_max));
2548 gl_info->limits.arb_ps_local_constants = gl_max;
2549 TRACE_(d3d_caps)("Max ARB_FRAGMENT_PROGRAM local parameters: %d.\n", gl_info->limits.arb_ps_instructions);
2551 if (gl_info->supported[ARB_VERTEX_PROGRAM])
2553 GL_EXTCALL(glGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_MAX_PROGRAM_ENV_PARAMETERS_ARB, &gl_max));
2554 gl_info->limits.arb_vs_float_constants = gl_max;
2555 TRACE_(d3d_caps)("Max ARB_VERTEX_PROGRAM float constants: %d.\n", gl_info->limits.arb_vs_float_constants);
2556 GL_EXTCALL(glGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB, &gl_max));
2557 gl_info->limits.arb_vs_native_constants = gl_max;
2558 TRACE_(d3d_caps)("Max ARB_VERTEX_PROGRAM native float constants: %d.\n",
2559 gl_info->limits.arb_vs_native_constants);
2560 GL_EXTCALL(glGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB, &gl_max));
2561 gl_info->limits.arb_vs_temps = gl_max;
2562 TRACE_(d3d_caps)("Max ARB_VERTEX_PROGRAM native temporaries: %d.\n", gl_info->limits.arb_vs_temps);
2563 GL_EXTCALL(glGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB, &gl_max));
2564 gl_info->limits.arb_vs_instructions = gl_max;
2565 TRACE_(d3d_caps)("Max ARB_VERTEX_PROGRAM native instructions: %d.\n", gl_info->limits.arb_vs_instructions);
2567 if (test_arb_vs_offset_limit(gl_info)) gl_info->quirks |= WINED3D_QUIRK_ARB_VS_OFFSET_LIMIT;
2569 if (gl_info->supported[ARB_VERTEX_SHADER])
2571 glGetIntegerv(GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB, &gl_max);
2572 gl_info->limits.glsl_vs_float_constants = gl_max / 4;
2573 TRACE_(d3d_caps)("Max ARB_VERTEX_SHADER float constants: %u.\n", gl_info->limits.glsl_vs_float_constants);
2575 if (gl_info->supported[ARB_FRAGMENT_SHADER])
2577 glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB, &gl_max);
2578 gl_info->limits.glsl_ps_float_constants = gl_max / 4;
2579 TRACE_(d3d_caps)("Max ARB_FRAGMENT_SHADER float constants: %u.\n", gl_info->limits.glsl_ps_float_constants);
2580 glGetIntegerv(GL_MAX_VARYING_FLOATS_ARB, &gl_max);
2581 gl_info->limits.glsl_varyings = gl_max;
2582 TRACE_(d3d_caps)("Max GLSL varyings: %u (%u 4 component varyings).\n", gl_max, gl_max / 4);
2584 if (gl_info->supported[ARB_SHADING_LANGUAGE_100])
2586 const char *str = (const char *)glGetString(GL_SHADING_LANGUAGE_VERSION_ARB);
2587 unsigned int major, minor;
2589 TRACE_(d3d_caps)("GLSL version string: %s.\n", debugstr_a(str));
2591 /* The format of the GLSL version string is "major.minor[.release] [vendor info]". */
2592 sscanf(str, "%u.%u", &major, &minor);
2593 gl_info->glsl_version = MAKEDWORD_VERSION(major, minor);
2595 if (gl_info->supported[NV_LIGHT_MAX_EXPONENT])
2597 glGetFloatv(GL_MAX_SHININESS_NV, &gl_info->limits.shininess);
2601 gl_info->limits.shininess = 128.0f;
2603 if (gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO])
2605 /* If we have full NP2 texture support, disable
2606 * GL_ARB_texture_rectangle because we will never use it.
2607 * This saves a few redundant glDisable calls. */
2608 gl_info->supported[ARB_TEXTURE_RECTANGLE] = FALSE;
2610 if (gl_info->supported[ATI_FRAGMENT_SHADER])
2612 /* Disable NV_register_combiners and fragment shader if this is supported.
2613 * generally the NV extensions are preferred over the ATI ones, and this
2614 * extension is disabled if register_combiners and texture_shader2 are both
2615 * supported. So we reach this place only if we have incomplete NV dxlevel 8
2616 * fragment processing support. */
2617 gl_info->supported[NV_REGISTER_COMBINERS] = FALSE;
2618 gl_info->supported[NV_REGISTER_COMBINERS2] = FALSE;
2619 gl_info->supported[NV_TEXTURE_SHADER] = FALSE;
2620 gl_info->supported[NV_TEXTURE_SHADER2] = FALSE;
2622 if (gl_info->supported[NV_HALF_FLOAT])
2624 /* GL_ARB_half_float_vertex is a subset of GL_NV_half_float. */
2625 gl_info->supported[ARB_HALF_FLOAT_VERTEX] = TRUE;
2627 if (gl_info->supported[ARB_POINT_SPRITE])
2629 gl_info->limits.point_sprite_units = gl_info->limits.textures;
2633 gl_info->limits.point_sprite_units = 0;
2635 checkGLcall("extension detection");
2639 adapter->fragment_pipe = select_fragment_implementation(adapter);
2640 adapter->shader_backend = select_shader_backend(adapter);
2641 adapter->blitter = select_blit_implementation(adapter);
2643 adapter->fragment_pipe->get_caps(gl_info, &fragment_caps);
2644 gl_info->limits.texture_stages = fragment_caps.MaxTextureBlendStages;
2645 TRACE_(d3d_caps)("Max texture stages: %u.\n", gl_info->limits.texture_stages);
2647 /* In some cases the number of texture stages can be larger than the number
2648 * of samplers. The GF4 for example can use only 2 samplers (no fragment
2649 * shaders), but 8 texture stages (register combiners). */
2650 gl_info->limits.sampler_stages = max(gl_info->limits.fragment_samplers, gl_info->limits.texture_stages);
2652 if (gl_info->supported[ARB_FRAMEBUFFER_OBJECT])
2654 gl_info->fbo_ops.glIsRenderbuffer = gl_info->glIsRenderbuffer;
2655 gl_info->fbo_ops.glBindRenderbuffer = gl_info->glBindRenderbuffer;
2656 gl_info->fbo_ops.glDeleteRenderbuffers = gl_info->glDeleteRenderbuffers;
2657 gl_info->fbo_ops.glGenRenderbuffers = gl_info->glGenRenderbuffers;
2658 gl_info->fbo_ops.glRenderbufferStorage = gl_info->glRenderbufferStorage;
2659 gl_info->fbo_ops.glRenderbufferStorageMultisample = gl_info->glRenderbufferStorageMultisample;
2660 gl_info->fbo_ops.glGetRenderbufferParameteriv = gl_info->glGetRenderbufferParameteriv;
2661 gl_info->fbo_ops.glIsFramebuffer = gl_info->glIsFramebuffer;
2662 gl_info->fbo_ops.glBindFramebuffer = gl_info->glBindFramebuffer;
2663 gl_info->fbo_ops.glDeleteFramebuffers = gl_info->glDeleteFramebuffers;
2664 gl_info->fbo_ops.glGenFramebuffers = gl_info->glGenFramebuffers;
2665 gl_info->fbo_ops.glCheckFramebufferStatus = gl_info->glCheckFramebufferStatus;
2666 gl_info->fbo_ops.glFramebufferTexture1D = gl_info->glFramebufferTexture1D;
2667 gl_info->fbo_ops.glFramebufferTexture2D = gl_info->glFramebufferTexture2D;
2668 gl_info->fbo_ops.glFramebufferTexture3D = gl_info->glFramebufferTexture3D;
2669 gl_info->fbo_ops.glFramebufferRenderbuffer = gl_info->glFramebufferRenderbuffer;
2670 gl_info->fbo_ops.glGetFramebufferAttachmentParameteriv = gl_info->glGetFramebufferAttachmentParameteriv;
2671 gl_info->fbo_ops.glBlitFramebuffer = gl_info->glBlitFramebuffer;
2672 gl_info->fbo_ops.glGenerateMipmap = gl_info->glGenerateMipmap;
2676 if (gl_info->supported[EXT_FRAMEBUFFER_OBJECT])
2678 gl_info->fbo_ops.glIsRenderbuffer = gl_info->glIsRenderbufferEXT;
2679 gl_info->fbo_ops.glBindRenderbuffer = gl_info->glBindRenderbufferEXT;
2680 gl_info->fbo_ops.glDeleteRenderbuffers = gl_info->glDeleteRenderbuffersEXT;
2681 gl_info->fbo_ops.glGenRenderbuffers = gl_info->glGenRenderbuffersEXT;
2682 gl_info->fbo_ops.glRenderbufferStorage = gl_info->glRenderbufferStorageEXT;
2683 gl_info->fbo_ops.glGetRenderbufferParameteriv = gl_info->glGetRenderbufferParameterivEXT;
2684 gl_info->fbo_ops.glIsFramebuffer = gl_info->glIsFramebufferEXT;
2685 gl_info->fbo_ops.glBindFramebuffer = gl_info->glBindFramebufferEXT;
2686 gl_info->fbo_ops.glDeleteFramebuffers = gl_info->glDeleteFramebuffersEXT;
2687 gl_info->fbo_ops.glGenFramebuffers = gl_info->glGenFramebuffersEXT;
2688 gl_info->fbo_ops.glCheckFramebufferStatus = gl_info->glCheckFramebufferStatusEXT;
2689 gl_info->fbo_ops.glFramebufferTexture1D = gl_info->glFramebufferTexture1DEXT;
2690 gl_info->fbo_ops.glFramebufferTexture2D = gl_info->glFramebufferTexture2DEXT;
2691 gl_info->fbo_ops.glFramebufferTexture3D = gl_info->glFramebufferTexture3DEXT;
2692 gl_info->fbo_ops.glFramebufferRenderbuffer = gl_info->glFramebufferRenderbufferEXT;
2693 gl_info->fbo_ops.glGetFramebufferAttachmentParameteriv = gl_info->glGetFramebufferAttachmentParameterivEXT;
2694 gl_info->fbo_ops.glGenerateMipmap = gl_info->glGenerateMipmapEXT;
2696 else if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
2698 WARN_(d3d_caps)("Framebuffer objects not supported, falling back to backbuffer offscreen rendering mode.\n");
2699 wined3d_settings.offscreen_rendering_mode = ORM_BACKBUFFER;
2701 if (gl_info->supported[EXT_FRAMEBUFFER_BLIT])
2703 gl_info->fbo_ops.glBlitFramebuffer = gl_info->glBlitFramebufferEXT;
2705 if (gl_info->supported[EXT_FRAMEBUFFER_MULTISAMPLE])
2707 gl_info->fbo_ops.glRenderbufferStorageMultisample = gl_info->glRenderbufferStorageMultisampleEXT;
2711 /* MRTs are currently only supported when FBOs are used. */
2712 if (wined3d_settings.offscreen_rendering_mode != ORM_FBO)
2714 gl_info->limits.buffers = 1;
2717 gl_vendor = wined3d_guess_gl_vendor(gl_info, gl_vendor_str, gl_renderer_str);
2718 card_vendor = wined3d_guess_card_vendor(gl_vendor_str, gl_renderer_str);
2719 TRACE_(d3d_caps)("found GL_VENDOR (%s)->(0x%04x/0x%04x)\n", debugstr_a(gl_vendor_str), gl_vendor, card_vendor);
2721 device = wined3d_guess_card(gl_info, gl_renderer_str, &gl_vendor, &card_vendor);
2722 TRACE_(d3d_caps)("FOUND (fake) card: 0x%x (vendor id), 0x%x (device id)\n", card_vendor, device);
2724 gl_info->wrap_lookup[WINED3DTADDRESS_WRAP - WINED3DTADDRESS_WRAP] = GL_REPEAT;
2725 gl_info->wrap_lookup[WINED3DTADDRESS_MIRROR - WINED3DTADDRESS_WRAP] =
2726 gl_info->supported[ARB_TEXTURE_MIRRORED_REPEAT] ? GL_MIRRORED_REPEAT_ARB : GL_REPEAT;
2727 gl_info->wrap_lookup[WINED3DTADDRESS_CLAMP - WINED3DTADDRESS_WRAP] = GL_CLAMP_TO_EDGE;
2728 gl_info->wrap_lookup[WINED3DTADDRESS_BORDER - WINED3DTADDRESS_WRAP] =
2729 gl_info->supported[ARB_TEXTURE_BORDER_CLAMP] ? GL_CLAMP_TO_BORDER_ARB : GL_REPEAT;
2730 gl_info->wrap_lookup[WINED3DTADDRESS_MIRRORONCE - WINED3DTADDRESS_WRAP] =
2731 gl_info->supported[ATI_TEXTURE_MIRROR_ONCE] ? GL_MIRROR_CLAMP_TO_EDGE_ATI : GL_REPEAT;
2733 /* Make sure there's an active HDC else the WGL extensions will fail */
2734 hdc = pwglGetCurrentDC();
2736 /* Not all GL drivers might offer WGL extensions e.g. VirtualBox */
2737 if(GL_EXTCALL(wglGetExtensionsStringARB))
2738 WGL_Extensions = GL_EXTCALL(wglGetExtensionsStringARB(hdc));
2740 if (!WGL_Extensions)
2742 ERR(" WGL_Extensions returns NULL\n");
2746 TRACE_(d3d_caps)("WGL_Extensions reported:\n");
2747 while (*WGL_Extensions)
2752 while (isspace(*WGL_Extensions)) WGL_Extensions++;
2753 Start = WGL_Extensions;
2754 while (!isspace(*WGL_Extensions) && *WGL_Extensions) ++WGL_Extensions;
2756 len = WGL_Extensions - Start;
2757 if (!len || len >= sizeof(ThisExtn))
2760 memcpy(ThisExtn, Start, len);
2761 ThisExtn[len] = '\0';
2762 TRACE_(d3d_caps)("- %s\n", debugstr_a(ThisExtn));
2764 if (!strcmp(ThisExtn, "WGL_ARB_pixel_format")) {
2765 gl_info->supported[WGL_ARB_PIXEL_FORMAT] = TRUE;
2766 TRACE_(d3d_caps)("FOUND: WGL_ARB_pixel_format support\n");
2768 if (!strcmp(ThisExtn, "WGL_WINE_pixel_format_passthrough")) {
2769 gl_info->supported[WGL_WINE_PIXEL_FORMAT_PASSTHROUGH] = TRUE;
2770 TRACE_(d3d_caps)("FOUND: WGL_WINE_pixel_format_passthrough support\n");
2776 fixup_extensions(gl_info, gl_renderer_str, gl_vendor, card_vendor, device);
2777 init_driver_info(driver_info, card_vendor, device);
2778 add_gl_compat_wrappers(gl_info);
2783 /**********************************************************
2784 * IWineD3D implementation follows
2785 **********************************************************/
2787 static UINT WINAPI IWineD3DImpl_GetAdapterCount (IWineD3D *iface) {
2788 IWineD3DImpl *This = (IWineD3DImpl *)iface;
2790 TRACE_(d3d_caps)("(%p): Reporting %u adapters\n", This, This->adapter_count);
2792 return This->adapter_count;
2795 static HRESULT WINAPI IWineD3DImpl_RegisterSoftwareDevice(IWineD3D *iface, void *init_function)
2797 FIXME("iface %p, init_function %p stub!\n", iface, init_function);
2802 static HMONITOR WINAPI IWineD3DImpl_GetAdapterMonitor(IWineD3D *iface, UINT Adapter) {
2803 IWineD3DImpl *This = (IWineD3DImpl *)iface;
2805 TRACE_(d3d_caps)("(%p)->(%d)\n", This, Adapter);
2807 if (Adapter >= IWineD3DImpl_GetAdapterCount(iface)) {
2811 return MonitorFromPoint(This->adapters[Adapter].monitorPoint, MONITOR_DEFAULTTOPRIMARY);
2814 /* FIXME: GetAdapterModeCount and EnumAdapterModes currently only returns modes
2815 of the same bpp but different resolutions */
2817 /* Note: dx9 supplies a format. Calls from d3d8 supply WINED3DFMT_UNKNOWN */
2818 static UINT WINAPI IWineD3DImpl_GetAdapterModeCount(IWineD3D *iface, UINT Adapter, enum wined3d_format_id format_id)
2820 IWineD3DImpl *This = (IWineD3DImpl *)iface;
2822 TRACE_(d3d_caps)("iface %p, adapter %u, format_id: %s.\n", iface, Adapter, debug_d3dformat(format_id));
2824 if (Adapter >= IWineD3D_GetAdapterCount(iface)) {
2828 /* TODO: Store modes per adapter and read it from the adapter structure */
2831 const struct wined3d_format *format = wined3d_get_format(&This->adapters[Adapter].gl_info, format_id);
2832 UINT format_bits = format->byte_count * CHAR_BIT;
2837 memset(&mode, 0, sizeof(mode));
2838 mode.dmSize = sizeof(mode);
2840 while (EnumDisplaySettingsExW(NULL, j, &mode, 0))
2844 if (format_id == WINED3DFMT_UNKNOWN)
2846 /* This is for D3D8, do not enumerate P8 here */
2847 if (mode.dmBitsPerPel == 32 || mode.dmBitsPerPel == 16) ++i;
2849 else if (mode.dmBitsPerPel == format_bits)
2855 TRACE_(d3d_caps)("(%p}->(Adapter: %d) => %d (out of %d)\n", This, Adapter, i, j);
2858 FIXME_(d3d_caps)("Adapter not primary display\n");
2863 /* Note: dx9 supplies a format. Calls from d3d8 supply WINED3DFMT_UNKNOWN */
2864 static HRESULT WINAPI IWineD3DImpl_EnumAdapterModes(IWineD3D *iface, UINT Adapter,
2865 enum wined3d_format_id format_id, UINT Mode, WINED3DDISPLAYMODE *pMode)
2867 IWineD3DImpl *This = (IWineD3DImpl *)iface;
2869 TRACE_(d3d_caps)("iface %p, adapter_idx %u, format %s, mode_idx %u, mode %p.\n",
2870 iface, Adapter, debug_d3dformat(format_id), Mode, pMode);
2872 /* Validate the parameters as much as possible */
2873 if (!pMode || Adapter >= IWineD3DImpl_GetAdapterCount(iface)
2874 || Mode >= IWineD3DImpl_GetAdapterModeCount(iface, Adapter, format_id))
2876 return WINED3DERR_INVALIDCALL;
2879 /* TODO: Store modes per adapter and read it from the adapter structure */
2882 const struct wined3d_format *format = wined3d_get_format(&This->adapters[Adapter].gl_info, format_id);
2883 UINT format_bits = format->byte_count * CHAR_BIT;
2889 ZeroMemory(&DevModeW, sizeof(DevModeW));
2890 DevModeW.dmSize = sizeof(DevModeW);
2892 /* If we are filtering to a specific format (D3D9), then need to skip
2893 all unrelated modes, but if mode is irrelevant (D3D8), then we can
2894 just count through the ones with valid bit depths */
2895 while ((i<=Mode) && EnumDisplaySettingsExW(NULL, j++, &DevModeW, 0))
2897 if (format_id == WINED3DFMT_UNKNOWN)
2899 /* This is for D3D8, do not enumerate P8 here */
2900 if (DevModeW.dmBitsPerPel == 32 || DevModeW.dmBitsPerPel == 16) ++i;
2902 else if (DevModeW.dmBitsPerPel == format_bits)
2910 TRACE_(d3d_caps)("No modes found for format (%x - %s)\n", format_id, debug_d3dformat(format_id));
2911 return WINED3DERR_INVALIDCALL;
2915 /* Now get the display mode via the calculated index */
2916 if (EnumDisplaySettingsExW(NULL, ModeIdx, &DevModeW, 0)) {
2917 pMode->Width = DevModeW.dmPelsWidth;
2918 pMode->Height = DevModeW.dmPelsHeight;
2919 pMode->RefreshRate = DEFAULT_REFRESH_RATE;
2920 if (DevModeW.dmFields & DM_DISPLAYFREQUENCY)
2921 pMode->RefreshRate = DevModeW.dmDisplayFrequency;
2923 if (format_id == WINED3DFMT_UNKNOWN)
2924 pMode->Format = pixelformat_for_depth(DevModeW.dmBitsPerPel);
2926 pMode->Format = format_id;
2930 TRACE_(d3d_caps)("Requested mode out of range %d\n", Mode);
2931 return WINED3DERR_INVALIDCALL;
2934 TRACE_(d3d_caps)("W %d H %d rr %d fmt (%x - %s) bpp %u\n", pMode->Width, pMode->Height,
2935 pMode->RefreshRate, pMode->Format, debug_d3dformat(pMode->Format),
2936 DevModeW.dmBitsPerPel);
2941 FIXME_(d3d_caps)("Adapter not primary display\n");
2947 static HRESULT WINAPI IWineD3DImpl_GetAdapterDisplayMode(IWineD3D *iface, UINT Adapter, WINED3DDISPLAYMODE *pMode)
2949 TRACE("iface %p, adapter_idx %u, display_mode %p.\n", iface, Adapter, pMode);
2951 if (!pMode || Adapter >= IWineD3D_GetAdapterCount(iface))
2952 return WINED3DERR_INVALIDCALL;
2954 if (Adapter == 0) { /* Display */
2958 ZeroMemory(&DevModeW, sizeof(DevModeW));
2959 DevModeW.dmSize = sizeof(DevModeW);
2961 EnumDisplaySettingsExW(NULL, ENUM_CURRENT_SETTINGS, &DevModeW, 0);
2962 pMode->Width = DevModeW.dmPelsWidth;
2963 pMode->Height = DevModeW.dmPelsHeight;
2964 bpp = DevModeW.dmBitsPerPel;
2965 pMode->RefreshRate = DEFAULT_REFRESH_RATE;
2966 if (DevModeW.dmFields&DM_DISPLAYFREQUENCY)
2968 pMode->RefreshRate = DevModeW.dmDisplayFrequency;
2971 pMode->Format = pixelformat_for_depth(bpp);
2973 FIXME_(d3d_caps)("Adapter not primary display\n");
2976 TRACE_(d3d_caps)("returning w:%d, h:%d, ref:%d, fmt:%s\n", pMode->Width,
2977 pMode->Height, pMode->RefreshRate, debug_d3dformat(pMode->Format));
2981 /* NOTE: due to structure differences between dx8 and dx9 D3DADAPTER_IDENTIFIER,
2982 and fields being inserted in the middle, a new structure is used in place */
2983 static HRESULT WINAPI IWineD3DImpl_GetAdapterIdentifier(IWineD3D *iface, UINT Adapter, DWORD Flags,
2984 WINED3DADAPTER_IDENTIFIER* pIdentifier) {
2985 IWineD3DImpl *This = (IWineD3DImpl *)iface;
2986 struct wined3d_adapter *adapter;
2989 TRACE_(d3d_caps)("(%p}->(Adapter: %d, Flags: %x, pId=%p)\n", This, Adapter, Flags, pIdentifier);
2991 if (Adapter >= IWineD3D_GetAdapterCount(iface)) {
2992 return WINED3DERR_INVALIDCALL;
2995 adapter = &This->adapters[Adapter];
2997 /* Return the information requested */
2998 TRACE_(d3d_caps)("device/Vendor Name and Version detection using FillGLCaps\n");
3000 if (pIdentifier->driver_size)
3002 const char *name = adapter->driver_info.name;
3003 len = min(strlen(name), pIdentifier->driver_size - 1);
3004 memcpy(pIdentifier->driver, name, len);
3005 pIdentifier->driver[len] = '\0';
3008 if (pIdentifier->description_size)
3010 const char *description = adapter->driver_info.description;
3011 len = min(strlen(description), pIdentifier->description_size - 1);
3012 memcpy(pIdentifier->description, description, len);
3013 pIdentifier->description[len] = '\0';
3016 /* Note that d3d8 doesn't supply a device name. */
3017 if (pIdentifier->device_name_size)
3019 static const char *device_name = "\\\\.\\DISPLAY1"; /* FIXME: May depend on desktop? */
3021 len = strlen(device_name);
3022 if (len >= pIdentifier->device_name_size)
3024 ERR("Device name size too small.\n");
3025 return WINED3DERR_INVALIDCALL;
3028 memcpy(pIdentifier->device_name, device_name, len);
3029 pIdentifier->device_name[len] = '\0';
3032 pIdentifier->driver_version.u.HighPart = adapter->driver_info.version_high;
3033 pIdentifier->driver_version.u.LowPart = adapter->driver_info.version_low;
3034 pIdentifier->vendor_id = adapter->driver_info.vendor;
3035 pIdentifier->device_id = adapter->driver_info.device;
3036 pIdentifier->subsystem_id = 0;
3037 pIdentifier->revision = 0;
3038 memcpy(&pIdentifier->device_identifier, &IID_D3DDEVICE_D3DUID, sizeof(pIdentifier->device_identifier));
3039 pIdentifier->whql_level = (Flags & WINED3DENUM_NO_WHQL_LEVEL) ? 0 : 1;
3040 memcpy(&pIdentifier->adapter_luid, &adapter->luid, sizeof(pIdentifier->adapter_luid));
3041 pIdentifier->video_memory = adapter->TextureRam;
3046 static BOOL IWineD3DImpl_IsPixelFormatCompatibleWithRenderFmt(const struct wined3d_gl_info *gl_info,
3047 const WineD3D_PixelFormat *cfg, const struct wined3d_format *format)
3049 short redSize, greenSize, blueSize, alphaSize, colorBits;
3054 /* Float formats need FBOs. If FBOs are used this function isn't called */
3055 if (format->Flags & WINED3DFMT_FLAG_FLOAT) return FALSE;
3057 if(cfg->iPixelType == WGL_TYPE_RGBA_ARB) { /* Integer RGBA formats */
3058 if (!getColorBits(format, &redSize, &greenSize, &blueSize, &alphaSize, &colorBits))
3060 ERR("Unable to check compatibility for format %s.\n", debug_d3dformat(format->id));
3064 if(cfg->redSize < redSize)
3067 if(cfg->greenSize < greenSize)
3070 if(cfg->blueSize < blueSize)
3073 if(cfg->alphaSize < alphaSize)
3079 /* Probably a RGBA_float or color index mode */
3083 static BOOL IWineD3DImpl_IsPixelFormatCompatibleWithDepthFmt(const struct wined3d_gl_info *gl_info,
3084 const WineD3D_PixelFormat *cfg, const struct wined3d_format *format)
3086 short depthSize, stencilSize;
3087 BOOL lockable = FALSE;
3092 if (!getDepthStencilBits(format, &depthSize, &stencilSize))
3094 ERR("Unable to check compatibility for format %s.\n", debug_d3dformat(format->id));
3098 /* Float formats need FBOs. If FBOs are used this function isn't called */
3099 if (format->Flags & WINED3DFMT_FLAG_FLOAT) return FALSE;
3101 if ((format->id == WINED3DFMT_D16_LOCKABLE) || (format->id == WINED3DFMT_D32_FLOAT))
3104 /* On some modern cards like the Geforce8/9 GLX doesn't offer some dephthstencil formats which D3D9 reports.
3105 * We can safely report 'compatible' formats (e.g. D24 can be used for D16) as long as we aren't dealing with
3106 * a lockable format. This also helps D3D <= 7 as they expect D16 which isn't offered without this on Geforce8 cards. */
3107 if(!(cfg->depthSize == depthSize || (!lockable && cfg->depthSize > depthSize)))
3110 /* Some cards like Intel i915 ones only offer D24S8 but lots of games also need a format without stencil, so
3111 * allow more stencil bits than requested. */
3112 if(cfg->stencilSize < stencilSize)
3118 static HRESULT WINAPI IWineD3DImpl_CheckDepthStencilMatch(IWineD3D *iface,
3119 UINT Adapter, WINED3DDEVTYPE DeviceType, enum wined3d_format_id AdapterFormat,
3120 enum wined3d_format_id RenderTargetFormat, enum wined3d_format_id DepthStencilFormat)
3122 IWineD3DImpl *This = (IWineD3DImpl *)iface;
3124 const WineD3D_PixelFormat *cfgs;
3125 const struct wined3d_adapter *adapter;
3126 const struct wined3d_format *rt_format;
3127 const struct wined3d_format *ds_format;
3130 WARN_(d3d_caps)("(%p)-> (STUB) (Adptr:%d, DevType:(%x,%s), AdptFmt:(%x,%s), RendrTgtFmt:(%x,%s), DepthStencilFmt:(%x,%s))\n",
3132 DeviceType, debug_d3ddevicetype(DeviceType),
3133 AdapterFormat, debug_d3dformat(AdapterFormat),
3134 RenderTargetFormat, debug_d3dformat(RenderTargetFormat),
3135 DepthStencilFormat, debug_d3dformat(DepthStencilFormat));
3137 if (Adapter >= IWineD3D_GetAdapterCount(iface)) {
3138 TRACE("(%p) Failed: Atapter (%u) higher than supported adapters (%u) returning WINED3DERR_INVALIDCALL\n", This, Adapter, IWineD3D_GetAdapterCount(iface));
3139 return WINED3DERR_INVALIDCALL;
3142 adapter = &This->adapters[Adapter];
3143 rt_format = wined3d_get_format(&adapter->gl_info, RenderTargetFormat);
3144 ds_format = wined3d_get_format(&adapter->gl_info, DepthStencilFormat);
3145 if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
3147 if ((rt_format->Flags & WINED3DFMT_FLAG_RENDERTARGET)
3148 && (ds_format->Flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL)))
3150 TRACE_(d3d_caps)("(%p) : Formats matched\n", This);
3156 cfgs = adapter->cfgs;
3157 nCfgs = adapter->nCfgs;
3158 for (it = 0; it < nCfgs; ++it)
3160 if (IWineD3DImpl_IsPixelFormatCompatibleWithRenderFmt(&adapter->gl_info, &cfgs[it], rt_format))
3162 if (IWineD3DImpl_IsPixelFormatCompatibleWithDepthFmt(&adapter->gl_info, &cfgs[it], ds_format))
3164 TRACE_(d3d_caps)("(%p) : Formats matched\n", This);
3170 WARN_(d3d_caps)("unsupported format pair: %s and %s\n", debug_d3dformat(RenderTargetFormat), debug_d3dformat(DepthStencilFormat));
3172 return WINED3DERR_NOTAVAILABLE;
3175 static HRESULT WINAPI IWineD3DImpl_CheckDeviceMultiSampleType(IWineD3D *iface, UINT Adapter,
3176 WINED3DDEVTYPE DeviceType, enum wined3d_format_id SurfaceFormat, BOOL Windowed,
3177 WINED3DMULTISAMPLE_TYPE MultiSampleType, DWORD *pQualityLevels)
3179 IWineD3DImpl *This = (IWineD3DImpl *)iface;
3180 const struct wined3d_adapter *adapter;
3181 const struct wined3d_format *format;
3183 TRACE_(d3d_caps)("(%p)-> (Adptr:%d, DevType:(%x,%s), SurfFmt:(%x,%s), Win?%d, MultiSamp:%x, pQual:%p)\n",
3186 DeviceType, debug_d3ddevicetype(DeviceType),
3187 SurfaceFormat, debug_d3dformat(SurfaceFormat),
3192 if (Adapter >= IWineD3D_GetAdapterCount(iface)) {
3193 return WINED3DERR_INVALIDCALL;
3196 /* TODO: handle Windowed, add more quality levels */
3198 if (WINED3DMULTISAMPLE_NONE == MultiSampleType) {
3199 if(pQualityLevels) *pQualityLevels = 1;
3203 /* By default multisampling is disabled right now as it causes issues
3204 * on some Nvidia driver versions and it doesn't work well in combination
3206 if(!wined3d_settings.allow_multisampling)
3207 return WINED3DERR_NOTAVAILABLE;
3209 adapter = &This->adapters[Adapter];
3210 format = wined3d_get_format(&adapter->gl_info, SurfaceFormat);
3211 if (!format) return WINED3DERR_INVALIDCALL;
3213 if (format->Flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL))
3216 const WineD3D_PixelFormat *cfgs;
3218 cfgs = adapter->cfgs;
3219 nCfgs = adapter->nCfgs;
3220 for(i=0; i<nCfgs; i++) {
3221 if(cfgs[i].numSamples != MultiSampleType)
3224 if (!IWineD3DImpl_IsPixelFormatCompatibleWithDepthFmt(&adapter->gl_info, &cfgs[i], format))
3227 TRACE("Found iPixelFormat=%d to support MultiSampleType=%d for format %s\n", cfgs[i].iPixelFormat, MultiSampleType, debug_d3dformat(SurfaceFormat));
3230 *pQualityLevels = 1; /* Guess at a value! */
3234 else if (format->Flags & WINED3DFMT_FLAG_RENDERTARGET)
3236 short redSize, greenSize, blueSize, alphaSize, colorBits;
3238 const WineD3D_PixelFormat *cfgs;
3240 if (!getColorBits(format, &redSize, &greenSize, &blueSize, &alphaSize, &colorBits))
3242 ERR("Unable to color bits for format %#x, can't check multisampling capability!\n", SurfaceFormat);
3243 return WINED3DERR_NOTAVAILABLE;
3246 cfgs = adapter->cfgs;
3247 nCfgs = adapter->nCfgs;
3248 for(i=0; i<nCfgs; i++) {
3249 if(cfgs[i].numSamples != MultiSampleType)
3251 if(cfgs[i].redSize != redSize)
3253 if(cfgs[i].greenSize != greenSize)
3255 if(cfgs[i].blueSize != blueSize)
3257 /* Not all drivers report alpha-less formats since they use 32-bit anyway, so accept alpha even if we didn't ask for it. */
3258 if(alphaSize && cfgs[i].alphaSize != alphaSize)
3260 if (cfgs[i].colorSize != (format->byte_count << 3))
3263 TRACE("Found iPixelFormat=%d to support MultiSampleType=%d for format %s\n", cfgs[i].iPixelFormat, MultiSampleType, debug_d3dformat(SurfaceFormat));
3266 *pQualityLevels = 1; /* Guess at a value! */
3270 return WINED3DERR_NOTAVAILABLE;
3273 /* Check if we support bumpmapping for a format */
3274 static BOOL CheckBumpMapCapability(struct wined3d_adapter *adapter, const struct wined3d_format *format)
3276 /* Ask the fixed function pipeline implementation if it can deal
3277 * with the conversion. If we've got a GL extension giving native
3278 * support this will be an identity conversion. */
3279 return (format->Flags & WINED3DFMT_FLAG_BUMPMAP)
3280 && adapter->fragment_pipe->color_fixup_supported(format->color_fixup);
3283 /* Check if the given DisplayFormat + DepthStencilFormat combination is valid for the Adapter */
3284 static BOOL CheckDepthStencilCapability(struct wined3d_adapter *adapter,
3285 const struct wined3d_format *display_format, const struct wined3d_format *ds_format)
3289 /* Only allow depth/stencil formats */
3290 if (!(ds_format->depth_size || ds_format->stencil_size)) return FALSE;
3292 if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
3294 /* With FBOs WGL limitations do not apply, but the format needs to be FBO attachable */
3295 if (ds_format->Flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL)) return TRUE;
3299 /* Walk through all WGL pixel formats to find a match */
3300 for (it = 0; it < adapter->nCfgs; ++it)
3302 WineD3D_PixelFormat *cfg = &adapter->cfgs[it];
3303 if (IWineD3DImpl_IsPixelFormatCompatibleWithRenderFmt(&adapter->gl_info, cfg, display_format))
3305 if (IWineD3DImpl_IsPixelFormatCompatibleWithDepthFmt(&adapter->gl_info, cfg, ds_format))
3316 static BOOL CheckFilterCapability(struct wined3d_adapter *adapter, const struct wined3d_format *format)
3318 /* The flags entry of a format contains the filtering capability */
3319 if (format->Flags & WINED3DFMT_FLAG_FILTERING) return TRUE;
3324 /* Check the render target capabilities of a format */
3325 static BOOL CheckRenderTargetCapability(struct wined3d_adapter *adapter,
3326 const struct wined3d_format *adapter_format, const struct wined3d_format *check_format)
3328 /* Filter out non-RT formats */
3329 if (!(check_format->Flags & WINED3DFMT_FLAG_RENDERTARGET)) return FALSE;
3330 if (wined3d_settings.offscreen_rendering_mode == ORM_BACKBUFFER)
3332 WineD3D_PixelFormat *cfgs = adapter->cfgs;
3334 short AdapterRed, AdapterGreen, AdapterBlue, AdapterAlpha, AdapterTotalSize;
3335 short CheckRed, CheckGreen, CheckBlue, CheckAlpha, CheckTotalSize;
3337 getColorBits(adapter_format, &AdapterRed, &AdapterGreen, &AdapterBlue, &AdapterAlpha, &AdapterTotalSize);
3338 getColorBits(check_format, &CheckRed, &CheckGreen, &CheckBlue, &CheckAlpha, &CheckTotalSize);
3340 /* In backbuffer mode the front and backbuffer share the same WGL pixelformat.
3341 * The format must match in RGB, alpha is allowed to be different. (Only the backbuffer can have alpha) */
3342 if(!((AdapterRed == CheckRed) && (AdapterGreen == CheckGreen) && (AdapterBlue == CheckBlue))) {
3343 TRACE_(d3d_caps)("[FAILED]\n");
3347 /* Check if there is a WGL pixel format matching the requirements, the format should also be window
3348 * drawable (not offscreen; e.g. Nvidia offers R5G6B5 for pbuffers even when X is running at 24bit) */
3349 for (it = 0; it < adapter->nCfgs; ++it)
3351 if (cfgs[it].windowDrawable && IWineD3DImpl_IsPixelFormatCompatibleWithRenderFmt(&adapter->gl_info,
3352 &cfgs[it], check_format))
3354 TRACE_(d3d_caps)("Pixel format %d is compatible with format %s.\n",
3355 cfgs[it].iPixelFormat, debug_d3dformat(check_format->id));
3360 else if(wined3d_settings.offscreen_rendering_mode == ORM_FBO)
3362 /* For now return TRUE for FBOs until we have some proper checks.
3363 * Note that this function will only be called when the format is around for texturing. */
3369 static BOOL CheckSrgbReadCapability(struct wined3d_adapter *adapter, const struct wined3d_format *format)
3371 return adapter->gl_info.supported[EXT_TEXTURE_SRGB] && (format->Flags & WINED3DFMT_FLAG_SRGB_READ);
3374 static BOOL CheckSrgbWriteCapability(struct wined3d_adapter *adapter, const struct wined3d_format *format)
3376 /* Only offer SRGB writing on X8R8G8B8/A8R8G8B8 when we use ARB or GLSL shaders as we are
3377 * doing the color fixup in shaders.
3378 * Note Windows drivers (at least on the Geforce 8800) also offer this on R5G6B5. */
3379 if (format->Flags & WINED3DFMT_FLAG_SRGB_WRITE)
3381 int vs_selected_mode;
3382 int ps_selected_mode;
3383 select_shader_mode(&adapter->gl_info, &ps_selected_mode, &vs_selected_mode);
3385 if((ps_selected_mode == SHADER_ARB) || (ps_selected_mode == SHADER_GLSL)) {
3386 TRACE_(d3d_caps)("[OK]\n");
3391 TRACE_(d3d_caps)("[FAILED] - sRGB writes not supported by format %s.\n", debug_d3dformat(format->id));
3395 /* Check if a format support blending in combination with pixel shaders */
3396 static BOOL CheckPostPixelShaderBlendingCapability(struct wined3d_adapter *adapter,
3397 const struct wined3d_format *format)
3399 /* The flags entry of a format contains the post pixel shader blending capability */
3400 if (format->Flags & WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING) return TRUE;
3405 static BOOL CheckWrapAndMipCapability(struct wined3d_adapter *adapter, const struct wined3d_format *format)
3407 /* OpenGL supports mipmapping on all formats basically. Wrapping is unsupported,
3408 * but we have to report mipmapping so we cannot reject this flag. Tests show that
3409 * windows reports WRAPANDMIP on unfilterable surfaces as well, apparently to show
3410 * that wrapping is supported. The lack of filtering will sort out the mipmapping
3411 * capability anyway.
3413 * For now lets report this on all formats, but in the future we may want to
3414 * restrict it to some should games need that
3419 /* Check if a texture format is supported on the given adapter */
3420 static BOOL CheckTextureCapability(struct wined3d_adapter *adapter, const struct wined3d_format *format)
3422 const struct wined3d_gl_info *gl_info = &adapter->gl_info;
3427 * supported: RGB(A) formats
3429 case WINED3DFMT_B8G8R8_UNORM: /* Enable for dx7, blacklisted for 8 and 9 above */
3430 case WINED3DFMT_B8G8R8A8_UNORM:
3431 case WINED3DFMT_B8G8R8X8_UNORM:
3432 case WINED3DFMT_B5G6R5_UNORM:
3433 case WINED3DFMT_B5G5R5X1_UNORM:
3434 case WINED3DFMT_B5G5R5A1_UNORM:
3435 case WINED3DFMT_B4G4R4A4_UNORM:
3436 case WINED3DFMT_A8_UNORM:
3437 case WINED3DFMT_B4G4R4X4_UNORM:
3438 case WINED3DFMT_R8G8B8A8_UNORM:
3439 case WINED3DFMT_R8G8B8X8_UNORM:
3440 case WINED3DFMT_B10G10R10A2_UNORM:
3441 case WINED3DFMT_R10G10B10A2_UNORM:
3442 case WINED3DFMT_R16G16_UNORM:
3443 TRACE_(d3d_caps)("[OK]\n");
3446 case WINED3DFMT_B2G3R3_UNORM:
3447 TRACE_(d3d_caps)("[FAILED] - Not supported on Windows\n");
3451 * Not supported: Palettized
3452 * Only some Geforce/Voodoo3/G400 cards offer 8-bit textures in case of <=Direct3D7.
3453 * Since it is not widely available, don't offer it. Further no Windows driver offers
3454 * WINED3DFMT_P8_UINT_A8_NORM, so don't offer it either.
3456 case WINED3DFMT_P8_UINT:
3457 case WINED3DFMT_P8_UINT_A8_UNORM:
3461 * Supported: (Alpha)-Luminance
3463 case WINED3DFMT_L8_UNORM:
3464 case WINED3DFMT_L8A8_UNORM:
3465 case WINED3DFMT_L16_UNORM:
3466 TRACE_(d3d_caps)("[OK]\n");
3469 /* Not supported on Windows, thus disabled */
3470 case WINED3DFMT_L4A4_UNORM:
3471 TRACE_(d3d_caps)("[FAILED] - not supported on windows\n");
3475 * Supported: Depth/Stencil formats
3477 case WINED3DFMT_D16_LOCKABLE:
3478 case WINED3DFMT_D16_UNORM:
3479 case WINED3DFMT_S1_UINT_D15_UNORM:
3480 case WINED3DFMT_X8D24_UNORM:
3481 case WINED3DFMT_S4X4_UINT_D24_UNORM:
3482 case WINED3DFMT_D24_UNORM_S8_UINT:
3483 case WINED3DFMT_S8_UINT_D24_FLOAT:
3484 case WINED3DFMT_D32_UNORM:
3485 case WINED3DFMT_D32_FLOAT:
3488 case WINED3DFMT_INTZ:
3489 if (gl_info->supported[EXT_PACKED_DEPTH_STENCIL]
3490 || gl_info->supported[ARB_FRAMEBUFFER_OBJECT])
3495 * Not supported everywhere(depends on GL_ATI_envmap_bumpmap or
3496 * GL_NV_texture_shader). Emulated by shaders
3498 case WINED3DFMT_R8G8_SNORM:
3499 case WINED3DFMT_R8G8_SNORM_L8X8_UNORM:
3500 case WINED3DFMT_R5G5_SNORM_L6_UNORM:
3501 case WINED3DFMT_R8G8B8A8_SNORM:
3502 case WINED3DFMT_R16G16_SNORM:
3503 /* Ask the shader backend if it can deal with the conversion. If
3504 * we've got a GL extension giving native support this will be an
3505 * identity conversion. */
3506 if (adapter->shader_backend->shader_color_fixup_supported(format->color_fixup))
3508 TRACE_(d3d_caps)("[OK]\n");
3511 TRACE_(d3d_caps)("[FAILED]\n");
3514 case WINED3DFMT_DXT1:
3515 case WINED3DFMT_DXT2:
3516 case WINED3DFMT_DXT3:
3517 case WINED3DFMT_DXT4:
3518 case WINED3DFMT_DXT5:
3519 if (gl_info->supported[EXT_TEXTURE_COMPRESSION_S3TC])
3521 TRACE_(d3d_caps)("[OK]\n");
3524 TRACE_(d3d_caps)("[FAILED]\n");
3529 * Odd formats - not supported
3531 case WINED3DFMT_VERTEXDATA:
3532 case WINED3DFMT_R16_UINT:
3533 case WINED3DFMT_R32_UINT:
3534 case WINED3DFMT_R16G16B16A16_SNORM:
3535 case WINED3DFMT_R10G10B10_SNORM_A2_UNORM:
3536 case WINED3DFMT_R10G11B11_SNORM:
3537 TRACE_(d3d_caps)("[FAILED]\n"); /* Enable when implemented */
3541 * WINED3DFMT_R8G8_SNORM_Cx: Not supported right now
3543 case WINED3DFMT_R8G8_SNORM_Cx:
3544 TRACE_(d3d_caps)("[FAILED]\n"); /* Enable when implemented */
3548 case WINED3DFMT_UYVY:
3549 case WINED3DFMT_YUY2:
3550 if (gl_info->supported[APPLE_YCBCR_422])
3552 TRACE_(d3d_caps)("[OK]\n");
3555 TRACE_(d3d_caps)("[FAILED]\n");
3557 case WINED3DFMT_YV12:
3558 TRACE_(d3d_caps)("[FAILED]\n");
3562 case WINED3DFMT_R16G16B16A16_UNORM:
3563 case WINED3DFMT_B2G3R3A8_UNORM:
3564 TRACE_(d3d_caps)("[FAILED]\n"); /* Enable when implemented */
3567 /* Floating point formats */
3568 case WINED3DFMT_R16_FLOAT:
3569 case WINED3DFMT_R16G16_FLOAT:
3570 case WINED3DFMT_R16G16B16A16_FLOAT:
3571 if (gl_info->supported[ARB_TEXTURE_FLOAT] && gl_info->supported[ARB_HALF_FLOAT_PIXEL])
3573 TRACE_(d3d_caps)("[OK]\n");
3576 TRACE_(d3d_caps)("[FAILED]\n");
3579 case WINED3DFMT_R32_FLOAT:
3580 case WINED3DFMT_R32G32_FLOAT:
3581 case WINED3DFMT_R32G32B32A32_FLOAT:
3582 if (gl_info->supported[ARB_TEXTURE_FLOAT])
3584 TRACE_(d3d_caps)("[OK]\n");
3587 TRACE_(d3d_caps)("[FAILED]\n");
3590 /* ATI instancing hack: Although ATI cards do not support Shader Model 3.0, they support
3591 * instancing. To query if the card supports instancing CheckDeviceFormat with the special format
3592 * MAKEFOURCC('I','N','S','T') is used. Should a (broken) app check for this provide a proper return value.
3593 * We can do instancing with all shader versions, but we need vertex shaders.
3595 * Additionally applications have to set the D3DRS_POINTSIZE render state to MAKEFOURCC('I','N','S','T') once
3596 * to enable instancing. WineD3D doesn't need that and just ignores it.
3598 * With Shader Model 3.0 capable cards Instancing 'just works' in Windows.
3600 case WINED3DFMT_INST:
3601 TRACE("ATI Instancing check hack\n");
3602 if (gl_info->supported[ARB_VERTEX_PROGRAM] || gl_info->supported[ARB_VERTEX_SHADER])
3604 TRACE_(d3d_caps)("[OK]\n");
3607 TRACE_(d3d_caps)("[FAILED]\n");
3610 /* Some weird FOURCC formats */
3611 case WINED3DFMT_R8G8_B8G8:
3612 case WINED3DFMT_G8R8_G8B8:
3613 case WINED3DFMT_MULTI2_ARGB8:
3614 TRACE_(d3d_caps)("[FAILED]\n");
3617 /* Vendor specific formats */
3618 case WINED3DFMT_ATI2N:
3619 if (gl_info->supported[ATI_TEXTURE_COMPRESSION_3DC]
3620 || gl_info->supported[ARB_TEXTURE_COMPRESSION_RGTC])
3622 if (adapter->shader_backend->shader_color_fixup_supported(format->color_fixup)
3623 && adapter->fragment_pipe->color_fixup_supported(format->color_fixup))
3625 TRACE_(d3d_caps)("[OK]\n");
3629 TRACE_(d3d_caps)("[OK]\n");
3632 TRACE_(d3d_caps)("[FAILED]\n");
3635 /* Depth bound test. To query if the card supports it CheckDeviceFormat with the special
3636 * format MAKEFOURCC('N','V','D','B') is used.
3637 * It is enabled by setting D3DRS_ADAPTIVETESS_X render state to MAKEFOURCC('N','V','D','B') and
3638 * then controlled by setting D3DRS_ADAPTIVETESS_Z (zMin) and D3DRS_ADAPTIVETESS_W (zMax)
3641 case WINED3DFMT_NVDB:
3642 if (gl_info->supported[EXT_DEPTH_BOUNDS_TEST])
3644 TRACE_(d3d_caps)("[OK]\n");
3647 TRACE_(d3d_caps)("[FAILED]\n");
3650 case WINED3DFMT_NVHU:
3651 case WINED3DFMT_NVHS:
3652 /* These formats seem to be similar to the HILO formats in GL_NV_texture_shader. NVHU
3653 * is said to be GL_UNSIGNED_HILO16, NVHS GL_SIGNED_HILO16. Rumours say that d3d computes
3654 * a 3rd channel similarly to D3DFMT_CxV8U8(So NVHS could be called D3DFMT_CxV16U16).
3655 * ATI refused to support formats which can easilly be emulated with pixel shaders, so
3656 * Applications have to deal with not having NVHS and NVHU.
3658 TRACE_(d3d_caps)("[FAILED]\n");
3661 case WINED3DFMT_UNKNOWN:
3665 ERR("Unhandled format %s.\n", debug_d3dformat(format->id));
3671 static BOOL CheckSurfaceCapability(struct wined3d_adapter *adapter,
3672 const struct wined3d_format *adapter_format,
3673 const struct wined3d_format *check_format,
3674 WINED3DSURFTYPE SurfaceType)
3676 if (SurfaceType == SURFACE_GDI)
3678 switch (check_format->id)
3680 case WINED3DFMT_B8G8R8_UNORM:
3681 case WINED3DFMT_B8G8R8A8_UNORM:
3682 case WINED3DFMT_B8G8R8X8_UNORM:
3683 case WINED3DFMT_B5G6R5_UNORM:
3684 case WINED3DFMT_B5G5R5X1_UNORM:
3685 case WINED3DFMT_B5G5R5A1_UNORM:
3686 case WINED3DFMT_B4G4R4A4_UNORM:
3687 case WINED3DFMT_B2G3R3_UNORM:
3688 case WINED3DFMT_A8_UNORM:
3689 case WINED3DFMT_B2G3R3A8_UNORM:
3690 case WINED3DFMT_B4G4R4X4_UNORM:
3691 case WINED3DFMT_R10G10B10A2_UNORM:
3692 case WINED3DFMT_R8G8B8A8_UNORM:
3693 case WINED3DFMT_R8G8B8X8_UNORM:
3694 case WINED3DFMT_R16G16_UNORM:
3695 case WINED3DFMT_B10G10R10A2_UNORM:
3696 case WINED3DFMT_R16G16B16A16_UNORM:
3697 case WINED3DFMT_P8_UINT:
3698 TRACE_(d3d_caps)("[OK]\n");
3701 TRACE_(d3d_caps)("[FAILED] - not available on GDI surfaces\n");
3706 /* All format that are supported for textures are supported for surfaces as well */
3707 if (CheckTextureCapability(adapter, check_format)) return TRUE;
3708 /* All depth stencil formats are supported on surfaces */
3709 if (CheckDepthStencilCapability(adapter, adapter_format, check_format)) return TRUE;
3711 /* If opengl can't process the format natively, the blitter may be able to convert it */
3712 if (adapter->blitter->blit_supported(&adapter->gl_info, BLIT_OP_BLIT,
3713 NULL, WINED3DPOOL_DEFAULT, 0, check_format,
3714 NULL, WINED3DPOOL_DEFAULT, 0, adapter_format))
3716 TRACE_(d3d_caps)("[OK]\n");
3720 /* Reject other formats */
3721 TRACE_(d3d_caps)("[FAILED]\n");
3725 static BOOL CheckVertexTextureCapability(struct wined3d_adapter *adapter,
3726 const struct wined3d_format *format)
3728 return adapter->gl_info.limits.vertex_samplers && (format->Flags & WINED3DFMT_FLAG_VTF);
3731 static HRESULT WINAPI IWineD3DImpl_CheckDeviceFormat(IWineD3D *iface, UINT Adapter, WINED3DDEVTYPE DeviceType,
3732 enum wined3d_format_id AdapterFormat, DWORD Usage, WINED3DRESOURCETYPE RType,
3733 enum wined3d_format_id CheckFormat, WINED3DSURFTYPE SurfaceType)
3735 IWineD3DImpl *This = (IWineD3DImpl *)iface;
3736 struct wined3d_adapter *adapter = &This->adapters[Adapter];
3737 const struct wined3d_gl_info *gl_info = &adapter->gl_info;
3738 const struct wined3d_format *format = wined3d_get_format(gl_info, CheckFormat);
3739 const struct wined3d_format *adapter_format = wined3d_get_format(gl_info, AdapterFormat);
3740 DWORD UsageCaps = 0;
3742 TRACE_(d3d_caps)("(%p)-> (STUB) (Adptr:%d, DevType:(%u,%s), AdptFmt:(%u,%s), Use:(%u,%s,%s), ResTyp:(%x,%s), CheckFmt:(%u,%s))\n",
3745 DeviceType, debug_d3ddevicetype(DeviceType),
3746 AdapterFormat, debug_d3dformat(AdapterFormat),
3747 Usage, debug_d3dusage(Usage), debug_d3dusagequery(Usage),
3748 RType, debug_d3dresourcetype(RType),
3749 CheckFormat, debug_d3dformat(CheckFormat));
3751 if (Adapter >= IWineD3D_GetAdapterCount(iface)) {
3752 return WINED3DERR_INVALIDCALL;
3757 case WINED3DRTYPE_CUBETEXTURE:
3758 /* Cubetexture allows:
3759 * - WINED3DUSAGE_AUTOGENMIPMAP
3760 * - WINED3DUSAGE_DEPTHSTENCIL
3761 * - WINED3DUSAGE_DYNAMIC
3762 * - WINED3DUSAGE_NONSECURE (d3d9ex)
3763 * - WINED3DUSAGE_RENDERTARGET
3764 * - WINED3DUSAGE_SOFTWAREPROCESSING
3765 * - WINED3DUSAGE_QUERY_WRAPANDMIP
3767 if (SurfaceType != SURFACE_OPENGL)
3769 TRACE_(d3d_caps)("[FAILED]\n");
3770 return WINED3DERR_NOTAVAILABLE;
3773 if (!gl_info->supported[ARB_TEXTURE_CUBE_MAP])
3775 TRACE_(d3d_caps)("[FAILED] - No cube texture support\n");
3776 return WINED3DERR_NOTAVAILABLE;
3779 if (!CheckTextureCapability(adapter, format))
3781 TRACE_(d3d_caps)("[FAILED] - Cube texture format not supported\n");
3782 return WINED3DERR_NOTAVAILABLE;
3785 if (Usage & WINED3DUSAGE_AUTOGENMIPMAP)
3787 if (!gl_info->supported[SGIS_GENERATE_MIPMAP])
3788 /* When autogenmipmap isn't around continue and return
3789 * WINED3DOK_NOAUTOGEN instead of D3D_OK. */
3790 TRACE_(d3d_caps)("[FAILED] - No autogenmipmap support, but continuing\n");
3792 UsageCaps |= WINED3DUSAGE_AUTOGENMIPMAP;
3795 /* Always report dynamic locking. */
3796 if (Usage & WINED3DUSAGE_DYNAMIC)
3797 UsageCaps |= WINED3DUSAGE_DYNAMIC;
3799 if (Usage & WINED3DUSAGE_RENDERTARGET)
3801 if (!CheckRenderTargetCapability(adapter, adapter_format, format))
3803 TRACE_(d3d_caps)("[FAILED] - No rendertarget support\n");
3804 return WINED3DERR_NOTAVAILABLE;
3806 UsageCaps |= WINED3DUSAGE_RENDERTARGET;
3809 /* Always report software processing. */
3810 if (Usage & WINED3DUSAGE_SOFTWAREPROCESSING)
3811 UsageCaps |= WINED3DUSAGE_SOFTWAREPROCESSING;
3813 if (Usage & WINED3DUSAGE_QUERY_FILTER)
3815 if (!CheckFilterCapability(adapter, format))
3817 TRACE_(d3d_caps)("[FAILED] - No query filter support\n");
3818 return WINED3DERR_NOTAVAILABLE;
3820 UsageCaps |= WINED3DUSAGE_QUERY_FILTER;
3823 if (Usage & WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING)
3825 if (!CheckPostPixelShaderBlendingCapability(adapter, format))
3827 TRACE_(d3d_caps)("[FAILED] - No query post pixelshader blending support\n");
3828 return WINED3DERR_NOTAVAILABLE;
3830 UsageCaps |= WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING;
3833 if (Usage & WINED3DUSAGE_QUERY_SRGBREAD)
3835 if (!CheckSrgbReadCapability(adapter, format))
3837 TRACE_(d3d_caps)("[FAILED] - No query srgbread support\n");
3838 return WINED3DERR_NOTAVAILABLE;
3840 UsageCaps |= WINED3DUSAGE_QUERY_SRGBREAD;
3843 if (Usage & WINED3DUSAGE_QUERY_SRGBWRITE)
3845 if (!CheckSrgbWriteCapability(adapter, format))
3847 TRACE_(d3d_caps)("[FAILED] - No query srgbwrite support\n");
3848 return WINED3DERR_NOTAVAILABLE;
3850 UsageCaps |= WINED3DUSAGE_QUERY_SRGBWRITE;
3853 if (Usage & WINED3DUSAGE_QUERY_VERTEXTEXTURE)
3855 if (!CheckVertexTextureCapability(adapter, format))
3857 TRACE_(d3d_caps)("[FAILED] - No query vertextexture support\n");
3858 return WINED3DERR_NOTAVAILABLE;
3860 UsageCaps |= WINED3DUSAGE_QUERY_VERTEXTEXTURE;
3863 if (Usage & WINED3DUSAGE_QUERY_WRAPANDMIP)
3865 if (!CheckWrapAndMipCapability(adapter, format))
3867 TRACE_(d3d_caps)("[FAILED] - No wrapping and mipmapping support\n");
3868 return WINED3DERR_NOTAVAILABLE;
3870 UsageCaps |= WINED3DUSAGE_QUERY_WRAPANDMIP;
3874 case WINED3DRTYPE_SURFACE:
3876 * - WINED3DUSAGE_DEPTHSTENCIL
3877 * - WINED3DUSAGE_NONSECURE (d3d9ex)
3878 * - WINED3DUSAGE_RENDERTARGET
3880 if (!CheckSurfaceCapability(adapter, adapter_format, format, SurfaceType))
3882 TRACE_(d3d_caps)("[FAILED] - Not supported for plain surfaces\n");
3883 return WINED3DERR_NOTAVAILABLE;
3886 if (Usage & WINED3DUSAGE_DEPTHSTENCIL)
3888 if (!CheckDepthStencilCapability(adapter, adapter_format, format))
3890 TRACE_(d3d_caps)("[FAILED] - No depthstencil support\n");
3891 return WINED3DERR_NOTAVAILABLE;
3893 UsageCaps |= WINED3DUSAGE_DEPTHSTENCIL;
3896 if (Usage & WINED3DUSAGE_RENDERTARGET)
3898 if (!CheckRenderTargetCapability(adapter, adapter_format, format))
3900 TRACE_(d3d_caps)("[FAILED] - No rendertarget support\n");
3901 return WINED3DERR_NOTAVAILABLE;
3903 UsageCaps |= WINED3DUSAGE_RENDERTARGET;
3906 if (Usage & WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING)
3908 if (!CheckPostPixelShaderBlendingCapability(adapter, format))
3910 TRACE_(d3d_caps)("[FAILED] - No query post pixelshader blending support\n");
3911 return WINED3DERR_NOTAVAILABLE;
3913 UsageCaps |= WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING;
3917 case WINED3DRTYPE_TEXTURE:
3919 * - WINED3DUSAGE_AUTOGENMIPMAP
3920 * - WINED3DUSAGE_DEPTHSTENCIL
3921 * - WINED3DUSAGE_DMAP
3922 * - WINED3DUSAGE_DYNAMIC
3923 * - WINED3DUSAGE_NONSECURE (d3d9ex)
3924 * - WINED3DUSAGE_RENDERTARGET
3925 * - WINED3DUSAGE_SOFTWAREPROCESSING
3926 * - WINED3DUSAGE_TEXTAPI (d3d9ex)
3927 * - WINED3DUSAGE_QUERY_WRAPANDMIP
3929 if (SurfaceType != SURFACE_OPENGL)
3931 TRACE_(d3d_caps)("[FAILED]\n");
3932 return WINED3DERR_NOTAVAILABLE;
3935 if (!CheckTextureCapability(adapter, format))
3937 TRACE_(d3d_caps)("[FAILED] - Texture format not supported\n");
3938 return WINED3DERR_NOTAVAILABLE;
3941 if (Usage & WINED3DUSAGE_AUTOGENMIPMAP)
3943 if (!gl_info->supported[SGIS_GENERATE_MIPMAP])
3944 /* When autogenmipmap isn't around continue and return
3945 * WINED3DOK_NOAUTOGEN instead of D3D_OK. */
3946 TRACE_(d3d_caps)("[FAILED] - No autogenmipmap support, but continuing\n");
3948 UsageCaps |= WINED3DUSAGE_AUTOGENMIPMAP;
3951 /* Always report dynamic locking. */
3952 if (Usage & WINED3DUSAGE_DYNAMIC)
3953 UsageCaps |= WINED3DUSAGE_DYNAMIC;
3955 if (Usage & WINED3DUSAGE_RENDERTARGET)
3957 if (!CheckRenderTargetCapability(adapter, adapter_format, format))
3959 TRACE_(d3d_caps)("[FAILED] - No rendertarget support\n");
3960 return WINED3DERR_NOTAVAILABLE;
3962 UsageCaps |= WINED3DUSAGE_RENDERTARGET;
3965 /* Always report software processing. */
3966 if (Usage & WINED3DUSAGE_SOFTWAREPROCESSING)
3967 UsageCaps |= WINED3DUSAGE_SOFTWAREPROCESSING;
3969 if (Usage & WINED3DUSAGE_QUERY_FILTER)
3971 if (!CheckFilterCapability(adapter, format))
3973 TRACE_(d3d_caps)("[FAILED] - No query filter support\n");
3974 return WINED3DERR_NOTAVAILABLE;
3976 UsageCaps |= WINED3DUSAGE_QUERY_FILTER;
3979 if (Usage & WINED3DUSAGE_QUERY_LEGACYBUMPMAP)
3981 if (!CheckBumpMapCapability(adapter, format))
3983 TRACE_(d3d_caps)("[FAILED] - No legacy bumpmap support\n");
3984 return WINED3DERR_NOTAVAILABLE;
3986 UsageCaps |= WINED3DUSAGE_QUERY_LEGACYBUMPMAP;
3989 if (Usage & WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING)
3991 if (!CheckPostPixelShaderBlendingCapability(adapter, format))
3993 TRACE_(d3d_caps)("[FAILED] - No query post pixelshader blending support\n");
3994 return WINED3DERR_NOTAVAILABLE;
3996 UsageCaps |= WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING;
3999 if (Usage & WINED3DUSAGE_QUERY_SRGBREAD)
4001 if (!CheckSrgbReadCapability(adapter, format))
4003 TRACE_(d3d_caps)("[FAILED] - No query srgbread support\n");
4004 return WINED3DERR_NOTAVAILABLE;
4006 UsageCaps |= WINED3DUSAGE_QUERY_SRGBREAD;
4009 if (Usage & WINED3DUSAGE_QUERY_SRGBWRITE)
4011 if (!CheckSrgbWriteCapability(adapter, format))
4013 TRACE_(d3d_caps)("[FAILED] - No query srgbwrite support\n");
4014 return WINED3DERR_NOTAVAILABLE;
4016 UsageCaps |= WINED3DUSAGE_QUERY_SRGBWRITE;
4019 if (Usage & WINED3DUSAGE_QUERY_VERTEXTEXTURE)
4021 if (!CheckVertexTextureCapability(adapter, format))
4023 TRACE_(d3d_caps)("[FAILED] - No query vertextexture support\n");
4024 return WINED3DERR_NOTAVAILABLE;
4026 UsageCaps |= WINED3DUSAGE_QUERY_VERTEXTEXTURE;
4029 if (Usage & WINED3DUSAGE_QUERY_WRAPANDMIP)
4031 if (!CheckWrapAndMipCapability(adapter, format))
4033 TRACE_(d3d_caps)("[FAILED] - No wrapping and mipmapping support\n");
4034 return WINED3DERR_NOTAVAILABLE;
4036 UsageCaps |= WINED3DUSAGE_QUERY_WRAPANDMIP;
4039 if (Usage & WINED3DUSAGE_DEPTHSTENCIL)
4041 if (!CheckDepthStencilCapability(adapter, adapter_format, format))
4043 TRACE_(d3d_caps)("[FAILED] - No depth stencil support\n");
4044 return WINED3DERR_NOTAVAILABLE;
4046 if ((format->Flags & WINED3DFMT_FLAG_SHADOW) && !gl_info->supported[ARB_SHADOW])
4048 TRACE_(d3d_caps)("[FAILED] - No shadow sampler support.\n");
4049 return WINED3DERR_NOTAVAILABLE;
4051 UsageCaps |= WINED3DUSAGE_DEPTHSTENCIL;
4055 case WINED3DRTYPE_VOLUMETEXTURE:
4056 case WINED3DRTYPE_VOLUME:
4057 /* Volume is to VolumeTexture what Surface is to Texture, but its
4058 * usage caps are not documented. Most driver seem to offer
4059 * (nearly) the same on Volume and VolumeTexture, so do that too.
4061 * Volumetexture allows:
4062 * - D3DUSAGE_DYNAMIC
4063 * - D3DUSAGE_NONSECURE (d3d9ex)
4064 * - D3DUSAGE_SOFTWAREPROCESSING
4065 * - D3DUSAGE_QUERY_WRAPANDMIP
4067 if (SurfaceType != SURFACE_OPENGL)
4069 TRACE_(d3d_caps)("[FAILED]\n");
4070 return WINED3DERR_NOTAVAILABLE;
4073 if (!gl_info->supported[EXT_TEXTURE3D])
4075 TRACE_(d3d_caps)("[FAILED] - No volume texture support\n");
4076 return WINED3DERR_NOTAVAILABLE;
4079 if (!CheckTextureCapability(adapter, format))
4081 TRACE_(d3d_caps)("[FAILED] - Format not supported\n");
4082 return WINED3DERR_NOTAVAILABLE;
4085 /* Filter formats that need conversion; For one part, this
4086 * conversion is unimplemented, and volume textures are huge, so
4087 * it would be a big performance hit. Unless we hit an application
4088 * needing one of those formats, don't advertize them to avoid
4089 * leading applications into temptation. The windows drivers don't
4090 * support most of those formats on volumes anyway, except for
4091 * WINED3DFMT_R32_FLOAT. */
4092 switch (CheckFormat)
4094 case WINED3DFMT_P8_UINT:
4095 case WINED3DFMT_L4A4_UNORM:
4096 case WINED3DFMT_R32_FLOAT:
4097 case WINED3DFMT_R16_FLOAT:
4098 case WINED3DFMT_R8G8_SNORM_L8X8_UNORM:
4099 case WINED3DFMT_R5G5_SNORM_L6_UNORM:
4100 case WINED3DFMT_R16G16_UNORM:
4101 TRACE_(d3d_caps)("[FAILED] - No converted formats on volumes\n");
4102 return WINED3DERR_NOTAVAILABLE;
4104 case WINED3DFMT_R8G8B8A8_SNORM:
4105 case WINED3DFMT_R16G16_SNORM:
4106 if (!gl_info->supported[NV_TEXTURE_SHADER])
4108 TRACE_(d3d_caps)("[FAILED] - No converted formats on volumes\n");
4109 return WINED3DERR_NOTAVAILABLE;
4113 case WINED3DFMT_R8G8_SNORM:
4114 if (!gl_info->supported[NV_TEXTURE_SHADER])
4116 TRACE_(d3d_caps)("[FAILED] - No converted formats on volumes\n");
4117 return WINED3DERR_NOTAVAILABLE;
4121 case WINED3DFMT_DXT1:
4122 case WINED3DFMT_DXT2:
4123 case WINED3DFMT_DXT3:
4124 case WINED3DFMT_DXT4:
4125 case WINED3DFMT_DXT5:
4126 /* The GL_EXT_texture_compression_s3tc spec requires that
4127 * loading an s3tc compressed texture results in an error.
4128 * While the D3D refrast does support s3tc volumes, at
4129 * least the nvidia windows driver does not, so we're free
4130 * not to support this format. */
4131 TRACE_(d3d_caps)("[FAILED] - DXTn does not support 3D textures\n");
4132 return WINED3DERR_NOTAVAILABLE;
4135 /* Do nothing, continue with checking the format below */
4139 /* Always report dynamic locking. */
4140 if (Usage & WINED3DUSAGE_DYNAMIC)
4141 UsageCaps |= WINED3DUSAGE_DYNAMIC;
4143 /* Always report software processing. */
4144 if (Usage & WINED3DUSAGE_SOFTWAREPROCESSING)
4145 UsageCaps |= WINED3DUSAGE_SOFTWAREPROCESSING;
4147 if (Usage & WINED3DUSAGE_QUERY_FILTER)
4149 if (!CheckFilterCapability(adapter, format))
4151 TRACE_(d3d_caps)("[FAILED] - No query filter support\n");
4152 return WINED3DERR_NOTAVAILABLE;
4154 UsageCaps |= WINED3DUSAGE_QUERY_FILTER;
4157 if (Usage & WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING)
4159 if (!CheckPostPixelShaderBlendingCapability(adapter, format))
4161 TRACE_(d3d_caps)("[FAILED] - No query post pixelshader blending support\n");
4162 return WINED3DERR_NOTAVAILABLE;
4164 UsageCaps |= WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING;
4167 if (Usage & WINED3DUSAGE_QUERY_SRGBREAD)
4169 if (!CheckSrgbReadCapability(adapter, format))
4171 TRACE_(d3d_caps)("[FAILED] - No query srgbread support\n");
4172 return WINED3DERR_NOTAVAILABLE;
4174 UsageCaps |= WINED3DUSAGE_QUERY_SRGBREAD;
4177 if (Usage & WINED3DUSAGE_QUERY_SRGBWRITE)
4179 if (!CheckSrgbWriteCapability(adapter, format))
4181 TRACE_(d3d_caps)("[FAILED] - No query srgbwrite support\n");
4182 return WINED3DERR_NOTAVAILABLE;
4184 UsageCaps |= WINED3DUSAGE_QUERY_SRGBWRITE;
4187 if (Usage & WINED3DUSAGE_QUERY_VERTEXTEXTURE)
4189 if (!CheckVertexTextureCapability(adapter, format))
4191 TRACE_(d3d_caps)("[FAILED] - No query vertextexture support\n");
4192 return WINED3DERR_NOTAVAILABLE;
4194 UsageCaps |= WINED3DUSAGE_QUERY_VERTEXTEXTURE;
4197 if (Usage & WINED3DUSAGE_QUERY_WRAPANDMIP)
4199 if (!CheckWrapAndMipCapability(adapter, format))
4201 TRACE_(d3d_caps)("[FAILED] - No wrapping and mipmapping support\n");
4202 return WINED3DERR_NOTAVAILABLE;
4204 UsageCaps |= WINED3DUSAGE_QUERY_WRAPANDMIP;
4209 FIXME_(d3d_caps)("Unhandled resource type %s.\n", debug_d3dresourcetype(RType));
4210 return WINED3DERR_NOTAVAILABLE;
4213 /* When the UsageCaps exactly matches Usage return WINED3D_OK except for
4214 * the situation in which WINED3DUSAGE_AUTOGENMIPMAP isn't around, then
4215 * WINED3DOK_NOAUTOGEN is returned if all the other usage flags match. */
4216 if (UsageCaps == Usage)
4218 if (UsageCaps == (Usage & ~WINED3DUSAGE_AUTOGENMIPMAP))
4219 return WINED3DOK_NOAUTOGEN;
4221 TRACE_(d3d_caps)("[FAILED] - Usage %#x requested for CheckFormat %s and RType %s but only %#x is available\n",
4222 Usage, debug_d3dformat(CheckFormat), debug_d3dresourcetype(RType), UsageCaps);
4224 return WINED3DERR_NOTAVAILABLE;
4227 static HRESULT WINAPI IWineD3DImpl_CheckDeviceFormatConversion(IWineD3D *iface, UINT adapter_idx,
4228 WINED3DDEVTYPE device_type, enum wined3d_format_id src_format, enum wined3d_format_id dst_format)
4230 FIXME("iface %p, adapter_idx %u, device_type %s, src_format %s, dst_format %s stub!\n",
4231 iface, adapter_idx, debug_d3ddevicetype(device_type), debug_d3dformat(src_format),
4232 debug_d3dformat(dst_format));
4237 static HRESULT WINAPI IWineD3DImpl_CheckDeviceType(IWineD3D *iface, UINT adapter_idx, WINED3DDEVTYPE device_type,
4238 enum wined3d_format_id display_format, enum wined3d_format_id backbuffer_format, BOOL windowed)
4243 TRACE("iface %p, adapter_idx %u, device_type %s, display_format %s, backbuffer_format %s, windowed %#x.\n",
4244 iface, adapter_idx, debug_d3ddevicetype(device_type), debug_d3dformat(display_format),
4245 debug_d3dformat(backbuffer_format), windowed);
4247 if (adapter_idx >= IWineD3D_GetAdapterCount(iface))
4249 WARN_(d3d_caps)("adapter_idx >= IWineD3D_GetAdapterCount(iface), returning WINED3DERR_INVALIDCALL\n");
4250 return WINED3DERR_INVALIDCALL;
4253 /* The task of this function is to check whether a certain display / backbuffer format
4254 * combination is available on the given adapter. In fullscreen mode microsoft specified
4255 * that the display format shouldn't provide alpha and that ignoring alpha the backbuffer
4256 * and display format should match exactly.
4257 * In windowed mode format conversion can occur and this depends on the driver. When format
4258 * conversion is done, this function should nevertheless fail and applications need to use
4259 * CheckDeviceFormatConversion.
4260 * At the moment we assume that fullscreen and windowed have the same capabilities. */
4262 /* There are only 4 display formats. */
4263 if (!(display_format == WINED3DFMT_B5G6R5_UNORM
4264 || display_format == WINED3DFMT_B5G5R5X1_UNORM
4265 || display_format == WINED3DFMT_B8G8R8X8_UNORM
4266 || display_format == WINED3DFMT_B10G10R10A2_UNORM))
4268 TRACE_(d3d_caps)("Format %s is not supported as display format.\n", debug_d3dformat(display_format));
4269 return WINED3DERR_NOTAVAILABLE;
4272 /* If the requested display format is not available, don't continue. */
4273 mode_count = IWineD3DImpl_GetAdapterModeCount(iface, adapter_idx, display_format);
4276 TRACE_(d3d_caps)("No available modes for display format %s.\n", debug_d3dformat(display_format));
4277 return WINED3DERR_NOTAVAILABLE;
4280 /* Windowed mode allows you to specify WINED3DFMT_UNKNOWN for the backbuffer format,
4281 * it means 'reuse' the display format for the backbuffer. */
4282 if (!windowed && backbuffer_format == WINED3DFMT_UNKNOWN)
4284 TRACE_(d3d_caps)("backbuffer_format WINED3FMT_UNKNOWN only available in windowed mode.\n");
4285 return WINED3DERR_NOTAVAILABLE;
4288 /* In FULLSCREEN mode WINED3DFMT_B5G6R5_UNORM can only be mixed with
4289 * backbuffer format WINED3DFMT_B5G6R5_UNORM. */
4290 if (display_format == WINED3DFMT_B5G6R5_UNORM && backbuffer_format != WINED3DFMT_B5G6R5_UNORM)
4292 TRACE_(d3d_caps)("Unsupported display/backbuffer format combination %s / %s.\n",
4293 debug_d3dformat(display_format), debug_d3dformat(backbuffer_format));
4294 return WINED3DERR_NOTAVAILABLE;
4297 /* In FULLSCREEN mode WINED3DFMT_B5G5R5X1_UNORM can only be mixed with
4298 * backbuffer formats WINED3DFMT_B5G5R5X1_UNORM and
4299 * WINED3DFMT_B5G5R5A1_UNORM. */
4300 if (display_format == WINED3DFMT_B5G5R5X1_UNORM
4301 && !(backbuffer_format == WINED3DFMT_B5G5R5X1_UNORM || backbuffer_format == WINED3DFMT_B5G5R5A1_UNORM))
4303 TRACE_(d3d_caps)("Unsupported display/backbuffer format combination %s / %s.\n",
4304 debug_d3dformat(display_format), debug_d3dformat(backbuffer_format));
4305 return WINED3DERR_NOTAVAILABLE;
4308 /* In FULLSCREEN mode WINED3DFMT_B8G8R8X8_UNORM can only be mixed with
4309 * backbuffer formats WINED3DFMT_B8G8R8X8_UNORM and
4310 * WINED3DFMT_B8G8R8A8_UNORM. */
4311 if (display_format == WINED3DFMT_B8G8R8X8_UNORM
4312 && !(backbuffer_format == WINED3DFMT_B8G8R8X8_UNORM || backbuffer_format == WINED3DFMT_B8G8R8A8_UNORM))
4314 TRACE_(d3d_caps)("Unsupported display/backbuffer format combination %s / %s.\n",
4315 debug_d3dformat(display_format), debug_d3dformat(backbuffer_format));
4316 return WINED3DERR_NOTAVAILABLE;
4319 /* WINED3DFMT_B10G10R10A2_UNORM is only allowed in fullscreen mode and it
4320 * can only be mixed with backbuffer format WINED3DFMT_B10G10R10A2_UNORM. */
4321 if (display_format == WINED3DFMT_B10G10R10A2_UNORM
4322 && (backbuffer_format != WINED3DFMT_B10G10R10A2_UNORM || windowed))
4324 TRACE_(d3d_caps)("Unsupported display/backbuffer format combination %s / %s.\n",
4325 debug_d3dformat(display_format), debug_d3dformat(backbuffer_format));
4326 return WINED3DERR_NOTAVAILABLE;
4329 /* Use CheckDeviceFormat to see if the backbuffer_format is usable with the given display_format */
4330 hr = IWineD3DImpl_CheckDeviceFormat(iface, adapter_idx, device_type, display_format,
4331 WINED3DUSAGE_RENDERTARGET, WINED3DRTYPE_SURFACE, backbuffer_format, SURFACE_OPENGL);
4333 TRACE_(d3d_caps)("Unsupported display/backbuffer format combination %s / %s.\n",
4334 debug_d3dformat(display_format), debug_d3dformat(backbuffer_format));
4339 /* Note: d3d8 passes in a pointer to a D3DCAPS8 structure, which is a true
4340 subset of a D3DCAPS9 structure. However, it has to come via a void *
4341 as the d3d8 interface cannot import the d3d9 header */
4342 static HRESULT WINAPI IWineD3DImpl_GetDeviceCaps(IWineD3D *iface, UINT Adapter, WINED3DDEVTYPE DeviceType, WINED3DCAPS* pCaps) {
4344 IWineD3DImpl *This = (IWineD3DImpl *)iface;
4345 struct wined3d_adapter *adapter = &This->adapters[Adapter];
4346 const struct wined3d_gl_info *gl_info = &adapter->gl_info;
4347 int vs_selected_mode;
4348 int ps_selected_mode;
4349 struct shader_caps shader_caps;
4350 struct fragment_caps fragment_caps;
4351 DWORD ckey_caps, blit_caps, fx_caps, pal_caps;
4353 TRACE_(d3d_caps)("(%p)->(Adptr:%d, DevType: %x, pCaps: %p)\n", This, Adapter, DeviceType, pCaps);
4355 if (Adapter >= IWineD3D_GetAdapterCount(iface)) {
4356 return WINED3DERR_INVALIDCALL;
4359 select_shader_mode(&adapter->gl_info, &ps_selected_mode, &vs_selected_mode);
4361 /* ------------------------------------------------
4362 The following fields apply to both d3d8 and d3d9
4363 ------------------------------------------------ */
4364 pCaps->DeviceType = (DeviceType == WINED3DDEVTYPE_HAL) ? WINED3DDEVTYPE_HAL : WINED3DDEVTYPE_REF; /* Not quite true, but use h/w supported by opengl I suppose */
4365 pCaps->AdapterOrdinal = Adapter;
4368 pCaps->Caps2 = WINED3DCAPS2_CANRENDERWINDOWED |
4369 WINED3DCAPS2_FULLSCREENGAMMA |
4370 WINED3DCAPS2_DYNAMICTEXTURES;
4371 if (gl_info->supported[SGIS_GENERATE_MIPMAP])
4373 pCaps->Caps2 |= WINED3DCAPS2_CANAUTOGENMIPMAP;
4376 pCaps->Caps3 = WINED3DCAPS3_ALPHA_FULLSCREEN_FLIP_OR_DISCARD |
4377 WINED3DCAPS3_COPY_TO_VIDMEM |
4378 WINED3DCAPS3_COPY_TO_SYSTEMMEM;
4380 pCaps->PresentationIntervals = WINED3DPRESENT_INTERVAL_IMMEDIATE |
4381 WINED3DPRESENT_INTERVAL_ONE;
4383 pCaps->CursorCaps = WINED3DCURSORCAPS_COLOR |
4384 WINED3DCURSORCAPS_LOWRES;
4386 pCaps->DevCaps = WINED3DDEVCAPS_FLOATTLVERTEX |
4387 WINED3DDEVCAPS_EXECUTESYSTEMMEMORY |
4388 WINED3DDEVCAPS_TLVERTEXSYSTEMMEMORY|
4389 WINED3DDEVCAPS_TLVERTEXVIDEOMEMORY |
4390 WINED3DDEVCAPS_DRAWPRIMTLVERTEX |
4391 WINED3DDEVCAPS_HWTRANSFORMANDLIGHT |
4392 WINED3DDEVCAPS_EXECUTEVIDEOMEMORY |
4393 WINED3DDEVCAPS_PUREDEVICE |
4394 WINED3DDEVCAPS_HWRASTERIZATION |
4395 WINED3DDEVCAPS_TEXTUREVIDEOMEMORY |
4396 WINED3DDEVCAPS_TEXTURESYSTEMMEMORY |
4397 WINED3DDEVCAPS_CANRENDERAFTERFLIP |
4398 WINED3DDEVCAPS_DRAWPRIMITIVES2 |
4399 WINED3DDEVCAPS_DRAWPRIMITIVES2EX |
4400 WINED3DDEVCAPS_RTPATCHES;
4402 pCaps->PrimitiveMiscCaps = WINED3DPMISCCAPS_CULLNONE |
4403 WINED3DPMISCCAPS_CULLCCW |
4404 WINED3DPMISCCAPS_CULLCW |
4405 WINED3DPMISCCAPS_COLORWRITEENABLE |
4406 WINED3DPMISCCAPS_CLIPTLVERTS |
4407 WINED3DPMISCCAPS_CLIPPLANESCALEDPOINTS |
4408 WINED3DPMISCCAPS_MASKZ |
4409 WINED3DPMISCCAPS_BLENDOP |
4410 WINED3DPMISCCAPS_MRTPOSTPIXELSHADERBLENDING;
4412 WINED3DPMISCCAPS_NULLREFERENCE
4413 WINED3DPMISCCAPS_FOGANDSPECULARALPHA
4414 WINED3DPMISCCAPS_MRTINDEPENDENTBITDEPTHS
4415 WINED3DPMISCCAPS_FOGVERTEXCLAMPED */
4417 if (gl_info->supported[EXT_BLEND_EQUATION_SEPARATE] && gl_info->supported[EXT_BLEND_FUNC_SEPARATE])
4418 pCaps->PrimitiveMiscCaps |= WINED3DPMISCCAPS_SEPARATEALPHABLEND;
4419 if (gl_info->supported[EXT_DRAW_BUFFERS2])
4420 pCaps->PrimitiveMiscCaps |= WINED3DPMISCCAPS_INDEPENDENTWRITEMASKS;
4422 pCaps->RasterCaps = WINED3DPRASTERCAPS_DITHER |
4423 WINED3DPRASTERCAPS_PAT |
4424 WINED3DPRASTERCAPS_WFOG |
4425 WINED3DPRASTERCAPS_ZFOG |
4426 WINED3DPRASTERCAPS_FOGVERTEX |
4427 WINED3DPRASTERCAPS_FOGTABLE |
4428 WINED3DPRASTERCAPS_STIPPLE |
4429 WINED3DPRASTERCAPS_SUBPIXEL |
4430 WINED3DPRASTERCAPS_ZTEST |
4431 WINED3DPRASTERCAPS_SCISSORTEST |
4432 WINED3DPRASTERCAPS_SLOPESCALEDEPTHBIAS |
4433 WINED3DPRASTERCAPS_DEPTHBIAS;
4435 if (gl_info->supported[EXT_TEXTURE_FILTER_ANISOTROPIC])
4437 pCaps->RasterCaps |= WINED3DPRASTERCAPS_ANISOTROPY |
4438 WINED3DPRASTERCAPS_ZBIAS |
4439 WINED3DPRASTERCAPS_MIPMAPLODBIAS;
4441 if (gl_info->supported[NV_FOG_DISTANCE])
4443 pCaps->RasterCaps |= WINED3DPRASTERCAPS_FOGRANGE;
4446 WINED3DPRASTERCAPS_COLORPERSPECTIVE
4447 WINED3DPRASTERCAPS_STRETCHBLTMULTISAMPLE
4448 WINED3DPRASTERCAPS_ANTIALIASEDGES
4449 WINED3DPRASTERCAPS_ZBUFFERLESSHSR
4450 WINED3DPRASTERCAPS_WBUFFER */
4452 pCaps->ZCmpCaps = WINED3DPCMPCAPS_ALWAYS |
4453 WINED3DPCMPCAPS_EQUAL |
4454 WINED3DPCMPCAPS_GREATER |
4455 WINED3DPCMPCAPS_GREATEREQUAL |
4456 WINED3DPCMPCAPS_LESS |
4457 WINED3DPCMPCAPS_LESSEQUAL |
4458 WINED3DPCMPCAPS_NEVER |
4459 WINED3DPCMPCAPS_NOTEQUAL;
4461 pCaps->SrcBlendCaps = WINED3DPBLENDCAPS_BOTHINVSRCALPHA |
4462 WINED3DPBLENDCAPS_BOTHSRCALPHA |
4463 WINED3DPBLENDCAPS_DESTALPHA |
4464 WINED3DPBLENDCAPS_DESTCOLOR |
4465 WINED3DPBLENDCAPS_INVDESTALPHA |
4466 WINED3DPBLENDCAPS_INVDESTCOLOR |
4467 WINED3DPBLENDCAPS_INVSRCALPHA |
4468 WINED3DPBLENDCAPS_INVSRCCOLOR |
4469 WINED3DPBLENDCAPS_ONE |
4470 WINED3DPBLENDCAPS_SRCALPHA |
4471 WINED3DPBLENDCAPS_SRCALPHASAT |
4472 WINED3DPBLENDCAPS_SRCCOLOR |
4473 WINED3DPBLENDCAPS_ZERO;
4475 pCaps->DestBlendCaps = WINED3DPBLENDCAPS_DESTALPHA |
4476 WINED3DPBLENDCAPS_DESTCOLOR |
4477 WINED3DPBLENDCAPS_INVDESTALPHA |
4478 WINED3DPBLENDCAPS_INVDESTCOLOR |
4479 WINED3DPBLENDCAPS_INVSRCALPHA |
4480 WINED3DPBLENDCAPS_INVSRCCOLOR |
4481 WINED3DPBLENDCAPS_ONE |
4482 WINED3DPBLENDCAPS_SRCALPHA |
4483 WINED3DPBLENDCAPS_SRCCOLOR |
4484 WINED3DPBLENDCAPS_ZERO;
4485 /* NOTE: WINED3DPBLENDCAPS_SRCALPHASAT is not supported as dest blend factor,
4486 * according to the glBlendFunc manpage
4488 * WINED3DPBLENDCAPS_BOTHINVSRCALPHA and WINED3DPBLENDCAPS_BOTHSRCALPHA are
4489 * legacy settings for srcblend only
4492 if (gl_info->supported[EXT_BLEND_COLOR])
4494 pCaps->SrcBlendCaps |= WINED3DPBLENDCAPS_BLENDFACTOR;
4495 pCaps->DestBlendCaps |= WINED3DPBLENDCAPS_BLENDFACTOR;
4499 pCaps->AlphaCmpCaps = WINED3DPCMPCAPS_ALWAYS |
4500 WINED3DPCMPCAPS_EQUAL |
4501 WINED3DPCMPCAPS_GREATER |
4502 WINED3DPCMPCAPS_GREATEREQUAL |
4503 WINED3DPCMPCAPS_LESS |
4504 WINED3DPCMPCAPS_LESSEQUAL |
4505 WINED3DPCMPCAPS_NEVER |
4506 WINED3DPCMPCAPS_NOTEQUAL;
4508 pCaps->ShadeCaps = WINED3DPSHADECAPS_SPECULARGOURAUDRGB |
4509 WINED3DPSHADECAPS_COLORGOURAUDRGB |
4510 WINED3DPSHADECAPS_ALPHAFLATBLEND |
4511 WINED3DPSHADECAPS_ALPHAGOURAUDBLEND |
4512 WINED3DPSHADECAPS_COLORFLATRGB |
4513 WINED3DPSHADECAPS_FOGFLAT |
4514 WINED3DPSHADECAPS_FOGGOURAUD |
4515 WINED3DPSHADECAPS_SPECULARFLATRGB;
4517 pCaps->TextureCaps = WINED3DPTEXTURECAPS_ALPHA |
4518 WINED3DPTEXTURECAPS_ALPHAPALETTE |
4519 WINED3DPTEXTURECAPS_TRANSPARENCY |
4520 WINED3DPTEXTURECAPS_BORDER |
4521 WINED3DPTEXTURECAPS_MIPMAP |
4522 WINED3DPTEXTURECAPS_PROJECTED |
4523 WINED3DPTEXTURECAPS_PERSPECTIVE;
4525 if (!gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO])
4527 pCaps->TextureCaps |= WINED3DPTEXTURECAPS_POW2 |
4528 WINED3DPTEXTURECAPS_NONPOW2CONDITIONAL;
4531 if (gl_info->supported[EXT_TEXTURE3D])
4533 pCaps->TextureCaps |= WINED3DPTEXTURECAPS_VOLUMEMAP |
4534 WINED3DPTEXTURECAPS_MIPVOLUMEMAP |
4535 WINED3DPTEXTURECAPS_VOLUMEMAP_POW2;
4538 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
4540 pCaps->TextureCaps |= WINED3DPTEXTURECAPS_CUBEMAP |
4541 WINED3DPTEXTURECAPS_MIPCUBEMAP |
4542 WINED3DPTEXTURECAPS_CUBEMAP_POW2;
4546 pCaps->TextureFilterCaps = WINED3DPTFILTERCAPS_MAGFLINEAR |
4547 WINED3DPTFILTERCAPS_MAGFPOINT |
4548 WINED3DPTFILTERCAPS_MINFLINEAR |
4549 WINED3DPTFILTERCAPS_MINFPOINT |
4550 WINED3DPTFILTERCAPS_MIPFLINEAR |
4551 WINED3DPTFILTERCAPS_MIPFPOINT |
4552 WINED3DPTFILTERCAPS_LINEAR |
4553 WINED3DPTFILTERCAPS_LINEARMIPLINEAR |
4554 WINED3DPTFILTERCAPS_LINEARMIPNEAREST |
4555 WINED3DPTFILTERCAPS_MIPLINEAR |
4556 WINED3DPTFILTERCAPS_MIPNEAREST |
4557 WINED3DPTFILTERCAPS_NEAREST;
4559 if (gl_info->supported[EXT_TEXTURE_FILTER_ANISOTROPIC])
4561 pCaps->TextureFilterCaps |= WINED3DPTFILTERCAPS_MAGFANISOTROPIC |
4562 WINED3DPTFILTERCAPS_MINFANISOTROPIC;
4565 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
4567 pCaps->CubeTextureFilterCaps = WINED3DPTFILTERCAPS_MAGFLINEAR |
4568 WINED3DPTFILTERCAPS_MAGFPOINT |
4569 WINED3DPTFILTERCAPS_MINFLINEAR |
4570 WINED3DPTFILTERCAPS_MINFPOINT |
4571 WINED3DPTFILTERCAPS_MIPFLINEAR |
4572 WINED3DPTFILTERCAPS_MIPFPOINT |
4573 WINED3DPTFILTERCAPS_LINEAR |
4574 WINED3DPTFILTERCAPS_LINEARMIPLINEAR |
4575 WINED3DPTFILTERCAPS_LINEARMIPNEAREST |
4576 WINED3DPTFILTERCAPS_MIPLINEAR |
4577 WINED3DPTFILTERCAPS_MIPNEAREST |
4578 WINED3DPTFILTERCAPS_NEAREST;
4580 if (gl_info->supported[EXT_TEXTURE_FILTER_ANISOTROPIC])
4582 pCaps->CubeTextureFilterCaps |= WINED3DPTFILTERCAPS_MAGFANISOTROPIC |
4583 WINED3DPTFILTERCAPS_MINFANISOTROPIC;
4586 pCaps->CubeTextureFilterCaps = 0;
4588 if (gl_info->supported[EXT_TEXTURE3D])
4590 pCaps->VolumeTextureFilterCaps = WINED3DPTFILTERCAPS_MAGFLINEAR |
4591 WINED3DPTFILTERCAPS_MAGFPOINT |
4592 WINED3DPTFILTERCAPS_MINFLINEAR |
4593 WINED3DPTFILTERCAPS_MINFPOINT |
4594 WINED3DPTFILTERCAPS_MIPFLINEAR |
4595 WINED3DPTFILTERCAPS_MIPFPOINT |
4596 WINED3DPTFILTERCAPS_LINEAR |
4597 WINED3DPTFILTERCAPS_LINEARMIPLINEAR |
4598 WINED3DPTFILTERCAPS_LINEARMIPNEAREST |
4599 WINED3DPTFILTERCAPS_MIPLINEAR |
4600 WINED3DPTFILTERCAPS_MIPNEAREST |
4601 WINED3DPTFILTERCAPS_NEAREST;
4603 pCaps->VolumeTextureFilterCaps = 0;
4605 pCaps->TextureAddressCaps = WINED3DPTADDRESSCAPS_INDEPENDENTUV |
4606 WINED3DPTADDRESSCAPS_CLAMP |
4607 WINED3DPTADDRESSCAPS_WRAP;
4609 if (gl_info->supported[ARB_TEXTURE_BORDER_CLAMP])
4611 pCaps->TextureAddressCaps |= WINED3DPTADDRESSCAPS_BORDER;
4613 if (gl_info->supported[ARB_TEXTURE_MIRRORED_REPEAT])
4615 pCaps->TextureAddressCaps |= WINED3DPTADDRESSCAPS_MIRROR;
4617 if (gl_info->supported[ATI_TEXTURE_MIRROR_ONCE])
4619 pCaps->TextureAddressCaps |= WINED3DPTADDRESSCAPS_MIRRORONCE;
4622 if (gl_info->supported[EXT_TEXTURE3D])
4624 pCaps->VolumeTextureAddressCaps = WINED3DPTADDRESSCAPS_INDEPENDENTUV |
4625 WINED3DPTADDRESSCAPS_CLAMP |
4626 WINED3DPTADDRESSCAPS_WRAP;
4627 if (gl_info->supported[ARB_TEXTURE_BORDER_CLAMP])
4629 pCaps->VolumeTextureAddressCaps |= WINED3DPTADDRESSCAPS_BORDER;
4631 if (gl_info->supported[ARB_TEXTURE_MIRRORED_REPEAT])
4633 pCaps->VolumeTextureAddressCaps |= WINED3DPTADDRESSCAPS_MIRROR;
4635 if (gl_info->supported[ATI_TEXTURE_MIRROR_ONCE])
4637 pCaps->VolumeTextureAddressCaps |= WINED3DPTADDRESSCAPS_MIRRORONCE;
4640 pCaps->VolumeTextureAddressCaps = 0;
4642 pCaps->LineCaps = WINED3DLINECAPS_TEXTURE |
4643 WINED3DLINECAPS_ZTEST |
4644 WINED3DLINECAPS_BLEND |
4645 WINED3DLINECAPS_ALPHACMP |
4646 WINED3DLINECAPS_FOG;
4647 /* WINED3DLINECAPS_ANTIALIAS is not supported on Windows, and dx and gl seem to have a different
4648 * idea how generating the smoothing alpha values works; the result is different
4651 pCaps->MaxTextureWidth = gl_info->limits.texture_size;
4652 pCaps->MaxTextureHeight = gl_info->limits.texture_size;
4654 if (gl_info->supported[EXT_TEXTURE3D])
4655 pCaps->MaxVolumeExtent = gl_info->limits.texture3d_size;
4657 pCaps->MaxVolumeExtent = 0;
4659 pCaps->MaxTextureRepeat = 32768;
4660 pCaps->MaxTextureAspectRatio = gl_info->limits.texture_size;
4661 pCaps->MaxVertexW = 1.0f;
4663 pCaps->GuardBandLeft = 0.0f;
4664 pCaps->GuardBandTop = 0.0f;
4665 pCaps->GuardBandRight = 0.0f;
4666 pCaps->GuardBandBottom = 0.0f;
4668 pCaps->ExtentsAdjust = 0.0f;
4670 pCaps->StencilCaps = WINED3DSTENCILCAPS_DECRSAT |
4671 WINED3DSTENCILCAPS_INCRSAT |
4672 WINED3DSTENCILCAPS_INVERT |
4673 WINED3DSTENCILCAPS_KEEP |
4674 WINED3DSTENCILCAPS_REPLACE |
4675 WINED3DSTENCILCAPS_ZERO;
4676 if (gl_info->supported[EXT_STENCIL_WRAP])
4678 pCaps->StencilCaps |= WINED3DSTENCILCAPS_DECR |
4679 WINED3DSTENCILCAPS_INCR;
4681 if (gl_info->supported[EXT_STENCIL_TWO_SIDE] || gl_info->supported[ATI_SEPARATE_STENCIL])
4683 pCaps->StencilCaps |= WINED3DSTENCILCAPS_TWOSIDED;
4686 pCaps->FVFCaps = WINED3DFVFCAPS_PSIZE | 0x0008; /* 8 texture coords */
4688 pCaps->MaxUserClipPlanes = gl_info->limits.clipplanes;
4689 pCaps->MaxActiveLights = gl_info->limits.lights;
4691 pCaps->MaxVertexBlendMatrices = gl_info->limits.blends;
4692 pCaps->MaxVertexBlendMatrixIndex = 0;
4694 pCaps->MaxAnisotropy = gl_info->limits.anisotropy;
4695 pCaps->MaxPointSize = gl_info->limits.pointsize_max;
4698 /* FIXME: Add D3DVTXPCAPS_TWEENING, D3DVTXPCAPS_TEXGEN_SPHEREMAP */
4699 pCaps->VertexProcessingCaps = WINED3DVTXPCAPS_DIRECTIONALLIGHTS |
4700 WINED3DVTXPCAPS_MATERIALSOURCE7 |
4701 WINED3DVTXPCAPS_POSITIONALLIGHTS |
4702 WINED3DVTXPCAPS_LOCALVIEWER |
4703 WINED3DVTXPCAPS_VERTEXFOG |
4704 WINED3DVTXPCAPS_TEXGEN;
4706 pCaps->MaxPrimitiveCount = 0xFFFFF; /* For now set 2^20-1 which is used by most >=Geforce3/Radeon8500 cards */
4707 pCaps->MaxVertexIndex = 0xFFFFF;
4708 pCaps->MaxStreams = MAX_STREAMS;
4709 pCaps->MaxStreamStride = 1024;
4711 /* d3d9.dll sets D3DDEVCAPS2_CAN_STRETCHRECT_FROM_TEXTURES here because StretchRects is implemented in d3d9 */
4712 pCaps->DevCaps2 = WINED3DDEVCAPS2_STREAMOFFSET |
4713 WINED3DDEVCAPS2_VERTEXELEMENTSCANSHARESTREAMOFFSET;
4714 pCaps->MaxNpatchTessellationLevel = 0;
4715 pCaps->MasterAdapterOrdinal = 0;
4716 pCaps->AdapterOrdinalInGroup = 0;
4717 pCaps->NumberOfAdaptersInGroup = 1;
4719 pCaps->NumSimultaneousRTs = gl_info->limits.buffers;
4721 pCaps->StretchRectFilterCaps = WINED3DPTFILTERCAPS_MINFPOINT |
4722 WINED3DPTFILTERCAPS_MAGFPOINT |
4723 WINED3DPTFILTERCAPS_MINFLINEAR |
4724 WINED3DPTFILTERCAPS_MAGFLINEAR;
4725 pCaps->VertexTextureFilterCaps = 0;
4727 adapter->shader_backend->shader_get_caps(&adapter->gl_info, &shader_caps);
4728 adapter->fragment_pipe->get_caps(&adapter->gl_info, &fragment_caps);
4730 /* Add shader misc caps. Only some of them belong to the shader parts of the pipeline */
4731 pCaps->PrimitiveMiscCaps |= fragment_caps.PrimitiveMiscCaps;
4733 /* This takes care for disabling vertex shader or pixel shader caps while leaving the other one enabled.
4734 * Ignore shader model capabilities if disabled in config
4736 if(vs_selected_mode == SHADER_NONE) {
4737 TRACE_(d3d_caps)("Vertex shader disabled in config, reporting version 0.0\n");
4738 pCaps->VertexShaderVersion = WINED3DVS_VERSION(0,0);
4739 pCaps->MaxVertexShaderConst = 0;
4741 pCaps->VertexShaderVersion = shader_caps.VertexShaderVersion;
4742 pCaps->MaxVertexShaderConst = shader_caps.MaxVertexShaderConst;
4745 if(ps_selected_mode == SHADER_NONE) {
4746 TRACE_(d3d_caps)("Pixel shader disabled in config, reporting version 0.0\n");
4747 pCaps->PixelShaderVersion = WINED3DPS_VERSION(0,0);
4748 pCaps->PixelShader1xMaxValue = 0.0f;
4750 pCaps->PixelShaderVersion = shader_caps.PixelShaderVersion;
4751 pCaps->PixelShader1xMaxValue = shader_caps.PixelShader1xMaxValue;
4754 pCaps->TextureOpCaps = fragment_caps.TextureOpCaps;
4755 pCaps->MaxTextureBlendStages = fragment_caps.MaxTextureBlendStages;
4756 pCaps->MaxSimultaneousTextures = fragment_caps.MaxSimultaneousTextures;
4758 /* The following caps are shader specific, but they are things we cannot detect, or which
4759 * are the same among all shader models. So to avoid code duplication set the shader version
4760 * specific, but otherwise constant caps here
4762 if(pCaps->VertexShaderVersion == WINED3DVS_VERSION(3,0)) {
4763 /* Where possible set the caps based on OpenGL extensions and if they aren't set (in case of software rendering)
4764 use the VS 3.0 from MSDN or else if there's OpenGL spec use a hardcoded value minimum VS3.0 value. */
4765 pCaps->VS20Caps.Caps = WINED3DVS20CAPS_PREDICATION;
4766 pCaps->VS20Caps.DynamicFlowControlDepth = WINED3DVS20_MAX_DYNAMICFLOWCONTROLDEPTH; /* VS 3.0 requires MAX_DYNAMICFLOWCONTROLDEPTH (24) */
4767 pCaps->VS20Caps.NumTemps = max(32, adapter->gl_info.limits.arb_vs_temps);
4768 pCaps->VS20Caps.StaticFlowControlDepth = WINED3DVS20_MAX_STATICFLOWCONTROLDEPTH ; /* level of nesting in loops / if-statements; VS 3.0 requires MAX (4) */
4770 pCaps->MaxVShaderInstructionsExecuted = 65535; /* VS 3.0 needs at least 65535, some cards even use 2^32-1 */
4771 pCaps->MaxVertexShader30InstructionSlots = max(512, adapter->gl_info.limits.arb_vs_instructions);
4773 else if (pCaps->VertexShaderVersion == WINED3DVS_VERSION(2,0))
4775 pCaps->VS20Caps.Caps = 0;
4776 pCaps->VS20Caps.DynamicFlowControlDepth = WINED3DVS20_MIN_DYNAMICFLOWCONTROLDEPTH;
4777 pCaps->VS20Caps.NumTemps = max(12, adapter->gl_info.limits.arb_vs_temps);
4778 pCaps->VS20Caps.StaticFlowControlDepth = 1;
4780 pCaps->MaxVShaderInstructionsExecuted = 65535;
4781 pCaps->MaxVertexShader30InstructionSlots = 0;
4782 } else { /* VS 1.x */
4783 pCaps->VS20Caps.Caps = 0;
4784 pCaps->VS20Caps.DynamicFlowControlDepth = 0;
4785 pCaps->VS20Caps.NumTemps = 0;
4786 pCaps->VS20Caps.StaticFlowControlDepth = 0;
4788 pCaps->MaxVShaderInstructionsExecuted = 0;
4789 pCaps->MaxVertexShader30InstructionSlots = 0;
4792 if(pCaps->PixelShaderVersion == WINED3DPS_VERSION(3,0)) {
4793 /* Where possible set the caps based on OpenGL extensions and if they aren't set (in case of software rendering)
4794 use the PS 3.0 from MSDN or else if there's OpenGL spec use a hardcoded value minimum PS 3.0 value. */
4796 /* 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 */
4797 pCaps->PS20Caps.Caps = WINED3DPS20CAPS_ARBITRARYSWIZZLE |
4798 WINED3DPS20CAPS_GRADIENTINSTRUCTIONS |
4799 WINED3DPS20CAPS_PREDICATION |
4800 WINED3DPS20CAPS_NODEPENDENTREADLIMIT |
4801 WINED3DPS20CAPS_NOTEXINSTRUCTIONLIMIT;
4802 pCaps->PS20Caps.DynamicFlowControlDepth = WINED3DPS20_MAX_DYNAMICFLOWCONTROLDEPTH; /* PS 3.0 requires MAX_DYNAMICFLOWCONTROLDEPTH (24) */
4803 pCaps->PS20Caps.NumTemps = max(32, adapter->gl_info.limits.arb_ps_temps);
4804 pCaps->PS20Caps.StaticFlowControlDepth = WINED3DPS20_MAX_STATICFLOWCONTROLDEPTH; /* PS 3.0 requires MAX_STATICFLOWCONTROLDEPTH (4) */
4805 pCaps->PS20Caps.NumInstructionSlots = WINED3DPS20_MAX_NUMINSTRUCTIONSLOTS; /* PS 3.0 requires MAX_NUMINSTRUCTIONSLOTS (512) */
4807 pCaps->MaxPShaderInstructionsExecuted = 65535;
4808 pCaps->MaxPixelShader30InstructionSlots = max(WINED3DMIN30SHADERINSTRUCTIONS,
4809 adapter->gl_info.limits.arb_ps_instructions);
4811 else if(pCaps->PixelShaderVersion == WINED3DPS_VERSION(2,0))
4813 /* Below we assume PS2.0 specs, not extended 2.0a(GeforceFX)/2.0b(Radeon R3xx) ones */
4814 pCaps->PS20Caps.Caps = 0;
4815 pCaps->PS20Caps.DynamicFlowControlDepth = 0; /* WINED3DVS20_MIN_DYNAMICFLOWCONTROLDEPTH = 0 */
4816 pCaps->PS20Caps.NumTemps = max(12, adapter->gl_info.limits.arb_ps_temps);
4817 pCaps->PS20Caps.StaticFlowControlDepth = WINED3DPS20_MIN_STATICFLOWCONTROLDEPTH; /* Minimum: 1 */
4818 pCaps->PS20Caps.NumInstructionSlots = WINED3DPS20_MIN_NUMINSTRUCTIONSLOTS; /* Minimum number (64 ALU + 32 Texture), a GeforceFX uses 512 */
4820 pCaps->MaxPShaderInstructionsExecuted = 512; /* Minimum value, a GeforceFX uses 1024 */
4821 pCaps->MaxPixelShader30InstructionSlots = 0;
4822 } else { /* PS 1.x */
4823 pCaps->PS20Caps.Caps = 0;
4824 pCaps->PS20Caps.DynamicFlowControlDepth = 0;
4825 pCaps->PS20Caps.NumTemps = 0;
4826 pCaps->PS20Caps.StaticFlowControlDepth = 0;
4827 pCaps->PS20Caps.NumInstructionSlots = 0;
4829 pCaps->MaxPShaderInstructionsExecuted = 0;
4830 pCaps->MaxPixelShader30InstructionSlots = 0;
4833 if(pCaps->VertexShaderVersion >= WINED3DVS_VERSION(2,0)) {
4834 /* OpenGL supports all the formats below, perhaps not always
4835 * without conversion, but it supports them.
4836 * Further GLSL doesn't seem to have an official unsigned type so
4837 * don't advertise it yet as I'm not sure how we handle it.
4838 * We might need to add some clamping in the shader engine to
4840 * TODO: WINED3DDTCAPS_USHORT2N, WINED3DDTCAPS_USHORT4N, WINED3DDTCAPS_UDEC3, WINED3DDTCAPS_DEC3N */
4841 pCaps->DeclTypes = WINED3DDTCAPS_UBYTE4 |
4842 WINED3DDTCAPS_UBYTE4N |
4843 WINED3DDTCAPS_SHORT2N |
4844 WINED3DDTCAPS_SHORT4N;
4845 if (gl_info->supported[ARB_HALF_FLOAT_VERTEX])
4847 pCaps->DeclTypes |= WINED3DDTCAPS_FLOAT16_2 |
4848 WINED3DDTCAPS_FLOAT16_4;
4851 pCaps->DeclTypes = 0;
4853 /* Set DirectDraw helper Caps */
4854 ckey_caps = WINEDDCKEYCAPS_DESTBLT |
4855 WINEDDCKEYCAPS_SRCBLT;
4856 fx_caps = WINEDDFXCAPS_BLTALPHA |
4857 WINEDDFXCAPS_BLTMIRRORLEFTRIGHT |
4858 WINEDDFXCAPS_BLTMIRRORUPDOWN |
4859 WINEDDFXCAPS_BLTROTATION90 |
4860 WINEDDFXCAPS_BLTSHRINKX |
4861 WINEDDFXCAPS_BLTSHRINKXN |
4862 WINEDDFXCAPS_BLTSHRINKY |
4863 WINEDDFXCAPS_BLTSHRINKXN |
4864 WINEDDFXCAPS_BLTSTRETCHX |
4865 WINEDDFXCAPS_BLTSTRETCHXN |
4866 WINEDDFXCAPS_BLTSTRETCHY |
4867 WINEDDFXCAPS_BLTSTRETCHYN;
4868 blit_caps = WINEDDCAPS_BLT |
4869 WINEDDCAPS_BLTCOLORFILL |
4870 WINEDDCAPS_BLTDEPTHFILL |
4871 WINEDDCAPS_BLTSTRETCH |
4872 WINEDDCAPS_CANBLTSYSMEM |
4873 WINEDDCAPS_CANCLIP |
4874 WINEDDCAPS_CANCLIPSTRETCHED |
4875 WINEDDCAPS_COLORKEY |
4876 WINEDDCAPS_COLORKEYHWASSIST |
4877 WINEDDCAPS_ALIGNBOUNDARYSRC;
4878 pal_caps = WINEDDPCAPS_8BIT |
4879 WINEDDPCAPS_PRIMARYSURFACE;
4881 /* Fill the ddraw caps structure */
4882 pCaps->DirectDrawCaps.Caps = WINEDDCAPS_GDI |
4883 WINEDDCAPS_PALETTE |
4885 pCaps->DirectDrawCaps.Caps2 = WINEDDCAPS2_CERTIFIED |
4886 WINEDDCAPS2_NOPAGELOCKREQUIRED |
4887 WINEDDCAPS2_PRIMARYGAMMA |
4888 WINEDDCAPS2_WIDESURFACES |
4889 WINEDDCAPS2_CANRENDERWINDOWED;
4890 pCaps->DirectDrawCaps.CKeyCaps = ckey_caps;
4891 pCaps->DirectDrawCaps.FXCaps = fx_caps;
4892 pCaps->DirectDrawCaps.PalCaps = pal_caps;
4893 pCaps->DirectDrawCaps.SVBCaps = blit_caps;
4894 pCaps->DirectDrawCaps.SVBCKeyCaps = ckey_caps;
4895 pCaps->DirectDrawCaps.SVBFXCaps = fx_caps;
4896 pCaps->DirectDrawCaps.VSBCaps = blit_caps;
4897 pCaps->DirectDrawCaps.VSBCKeyCaps = ckey_caps;
4898 pCaps->DirectDrawCaps.VSBFXCaps = fx_caps;
4899 pCaps->DirectDrawCaps.SSBCaps = blit_caps;
4900 pCaps->DirectDrawCaps.SSBCKeyCaps = ckey_caps;
4901 pCaps->DirectDrawCaps.SSBFXCaps = fx_caps;
4903 pCaps->DirectDrawCaps.ddsCaps = WINEDDSCAPS_ALPHA |
4904 WINEDDSCAPS_BACKBUFFER |
4906 WINEDDSCAPS_FRONTBUFFER |
4907 WINEDDSCAPS_OFFSCREENPLAIN |
4908 WINEDDSCAPS_PALETTE |
4909 WINEDDSCAPS_PRIMARYSURFACE |
4910 WINEDDSCAPS_SYSTEMMEMORY |
4911 WINEDDSCAPS_VIDEOMEMORY |
4912 WINEDDSCAPS_VISIBLE;
4913 pCaps->DirectDrawCaps.StrideAlign = DDRAW_PITCH_ALIGNMENT;
4915 /* Set D3D caps if OpenGL is available. */
4916 if (adapter->opengl)
4918 pCaps->DirectDrawCaps.ddsCaps |=WINEDDSCAPS_3DDEVICE |
4919 WINEDDSCAPS_MIPMAP |
4920 WINEDDSCAPS_TEXTURE |
4921 WINEDDSCAPS_ZBUFFER;
4922 pCaps->DirectDrawCaps.Caps |= WINEDDCAPS_3D;
4928 static HRESULT WINAPI IWineD3DImpl_CreateDevice(IWineD3D *iface, UINT adapter_idx, WINED3DDEVTYPE device_type,
4929 HWND focus_window, DWORD flags, IWineD3DDeviceParent *device_parent, IWineD3DDevice **device)
4931 IWineD3DImpl *This = (IWineD3DImpl *)iface;
4932 IWineD3DDeviceImpl *object;
4935 TRACE("iface %p, adapter_idx %u, device_type %#x, focus_window %p, flags %#x, device_parent %p, device %p.\n",
4936 iface, adapter_idx, device_type, focus_window, flags, device_parent, device);
4938 /* Validate the adapter number. If no adapters are available(no GL), ignore the adapter
4939 * number and create a device without a 3D adapter for 2D only operation. */
4940 if (IWineD3D_GetAdapterCount(iface) && adapter_idx >= IWineD3D_GetAdapterCount(iface))
4942 return WINED3DERR_INVALIDCALL;
4945 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
4948 ERR("Failed to allocate device memory.\n");
4949 return E_OUTOFMEMORY;
4952 hr = device_init(object, This, adapter_idx, device_type, focus_window, flags, device_parent);
4955 WARN("Failed to initialize device, hr %#x.\n", hr);
4956 HeapFree(GetProcessHeap(), 0, object);
4960 TRACE("Created device %p.\n", object);
4961 *device = (IWineD3DDevice *)object;
4963 IWineD3DDeviceParent_WineD3DDeviceCreated(device_parent, *device);
4968 static void * WINAPI IWineD3DImpl_GetParent(IWineD3D *iface)
4970 TRACE("iface %p.\n", iface);
4972 return ((IWineD3DImpl *)iface)->parent;
4975 static void WINE_GLAPI invalid_func(const void *data)
4977 ERR("Invalid vertex attribute function called\n");
4981 static void WINE_GLAPI invalid_texcoord_func(GLenum unit, const void *data)
4983 ERR("Invalid texcoord function called\n");
4987 /* Helper functions for providing vertex data to opengl. The arrays are initialized based on
4988 * the extension detection and are used in drawStridedSlow
4990 static void WINE_GLAPI position_d3dcolor(const void *data)
4992 DWORD pos = *((const DWORD *)data);
4994 FIXME("Add a test for fixed function position from d3dcolor type\n");
4995 glVertex4s(D3DCOLOR_B_R(pos),
5001 static void WINE_GLAPI position_float4(const void *data)
5003 const GLfloat *pos = data;
5005 if (pos[3] != 0.0f && pos[3] != 1.0f)
5007 float w = 1.0f / pos[3];
5009 glVertex4f(pos[0] * w, pos[1] * w, pos[2] * w, w);
5017 static void WINE_GLAPI diffuse_d3dcolor(const void *data)
5019 DWORD diffuseColor = *((const DWORD *)data);
5021 glColor4ub(D3DCOLOR_B_R(diffuseColor),
5022 D3DCOLOR_B_G(diffuseColor),
5023 D3DCOLOR_B_B(diffuseColor),
5024 D3DCOLOR_B_A(diffuseColor));
5027 static void WINE_GLAPI specular_d3dcolor(const void *data)
5029 DWORD specularColor = *((const DWORD *)data);
5030 GLbyte d[] = {D3DCOLOR_B_R(specularColor),
5031 D3DCOLOR_B_G(specularColor),
5032 D3DCOLOR_B_B(specularColor)};
5034 specular_func_3ubv(d);
5037 static void WINE_GLAPI warn_no_specular_func(const void *data)
5039 WARN("GL_EXT_secondary_color not supported\n");
5042 static void fillGLAttribFuncs(const struct wined3d_gl_info *gl_info)
5044 position_funcs[WINED3D_FFP_EMIT_FLOAT1] = invalid_func;
5045 position_funcs[WINED3D_FFP_EMIT_FLOAT2] = invalid_func;
5046 position_funcs[WINED3D_FFP_EMIT_FLOAT3] = (glAttribFunc)glVertex3fv;
5047 position_funcs[WINED3D_FFP_EMIT_FLOAT4] = position_float4;
5048 position_funcs[WINED3D_FFP_EMIT_D3DCOLOR] = position_d3dcolor;
5049 position_funcs[WINED3D_FFP_EMIT_UBYTE4] = invalid_func;
5050 position_funcs[WINED3D_FFP_EMIT_SHORT2] = invalid_func;
5051 position_funcs[WINED3D_FFP_EMIT_SHORT4] = (glAttribFunc)glVertex2sv;
5052 position_funcs[WINED3D_FFP_EMIT_UBYTE4N] = invalid_func;
5053 position_funcs[WINED3D_FFP_EMIT_SHORT2N] = invalid_func;
5054 position_funcs[WINED3D_FFP_EMIT_SHORT4N] = invalid_func;
5055 position_funcs[WINED3D_FFP_EMIT_USHORT2N] = invalid_func;
5056 position_funcs[WINED3D_FFP_EMIT_USHORT4N] = invalid_func;
5057 position_funcs[WINED3D_FFP_EMIT_UDEC3] = invalid_func;
5058 position_funcs[WINED3D_FFP_EMIT_DEC3N] = invalid_func;
5059 position_funcs[WINED3D_FFP_EMIT_FLOAT16_2] = invalid_func;
5060 position_funcs[WINED3D_FFP_EMIT_FLOAT16_4] = invalid_func;
5062 diffuse_funcs[WINED3D_FFP_EMIT_FLOAT1] = invalid_func;
5063 diffuse_funcs[WINED3D_FFP_EMIT_FLOAT2] = invalid_func;
5064 diffuse_funcs[WINED3D_FFP_EMIT_FLOAT3] = (glAttribFunc)glColor3fv;
5065 diffuse_funcs[WINED3D_FFP_EMIT_FLOAT4] = (glAttribFunc)glColor4fv;
5066 diffuse_funcs[WINED3D_FFP_EMIT_D3DCOLOR] = diffuse_d3dcolor;
5067 diffuse_funcs[WINED3D_FFP_EMIT_UBYTE4] = invalid_func;
5068 diffuse_funcs[WINED3D_FFP_EMIT_SHORT2] = invalid_func;
5069 diffuse_funcs[WINED3D_FFP_EMIT_SHORT4] = invalid_func;
5070 diffuse_funcs[WINED3D_FFP_EMIT_UBYTE4N] = (glAttribFunc)glColor4ubv;
5071 diffuse_funcs[WINED3D_FFP_EMIT_SHORT2N] = invalid_func;
5072 diffuse_funcs[WINED3D_FFP_EMIT_SHORT4N] = (glAttribFunc)glColor4sv;
5073 diffuse_funcs[WINED3D_FFP_EMIT_USHORT2N] = invalid_func;
5074 diffuse_funcs[WINED3D_FFP_EMIT_USHORT4N] = (glAttribFunc)glColor4usv;
5075 diffuse_funcs[WINED3D_FFP_EMIT_UDEC3] = invalid_func;
5076 diffuse_funcs[WINED3D_FFP_EMIT_DEC3N] = invalid_func;
5077 diffuse_funcs[WINED3D_FFP_EMIT_FLOAT16_2] = invalid_func;
5078 diffuse_funcs[WINED3D_FFP_EMIT_FLOAT16_4] = invalid_func;
5080 /* No 4 component entry points here */
5081 specular_funcs[WINED3D_FFP_EMIT_FLOAT1] = invalid_func;
5082 specular_funcs[WINED3D_FFP_EMIT_FLOAT2] = invalid_func;
5083 if (gl_info->supported[EXT_SECONDARY_COLOR])
5085 specular_funcs[WINED3D_FFP_EMIT_FLOAT3] = (glAttribFunc)GL_EXTCALL(glSecondaryColor3fvEXT);
5089 specular_funcs[WINED3D_FFP_EMIT_FLOAT3] = warn_no_specular_func;
5091 specular_funcs[WINED3D_FFP_EMIT_FLOAT4] = invalid_func;
5092 if (gl_info->supported[EXT_SECONDARY_COLOR])
5094 specular_func_3ubv = (glAttribFunc)GL_EXTCALL(glSecondaryColor3ubvEXT);
5095 specular_funcs[WINED3D_FFP_EMIT_D3DCOLOR] = specular_d3dcolor;
5099 specular_funcs[WINED3D_FFP_EMIT_D3DCOLOR] = warn_no_specular_func;
5101 specular_funcs[WINED3D_FFP_EMIT_UBYTE4] = invalid_func;
5102 specular_funcs[WINED3D_FFP_EMIT_SHORT2] = invalid_func;
5103 specular_funcs[WINED3D_FFP_EMIT_SHORT4] = invalid_func;
5104 specular_funcs[WINED3D_FFP_EMIT_UBYTE4N] = invalid_func;
5105 specular_funcs[WINED3D_FFP_EMIT_SHORT2N] = invalid_func;
5106 specular_funcs[WINED3D_FFP_EMIT_SHORT4N] = invalid_func;
5107 specular_funcs[WINED3D_FFP_EMIT_USHORT2N] = invalid_func;
5108 specular_funcs[WINED3D_FFP_EMIT_USHORT4N] = invalid_func;
5109 specular_funcs[WINED3D_FFP_EMIT_UDEC3] = invalid_func;
5110 specular_funcs[WINED3D_FFP_EMIT_DEC3N] = invalid_func;
5111 specular_funcs[WINED3D_FFP_EMIT_FLOAT16_2] = invalid_func;
5112 specular_funcs[WINED3D_FFP_EMIT_FLOAT16_4] = invalid_func;
5114 /* Only 3 component entry points here. Test how others behave. Float4 normals are used
5115 * by one of our tests, trying to pass it to the pixel shader, which fails on Windows.
5117 normal_funcs[WINED3D_FFP_EMIT_FLOAT1] = invalid_func;
5118 normal_funcs[WINED3D_FFP_EMIT_FLOAT2] = invalid_func;
5119 normal_funcs[WINED3D_FFP_EMIT_FLOAT3] = (glAttribFunc)glNormal3fv;
5120 normal_funcs[WINED3D_FFP_EMIT_FLOAT4] = (glAttribFunc)glNormal3fv; /* Just ignore the 4th value */
5121 normal_funcs[WINED3D_FFP_EMIT_D3DCOLOR] = invalid_func;
5122 normal_funcs[WINED3D_FFP_EMIT_UBYTE4] = invalid_func;
5123 normal_funcs[WINED3D_FFP_EMIT_SHORT2] = invalid_func;
5124 normal_funcs[WINED3D_FFP_EMIT_SHORT4] = invalid_func;
5125 normal_funcs[WINED3D_FFP_EMIT_UBYTE4N] = invalid_func;
5126 normal_funcs[WINED3D_FFP_EMIT_SHORT2N] = invalid_func;
5127 normal_funcs[WINED3D_FFP_EMIT_SHORT4N] = invalid_func;
5128 normal_funcs[WINED3D_FFP_EMIT_USHORT2N] = invalid_func;
5129 normal_funcs[WINED3D_FFP_EMIT_USHORT4N] = invalid_func;
5130 normal_funcs[WINED3D_FFP_EMIT_UDEC3] = invalid_func;
5131 normal_funcs[WINED3D_FFP_EMIT_DEC3N] = invalid_func;
5132 normal_funcs[WINED3D_FFP_EMIT_FLOAT16_2] = invalid_func;
5133 normal_funcs[WINED3D_FFP_EMIT_FLOAT16_4] = invalid_func;
5135 multi_texcoord_funcs[WINED3D_FFP_EMIT_FLOAT1] = (glMultiTexCoordFunc)GL_EXTCALL(glMultiTexCoord1fvARB);
5136 multi_texcoord_funcs[WINED3D_FFP_EMIT_FLOAT2] = (glMultiTexCoordFunc)GL_EXTCALL(glMultiTexCoord2fvARB);
5137 multi_texcoord_funcs[WINED3D_FFP_EMIT_FLOAT3] = (glMultiTexCoordFunc)GL_EXTCALL(glMultiTexCoord3fvARB);
5138 multi_texcoord_funcs[WINED3D_FFP_EMIT_FLOAT4] = (glMultiTexCoordFunc)GL_EXTCALL(glMultiTexCoord4fvARB);
5139 multi_texcoord_funcs[WINED3D_FFP_EMIT_D3DCOLOR] = invalid_texcoord_func;
5140 multi_texcoord_funcs[WINED3D_FFP_EMIT_UBYTE4] = invalid_texcoord_func;
5141 multi_texcoord_funcs[WINED3D_FFP_EMIT_SHORT2] = (glMultiTexCoordFunc)GL_EXTCALL(glMultiTexCoord2svARB);
5142 multi_texcoord_funcs[WINED3D_FFP_EMIT_SHORT4] = (glMultiTexCoordFunc)GL_EXTCALL(glMultiTexCoord4svARB);
5143 multi_texcoord_funcs[WINED3D_FFP_EMIT_UBYTE4N] = invalid_texcoord_func;
5144 multi_texcoord_funcs[WINED3D_FFP_EMIT_SHORT2N] = invalid_texcoord_func;
5145 multi_texcoord_funcs[WINED3D_FFP_EMIT_SHORT4N] = invalid_texcoord_func;
5146 multi_texcoord_funcs[WINED3D_FFP_EMIT_USHORT2N] = invalid_texcoord_func;
5147 multi_texcoord_funcs[WINED3D_FFP_EMIT_USHORT4N] = invalid_texcoord_func;
5148 multi_texcoord_funcs[WINED3D_FFP_EMIT_UDEC3] = invalid_texcoord_func;
5149 multi_texcoord_funcs[WINED3D_FFP_EMIT_DEC3N] = invalid_texcoord_func;
5150 if (gl_info->supported[NV_HALF_FLOAT])
5152 /* Not supported by ARB_HALF_FLOAT_VERTEX, so check for NV_HALF_FLOAT */
5153 multi_texcoord_funcs[WINED3D_FFP_EMIT_FLOAT16_2] = (glMultiTexCoordFunc)GL_EXTCALL(glMultiTexCoord2hvNV);
5154 multi_texcoord_funcs[WINED3D_FFP_EMIT_FLOAT16_4] = (glMultiTexCoordFunc)GL_EXTCALL(glMultiTexCoord4hvNV);
5156 multi_texcoord_funcs[WINED3D_FFP_EMIT_FLOAT16_2] = invalid_texcoord_func;
5157 multi_texcoord_funcs[WINED3D_FFP_EMIT_FLOAT16_4] = invalid_texcoord_func;
5161 /* Do not call while under the GL lock. */
5162 static BOOL InitAdapters(IWineD3DImpl *This)
5164 static HMODULE mod_gl;
5166 int ps_selected_mode, vs_selected_mode;
5168 /* No need to hold any lock. The calling library makes sure only one thread calls
5169 * wined3d simultaneously
5172 TRACE("Initializing adapters\n");
5175 #ifdef USE_WIN32_OPENGL
5176 #define USE_GL_FUNC(pfn) pfn = (void*)GetProcAddress(mod_gl, #pfn);
5177 mod_gl = LoadLibraryA("opengl32.dll");
5179 ERR("Can't load opengl32.dll!\n");
5183 #define USE_GL_FUNC(pfn) pfn = (void*)pwglGetProcAddress(#pfn);
5184 /* To bypass the opengl32 thunks load wglGetProcAddress from gdi32 (glXGetProcAddress wrapper) instead of opengl32's */
5185 mod_gl = GetModuleHandleA("gdi32.dll");
5189 /* Load WGL core functions from opengl32.dll */
5190 #define USE_WGL_FUNC(pfn) p##pfn = (void*)GetProcAddress(mod_gl, #pfn);
5194 if(!pwglGetProcAddress) {
5195 ERR("Unable to load wglGetProcAddress!\n");
5199 /* Dynamically load all GL core functions */
5203 /* Load glFinish and glFlush from opengl32.dll even if we're not using WIN32 opengl
5204 * otherwise because we have to use winex11.drv's override
5206 #ifdef USE_WIN32_OPENGL
5207 wglFinish = (void*)GetProcAddress(mod_gl, "glFinish");
5208 wglFlush = (void*)GetProcAddress(mod_gl, "glFlush");
5210 wglFinish = (void*)pwglGetProcAddress("wglFinish");
5211 wglFlush = (void*)pwglGetProcAddress("wglFlush");
5214 glEnableWINE = glEnable;
5215 glDisableWINE = glDisable;
5217 /* For now only one default adapter */
5219 struct wined3d_adapter *adapter = &This->adapters[0];
5220 const struct wined3d_gl_info *gl_info = &adapter->gl_info;
5221 struct wined3d_fake_gl_ctx fake_gl_ctx = {0};
5225 WineD3D_PixelFormat *cfgs;
5226 DISPLAY_DEVICEW DisplayDevice;
5229 TRACE("Initializing default adapter\n");
5230 adapter->ordinal = 0;
5231 adapter->monitorPoint.x = -1;
5232 adapter->monitorPoint.y = -1;
5234 if (!AllocateLocallyUniqueId(&adapter->luid))
5236 DWORD err = GetLastError();
5237 ERR("Failed to set adapter LUID (%#x).\n", err);
5240 TRACE("Allocated LUID %08x:%08x for adapter.\n",
5241 adapter->luid.HighPart, adapter->luid.LowPart);
5243 if (!WineD3D_CreateFakeGLContext(&fake_gl_ctx))
5245 ERR("Failed to get a gl context for default adapter\n");
5249 ret = IWineD3DImpl_FillGLCaps(adapter);
5251 ERR("Failed to initialize gl caps for default adapter\n");
5252 WineD3D_ReleaseFakeGLContext(&fake_gl_ctx);
5255 ret = initPixelFormats(&adapter->gl_info, adapter->driver_info.vendor);
5257 ERR("Failed to init gl formats\n");
5258 WineD3D_ReleaseFakeGLContext(&fake_gl_ctx);
5262 hdc = fake_gl_ctx.dc;
5264 adapter->TextureRam = adapter->driver_info.vidmem;
5265 adapter->UsedTextureRam = 0;
5266 TRACE("Emulating %dMB of texture ram\n", adapter->TextureRam/(1024*1024));
5268 /* Initialize the Adapter's DeviceName which is required for ChangeDisplaySettings and friends */
5269 DisplayDevice.cb = sizeof(DisplayDevice);
5270 EnumDisplayDevicesW(NULL, 0 /* Adapter 0 = iDevNum 0 */, &DisplayDevice, 0);
5271 TRACE("DeviceName: %s\n", debugstr_w(DisplayDevice.DeviceName));
5272 strcpyW(adapter->DeviceName, DisplayDevice.DeviceName);
5274 if (gl_info->supported[WGL_ARB_PIXEL_FORMAT])
5281 attribute = WGL_NUMBER_PIXEL_FORMATS_ARB;
5282 GL_EXTCALL(wglGetPixelFormatAttribivARB(hdc, 0, 0, 1, &attribute, &adapter->nCfgs));
5284 adapter->cfgs = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, adapter->nCfgs *sizeof(WineD3D_PixelFormat));
5285 cfgs = adapter->cfgs;
5286 attribs[nAttribs++] = WGL_RED_BITS_ARB;
5287 attribs[nAttribs++] = WGL_GREEN_BITS_ARB;
5288 attribs[nAttribs++] = WGL_BLUE_BITS_ARB;
5289 attribs[nAttribs++] = WGL_ALPHA_BITS_ARB;
5290 attribs[nAttribs++] = WGL_COLOR_BITS_ARB;
5291 attribs[nAttribs++] = WGL_DEPTH_BITS_ARB;
5292 attribs[nAttribs++] = WGL_STENCIL_BITS_ARB;
5293 attribs[nAttribs++] = WGL_DRAW_TO_WINDOW_ARB;
5294 attribs[nAttribs++] = WGL_PIXEL_TYPE_ARB;
5295 attribs[nAttribs++] = WGL_DOUBLE_BUFFER_ARB;
5296 attribs[nAttribs++] = WGL_AUX_BUFFERS_ARB;
5298 for (iPixelFormat=1; iPixelFormat <= adapter->nCfgs; ++iPixelFormat)
5300 res = GL_EXTCALL(wglGetPixelFormatAttribivARB(hdc, iPixelFormat, 0, nAttribs, attribs, values));
5305 /* Cache the pixel format */
5306 cfgs->iPixelFormat = iPixelFormat;
5307 cfgs->redSize = values[0];
5308 cfgs->greenSize = values[1];
5309 cfgs->blueSize = values[2];
5310 cfgs->alphaSize = values[3];
5311 cfgs->colorSize = values[4];
5312 cfgs->depthSize = values[5];
5313 cfgs->stencilSize = values[6];
5314 cfgs->windowDrawable = values[7];
5315 cfgs->iPixelType = values[8];
5316 cfgs->doubleBuffer = values[9];
5317 cfgs->auxBuffers = values[10];
5319 cfgs->numSamples = 0;
5320 /* Check multisample support */
5321 if (gl_info->supported[ARB_MULTISAMPLE])
5323 int attrib[2] = {WGL_SAMPLE_BUFFERS_ARB, WGL_SAMPLES_ARB};
5325 if(GL_EXTCALL(wglGetPixelFormatAttribivARB(hdc, iPixelFormat, 0, 2, attrib, value))) {
5326 /* value[0] = WGL_SAMPLE_BUFFERS_ARB which tells whether multisampling is supported.
5327 * value[1] = number of multi sample buffers*/
5329 cfgs->numSamples = value[1];
5333 TRACE("iPixelFormat=%d, iPixelType=%#x, doubleBuffer=%d, RGBA=%d/%d/%d/%d, "
5334 "depth=%d, stencil=%d, samples=%d, windowDrawable=%d\n",
5335 cfgs->iPixelFormat, cfgs->iPixelType, cfgs->doubleBuffer,
5336 cfgs->redSize, cfgs->greenSize, cfgs->blueSize, cfgs->alphaSize,
5337 cfgs->depthSize, cfgs->stencilSize, cfgs->numSamples, cfgs->windowDrawable);
5343 int nCfgs = DescribePixelFormat(hdc, 0, 0, 0);
5344 adapter->cfgs = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, nCfgs*sizeof(WineD3D_PixelFormat));
5345 adapter->nCfgs = 0; /* We won't accept all formats e.g. software accelerated ones will be skipped */
5347 cfgs = adapter->cfgs;
5348 for(iPixelFormat=1; iPixelFormat<=nCfgs; iPixelFormat++)
5350 PIXELFORMATDESCRIPTOR ppfd;
5352 res = DescribePixelFormat(hdc, iPixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &ppfd);
5356 /* We only want HW acceleration using an OpenGL ICD driver.
5357 * PFD_GENERIC_FORMAT = slow opengl 1.1 gdi software rendering
5358 * PFD_GENERIC_ACCELERATED = partial hw acceleration using a MCD driver (e.g. 3dfx minigl)
5360 if(ppfd.dwFlags & (PFD_GENERIC_FORMAT | PFD_GENERIC_ACCELERATED))
5362 TRACE("Skipping iPixelFormat=%d because it isn't ICD accelerated\n", iPixelFormat);
5366 cfgs->iPixelFormat = iPixelFormat;
5367 cfgs->redSize = ppfd.cRedBits;
5368 cfgs->greenSize = ppfd.cGreenBits;
5369 cfgs->blueSize = ppfd.cBlueBits;
5370 cfgs->alphaSize = ppfd.cAlphaBits;
5371 cfgs->colorSize = ppfd.cColorBits;
5372 cfgs->depthSize = ppfd.cDepthBits;
5373 cfgs->stencilSize = ppfd.cStencilBits;
5374 cfgs->windowDrawable = (ppfd.dwFlags & PFD_DRAW_TO_WINDOW) ? 1 : 0;
5375 cfgs->iPixelType = (ppfd.iPixelType == PFD_TYPE_RGBA) ? WGL_TYPE_RGBA_ARB : WGL_TYPE_COLORINDEX_ARB;
5376 cfgs->doubleBuffer = (ppfd.dwFlags & PFD_DOUBLEBUFFER) ? 1 : 0;
5377 cfgs->auxBuffers = ppfd.cAuxBuffers;
5378 cfgs->numSamples = 0;
5380 TRACE("iPixelFormat=%d, iPixelType=%#x, doubleBuffer=%d, RGBA=%d/%d/%d/%d, "
5381 "depth=%d, stencil=%d, windowDrawable=%d\n",
5382 cfgs->iPixelFormat, cfgs->iPixelType, cfgs->doubleBuffer,
5383 cfgs->redSize, cfgs->greenSize, cfgs->blueSize, cfgs->alphaSize,
5384 cfgs->depthSize, cfgs->stencilSize, cfgs->windowDrawable);
5389 /* Yikes we haven't found any suitable formats. This should only happen in case of GDI software rendering which we can't use anyway as its 3D functionality is very, very limited */
5392 ERR("Disabling Direct3D because no hardware accelerated pixel formats have been found!\n");
5394 WineD3D_ReleaseFakeGLContext(&fake_gl_ctx);
5395 HeapFree(GetProcessHeap(), 0, adapter->cfgs);
5400 /* D16, D24X8 and D24S8 are common depth / depth+stencil formats. All drivers support them though this doesn't
5401 * mean that the format is offered in hardware. For instance Geforce8 cards don't have offer D16 in hardware
5402 * but just fake it using D24(X8?) which is fine. D3D also allows that.
5403 * Some display drivers (i915 on Linux) only report mixed depth+stencil formats like D24S8. MSDN clearly mentions
5404 * that only on lockable formats (e.g. D16_locked) the bit order is guaranteed and that on other formats the
5405 * driver is allowed to consume more bits EXCEPT for stencil bits.
5407 * Mark an adapter with this broken stencil behavior.
5409 adapter->brokenStencil = TRUE;
5410 for (i = 0, cfgs = adapter->cfgs; i < adapter->nCfgs; ++i)
5412 /* Nearly all drivers offer depth formats without stencil, only on i915 this if-statement won't be entered. */
5413 if(cfgs[i].depthSize && !cfgs[i].stencilSize) {
5414 adapter->brokenStencil = FALSE;
5419 WineD3D_ReleaseFakeGLContext(&fake_gl_ctx);
5421 select_shader_mode(&adapter->gl_info, &ps_selected_mode, &vs_selected_mode);
5422 fillGLAttribFuncs(&adapter->gl_info);
5423 adapter->opengl = TRUE;
5425 This->adapter_count = 1;
5426 TRACE("%u adapters successfully initialized\n", This->adapter_count);
5431 /* Initialize an adapter for ddraw-only memory counting */
5432 memset(This->adapters, 0, sizeof(This->adapters));
5433 This->adapters[0].ordinal = 0;
5434 This->adapters[0].opengl = FALSE;
5435 This->adapters[0].monitorPoint.x = -1;
5436 This->adapters[0].monitorPoint.y = -1;
5438 This->adapters[0].driver_info.name = "Display";
5439 This->adapters[0].driver_info.description = "WineD3D DirectDraw Emulation";
5440 if(wined3d_settings.emulated_textureram) {
5441 This->adapters[0].TextureRam = wined3d_settings.emulated_textureram;
5443 This->adapters[0].TextureRam = 8 * 1024 * 1024; /* This is plenty for a DDraw-only card */
5446 initPixelFormatsNoGL(&This->adapters[0].gl_info);
5448 This->adapter_count = 1;
5452 /**********************************************************
5453 * IWineD3D VTbl follows
5454 **********************************************************/
5456 static const struct IWineD3DVtbl IWineD3D_Vtbl =
5459 IWineD3DImpl_QueryInterface,
5460 IWineD3DImpl_AddRef,
5461 IWineD3DImpl_Release,
5463 IWineD3DImpl_GetParent,
5464 IWineD3DImpl_GetAdapterCount,
5465 IWineD3DImpl_RegisterSoftwareDevice,
5466 IWineD3DImpl_GetAdapterMonitor,
5467 IWineD3DImpl_GetAdapterModeCount,
5468 IWineD3DImpl_EnumAdapterModes,
5469 IWineD3DImpl_GetAdapterDisplayMode,
5470 IWineD3DImpl_GetAdapterIdentifier,
5471 IWineD3DImpl_CheckDeviceMultiSampleType,
5472 IWineD3DImpl_CheckDepthStencilMatch,
5473 IWineD3DImpl_CheckDeviceType,
5474 IWineD3DImpl_CheckDeviceFormat,
5475 IWineD3DImpl_CheckDeviceFormatConversion,
5476 IWineD3DImpl_GetDeviceCaps,
5477 IWineD3DImpl_CreateDevice
5480 static void STDMETHODCALLTYPE wined3d_null_wined3d_object_destroyed(void *parent) {}
5482 const struct wined3d_parent_ops wined3d_null_parent_ops =
5484 wined3d_null_wined3d_object_destroyed,
5487 /* Do not call while under the GL lock. */
5488 HRESULT wined3d_init(IWineD3DImpl *wined3d, UINT version, void *parent)
5490 wined3d->lpVtbl = &IWineD3D_Vtbl;
5491 wined3d->dxVersion = version;
5493 wined3d->parent = parent;
5495 if (!InitAdapters(wined3d))
5497 WARN("Failed to initialize adapters.\n");
5500 MESSAGE("Direct3D%u is not available without OpenGL.\n", version);