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_cube_map", ARB_TEXTURE_CUBE_MAP, 0 },
81 {"GL_ARB_texture_env_add", ARB_TEXTURE_ENV_ADD, 0 },
82 {"GL_ARB_texture_env_combine", ARB_TEXTURE_ENV_COMBINE, 0 },
83 {"GL_ARB_texture_env_dot3", ARB_TEXTURE_ENV_DOT3, 0 },
84 {"GL_ARB_texture_float", ARB_TEXTURE_FLOAT, 0 },
85 {"GL_ARB_texture_mirrored_repeat", ARB_TEXTURE_MIRRORED_REPEAT, 0 },
86 {"GL_ARB_texture_non_power_of_two", ARB_TEXTURE_NON_POWER_OF_TWO, MAKEDWORD_VERSION(2, 0) },
87 {"GL_ARB_texture_rectangle", ARB_TEXTURE_RECTANGLE, 0 },
88 {"GL_ARB_texture_rg", ARB_TEXTURE_RG, 0 },
89 {"GL_ARB_vertex_array_bgra", ARB_VERTEX_ARRAY_BGRA, 0 },
90 {"GL_ARB_vertex_blend", ARB_VERTEX_BLEND, 0 },
91 {"GL_ARB_vertex_buffer_object", ARB_VERTEX_BUFFER_OBJECT, 0 },
92 {"GL_ARB_vertex_program", ARB_VERTEX_PROGRAM, 0 },
93 {"GL_ARB_vertex_shader", ARB_VERTEX_SHADER, 0 },
96 {"GL_ATI_fragment_shader", ATI_FRAGMENT_SHADER, 0 },
97 {"GL_ATI_separate_stencil", ATI_SEPARATE_STENCIL, 0 },
98 {"GL_ATI_texture_compression_3dc", ATI_TEXTURE_COMPRESSION_3DC, 0 },
99 {"GL_ATI_texture_env_combine3", ATI_TEXTURE_ENV_COMBINE3, 0 },
100 {"GL_ATI_texture_mirror_once", ATI_TEXTURE_MIRROR_ONCE, 0 },
103 {"GL_EXT_blend_color", EXT_BLEND_COLOR, 0 },
104 {"GL_EXT_blend_equation_separate", EXT_BLEND_EQUATION_SEPARATE, 0 },
105 {"GL_EXT_blend_func_separate", EXT_BLEND_FUNC_SEPARATE, 0 },
106 {"GL_EXT_blend_minmax", EXT_BLEND_MINMAX, 0 },
107 {"GL_EXT_draw_buffers2", EXT_DRAW_BUFFERS2, 0 },
108 {"GL_EXT_fog_coord", EXT_FOG_COORD, 0 },
109 {"GL_EXT_framebuffer_blit", EXT_FRAMEBUFFER_BLIT, 0 },
110 {"GL_EXT_framebuffer_multisample", EXT_FRAMEBUFFER_MULTISAMPLE, 0 },
111 {"GL_EXT_framebuffer_object", EXT_FRAMEBUFFER_OBJECT, 0 },
112 {"GL_EXT_gpu_program_parameters", EXT_GPU_PROGRAM_PARAMETERS, 0 },
113 {"GL_EXT_gpu_shader4", EXT_GPU_SHADER4, 0 },
114 {"GL_EXT_packed_depth_stencil", EXT_PACKED_DEPTH_STENCIL, 0 },
115 {"GL_EXT_paletted_texture", EXT_PALETTED_TEXTURE, 0 },
116 {"GL_EXT_point_parameters", EXT_POINT_PARAMETERS, 0 },
117 {"GL_EXT_provoking_vertex", EXT_PROVOKING_VERTEX, 0 },
118 {"GL_EXT_secondary_color", EXT_SECONDARY_COLOR, 0 },
119 {"GL_EXT_stencil_two_side", EXT_STENCIL_TWO_SIDE, 0 },
120 {"GL_EXT_stencil_wrap", EXT_STENCIL_WRAP, 0 },
121 {"GL_EXT_texture3D", EXT_TEXTURE3D, MAKEDWORD_VERSION(1, 2) },
122 {"GL_EXT_texture_compression_rgtc", EXT_TEXTURE_COMPRESSION_RGTC, 0 },
123 {"GL_EXT_texture_compression_s3tc", EXT_TEXTURE_COMPRESSION_S3TC, 0 },
124 {"GL_EXT_texture_env_add", EXT_TEXTURE_ENV_ADD, 0 },
125 {"GL_EXT_texture_env_combine", EXT_TEXTURE_ENV_COMBINE, 0 },
126 {"GL_EXT_texture_env_dot3", EXT_TEXTURE_ENV_DOT3, 0 },
127 {"GL_EXT_texture_filter_anisotropic", EXT_TEXTURE_FILTER_ANISOTROPIC, 0 },
128 {"GL_EXT_texture_lod_bias", EXT_TEXTURE_LOD_BIAS, 0 },
129 {"GL_EXT_texture_sRGB", EXT_TEXTURE_SRGB, 0 },
130 {"GL_EXT_vertex_array_bgra", EXT_VERTEX_ARRAY_BGRA, 0 },
133 {"GL_NV_depth_clamp", NV_DEPTH_CLAMP, 0 },
134 {"GL_NV_fence", NV_FENCE, 0 },
135 {"GL_NV_fog_distance", NV_FOG_DISTANCE, 0 },
136 {"GL_NV_fragment_program", NV_FRAGMENT_PROGRAM, 0 },
137 {"GL_NV_fragment_program2", NV_FRAGMENT_PROGRAM2, 0 },
138 {"GL_NV_fragment_program_option", NV_FRAGMENT_PROGRAM_OPTION, 0 },
139 {"GL_NV_half_float", NV_HALF_FLOAT, 0 },
140 {"GL_NV_light_max_exponent", NV_LIGHT_MAX_EXPONENT, 0 },
141 {"GL_NV_register_combiners", NV_REGISTER_COMBINERS, 0 },
142 {"GL_NV_register_combiners2", NV_REGISTER_COMBINERS2, 0 },
143 {"GL_NV_texgen_reflection", NV_TEXGEN_REFLECTION, 0 },
144 {"GL_NV_texture_env_combine4", NV_TEXTURE_ENV_COMBINE4, 0 },
145 {"GL_NV_texture_shader", NV_TEXTURE_SHADER, 0 },
146 {"GL_NV_texture_shader2", NV_TEXTURE_SHADER2, 0 },
147 {"GL_NV_vertex_program", NV_VERTEX_PROGRAM, 0 },
148 {"GL_NV_vertex_program1_1", NV_VERTEX_PROGRAM1_1, 0 },
149 {"GL_NV_vertex_program2", NV_VERTEX_PROGRAM2, 0 },
150 {"GL_NV_vertex_program2_option", NV_VERTEX_PROGRAM2_OPTION, 0 },
151 {"GL_NV_vertex_program3", NV_VERTEX_PROGRAM3, 0 },
154 {"GL_SGIS_generate_mipmap", SGIS_GENERATE_MIPMAP, 0 },
157 /**********************************************************
158 * Utility functions follow
159 **********************************************************/
161 static HRESULT WINAPI IWineD3DImpl_CheckDeviceFormat(IWineD3D *iface, UINT Adapter, WINED3DDEVTYPE DeviceType, WINED3DFORMAT AdapterFormat, DWORD Usage, WINED3DRESOURCETYPE RType, WINED3DFORMAT CheckFormat, WINED3DSURFTYPE SurfaceType);
163 const struct min_lookup minMipLookup[] =
165 /* NONE POINT LINEAR */
166 {{GL_NEAREST, GL_NEAREST, GL_NEAREST}}, /* NONE */
167 {{GL_NEAREST, GL_NEAREST_MIPMAP_NEAREST, GL_NEAREST_MIPMAP_LINEAR}}, /* POINT*/
168 {{GL_LINEAR, GL_LINEAR_MIPMAP_NEAREST, GL_LINEAR_MIPMAP_LINEAR}}, /* LINEAR */
171 const struct min_lookup minMipLookup_noFilter[] =
173 /* NONE POINT LINEAR */
174 {{GL_NEAREST, GL_NEAREST, GL_NEAREST}}, /* NONE */
175 {{GL_NEAREST, GL_NEAREST, GL_NEAREST}}, /* POINT */
176 {{GL_NEAREST, GL_NEAREST, GL_NEAREST}}, /* LINEAR */
179 const struct min_lookup minMipLookup_noMip[] =
181 /* NONE POINT LINEAR */
182 {{GL_NEAREST, GL_NEAREST, GL_NEAREST}}, /* NONE */
183 {{GL_NEAREST, GL_NEAREST, GL_NEAREST}}, /* POINT */
184 {{GL_LINEAR, GL_LINEAR, GL_LINEAR }}, /* LINEAR */
187 const GLenum magLookup[] =
189 /* NONE POINT LINEAR */
190 GL_NEAREST, GL_NEAREST, GL_LINEAR,
193 const GLenum magLookup_noFilter[] =
195 /* NONE POINT LINEAR */
196 GL_NEAREST, GL_NEAREST, GL_NEAREST,
199 /* drawStridedSlow attributes */
200 glAttribFunc position_funcs[WINED3D_FFP_EMIT_COUNT];
201 glAttribFunc diffuse_funcs[WINED3D_FFP_EMIT_COUNT];
202 glAttribFunc specular_func_3ubv;
203 glAttribFunc specular_funcs[WINED3D_FFP_EMIT_COUNT];
204 glAttribFunc normal_funcs[WINED3D_FFP_EMIT_COUNT];
205 glMultiTexCoordFunc multi_texcoord_funcs[WINED3D_FFP_EMIT_COUNT];
208 * Note: GL seems to trap if GetDeviceCaps is called before any HWND's created,
209 * i.e., there is no GL Context - Get a default rendering context to enable the
210 * function query some info from GL.
213 struct wined3d_fake_gl_ctx
219 HGLRC restore_gl_ctx;
222 static void WineD3D_ReleaseFakeGLContext(struct wined3d_fake_gl_ctx *ctx)
224 TRACE_(d3d_caps)("Destroying fake GL context.\n");
226 if (!pwglMakeCurrent(NULL, NULL))
228 ERR_(d3d_caps)("Failed to disable fake GL context.\n");
231 if (!pwglDeleteContext(ctx->gl_ctx))
233 DWORD err = GetLastError();
234 ERR("wglDeleteContext(%p) failed, last error %#x.\n", ctx->gl_ctx, err);
237 ReleaseDC(ctx->wnd, ctx->dc);
238 DestroyWindow(ctx->wnd);
240 if (ctx->restore_gl_ctx && !pwglMakeCurrent(ctx->restore_dc, ctx->restore_gl_ctx))
242 ERR_(d3d_caps)("Failed to restore previous GL context.\n");
246 static BOOL WineD3D_CreateFakeGLContext(struct wined3d_fake_gl_ctx *ctx)
248 PIXELFORMATDESCRIPTOR pfd;
251 TRACE("getting context...\n");
253 ctx->restore_dc = pwglGetCurrentDC();
254 ctx->restore_gl_ctx = pwglGetCurrentContext();
256 /* We need a fake window as a hdc retrieved using GetDC(0) can't be used for much GL purposes. */
257 ctx->wnd = CreateWindowA(WINED3D_OPENGL_WINDOW_CLASS_NAME, "WineD3D fake window",
258 WS_OVERLAPPEDWINDOW, 10, 10, 10, 10, NULL, NULL, NULL, NULL);
261 ERR_(d3d_caps)("Failed to create a window.\n");
265 ctx->dc = GetDC(ctx->wnd);
268 ERR_(d3d_caps)("Failed to get a DC.\n");
272 /* PixelFormat selection */
273 ZeroMemory(&pfd, sizeof(pfd));
274 pfd.nSize = sizeof(pfd);
276 pfd.dwFlags = PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER | PFD_DRAW_TO_WINDOW; /* PFD_GENERIC_ACCELERATED */
277 pfd.iPixelType = PFD_TYPE_RGBA;
279 pfd.iLayerType = PFD_MAIN_PLANE;
281 iPixelFormat = ChoosePixelFormat(ctx->dc, &pfd);
284 /* If this happens something is very wrong as ChoosePixelFormat barely fails. */
285 ERR_(d3d_caps)("Can't find a suitable iPixelFormat.\n");
288 DescribePixelFormat(ctx->dc, iPixelFormat, sizeof(pfd), &pfd);
289 SetPixelFormat(ctx->dc, iPixelFormat, &pfd);
291 /* Create a GL context. */
292 ctx->gl_ctx = pwglCreateContext(ctx->dc);
295 WARN_(d3d_caps)("Error creating default context for capabilities initialization.\n");
299 /* Make it the current GL context. */
300 if (!context_set_current(NULL))
302 ERR_(d3d_caps)("Failed to clear current D3D context.\n");
305 if (!pwglMakeCurrent(ctx->dc, ctx->gl_ctx))
307 ERR_(d3d_caps)("Failed to make fake GL context current.\n");
314 if (ctx->gl_ctx) pwglDeleteContext(ctx->gl_ctx);
316 if (ctx->dc) ReleaseDC(ctx->wnd, ctx->dc);
318 if (ctx->wnd) DestroyWindow(ctx->wnd);
320 if (ctx->restore_gl_ctx && !pwglMakeCurrent(ctx->restore_dc, ctx->restore_gl_ctx))
322 ERR_(d3d_caps)("Failed to restore previous GL context.\n");
328 /* Adjust the amount of used texture memory */
329 unsigned int WineD3DAdapterChangeGLRam(IWineD3DDeviceImpl *device, unsigned int glram)
331 struct wined3d_adapter *adapter = device->adapter;
333 adapter->UsedTextureRam += glram;
334 TRACE("Adjusted gl ram by %d to %d\n", glram, adapter->UsedTextureRam);
335 return adapter->UsedTextureRam;
338 static void wined3d_adapter_cleanup(struct wined3d_adapter *adapter)
340 HeapFree(GetProcessHeap(), 0, adapter->gl_info.gl_formats);
341 HeapFree(GetProcessHeap(), 0, adapter->cfgs);
344 /**********************************************************
345 * IUnknown parts follows
346 **********************************************************/
348 static HRESULT WINAPI IWineD3DImpl_QueryInterface(IWineD3D *iface,REFIID riid,LPVOID *ppobj)
350 IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
352 TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(riid),ppobj);
353 if (IsEqualGUID(riid, &IID_IUnknown)
354 || IsEqualGUID(riid, &IID_IWineD3DBase)
355 || IsEqualGUID(riid, &IID_IWineD3DDevice)) {
356 IUnknown_AddRef(iface);
361 return E_NOINTERFACE;
364 static ULONG WINAPI IWineD3DImpl_AddRef(IWineD3D *iface) {
365 IWineD3DImpl *This = (IWineD3DImpl *)iface;
366 ULONG refCount = InterlockedIncrement(&This->ref);
368 TRACE("(%p) : AddRef increasing from %d\n", This, refCount - 1);
372 static ULONG WINAPI IWineD3DImpl_Release(IWineD3D *iface) {
373 IWineD3DImpl *This = (IWineD3DImpl *)iface;
375 TRACE("(%p) : Releasing from %d\n", This, This->ref);
376 ref = InterlockedDecrement(&This->ref);
380 for (i = 0; i < This->adapter_count; ++i)
382 wined3d_adapter_cleanup(&This->adapters[i]);
384 HeapFree(GetProcessHeap(), 0, This);
390 /**********************************************************
391 * IWineD3D parts follows
392 **********************************************************/
394 /* GL locking is done by the caller */
395 static inline BOOL test_arb_vs_offset_limit(const struct wined3d_gl_info *gl_info)
399 const char *testcode =
401 "PARAM C[66] = { program.env[0..65] };\n"
403 "PARAM zero = {0.0, 0.0, 0.0, 0.0};\n"
404 "ARL A0.x, zero.x;\n"
405 "MOV result.position, C[A0.x + 65];\n"
409 GL_EXTCALL(glGenProgramsARB(1, &prog));
411 ERR("Failed to create an ARB offset limit test program\n");
413 GL_EXTCALL(glBindProgramARB(GL_VERTEX_PROGRAM_ARB, prog));
414 GL_EXTCALL(glProgramStringARB(GL_VERTEX_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB,
415 strlen(testcode), testcode));
416 if(glGetError() != 0) {
417 TRACE("OpenGL implementation does not allow indirect addressing offsets > 63\n");
418 TRACE("error: %s\n", debugstr_a((const char *)glGetString(GL_PROGRAM_ERROR_STRING_ARB)));
420 } else TRACE("OpenGL implementation allows offsets > 63\n");
422 GL_EXTCALL(glBindProgramARB(GL_VERTEX_PROGRAM_ARB, 0));
423 GL_EXTCALL(glDeleteProgramsARB(1, &prog));
424 checkGLcall("ARB vp offset limit test cleanup");
429 static DWORD ver_for_ext(GL_SupportedExt ext)
432 for (i = 0; i < (sizeof(EXTENSION_MAP) / sizeof(*EXTENSION_MAP)); ++i) {
433 if(EXTENSION_MAP[i].extension == ext) {
434 return EXTENSION_MAP[i].version;
440 static BOOL match_ati_r300_to_500(const struct wined3d_gl_info *gl_info, const char *gl_renderer,
441 enum wined3d_gl_vendor gl_vendor, enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device)
443 if (card_vendor != HW_VENDOR_ATI) return FALSE;
444 if (device == CARD_ATI_RADEON_9500) return TRUE;
445 if (device == CARD_ATI_RADEON_X700) return TRUE;
446 if (device == CARD_ATI_RADEON_X1600) return TRUE;
450 static BOOL match_geforce5(const struct wined3d_gl_info *gl_info, const char *gl_renderer,
451 enum wined3d_gl_vendor gl_vendor, enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device)
453 if (card_vendor == HW_VENDOR_NVIDIA)
455 if (device == CARD_NVIDIA_GEFORCEFX_5800 || device == CARD_NVIDIA_GEFORCEFX_5600)
463 static BOOL match_apple(const struct wined3d_gl_info *gl_info, const char *gl_renderer,
464 enum wined3d_gl_vendor gl_vendor, enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device)
466 /* MacOS has various specialities in the extensions it advertises. Some have to be loaded from
467 * the opengl 1.2+ core, while other extensions are advertised, but software emulated. So try to
468 * detect the Apple OpenGL implementation to apply some extension fixups afterwards.
470 * Detecting this isn't really easy. The vendor string doesn't mention Apple. Compile-time checks
471 * aren't sufficient either because a Linux binary may display on a macos X server via remote X11.
472 * So try to detect the GL implementation by looking at certain Apple extensions. Some extensions
473 * like client storage might be supported on other implementations too, but GL_APPLE_flush_render
474 * is specific to the Mac OS X window management, and GL_APPLE_ycbcr_422 is QuickTime specific. So
475 * the chance that other implementations support them is rather small since Win32 QuickTime uses
476 * DirectDraw, not OpenGL.
478 * This test has been moved into wined3d_guess_gl_vendor()
480 if (gl_vendor == GL_VENDOR_APPLE)
487 /* Context activation is done by the caller. */
488 static void test_pbo_functionality(struct wined3d_gl_info *gl_info)
490 /* Some OpenGL implementations, namely Apple's Geforce 8 driver, advertises PBOs,
491 * but glTexSubImage from a PBO fails miserably, with the first line repeated over
492 * all the texture. This function detects this bug by its symptom and disables PBOs
495 * The test uploads a 4x4 texture via the PBO in the "native" format GL_BGRA,
496 * GL_UNSIGNED_INT_8_8_8_8_REV. This format triggers the bug, and it is what we use
497 * for D3DFMT_A8R8G8B8. Then the texture is read back without any PBO and the data
498 * read back is compared to the original. If they are equal PBOs are assumed to work,
499 * otherwise the PBO extension is disabled. */
501 static const unsigned int pattern[] =
503 0x00000000, 0x000000ff, 0x0000ff00, 0x40ff0000,
504 0x80ffffff, 0x40ffff00, 0x00ff00ff, 0x0000ffff,
505 0x00ffff00, 0x00ff00ff, 0x0000ffff, 0x000000ff,
506 0x80ff00ff, 0x0000ffff, 0x00ff00ff, 0x40ff00ff
508 unsigned int check[sizeof(pattern) / sizeof(pattern[0])];
510 /* No PBO -> No point in testing them. */
511 if (!gl_info->supported[ARB_PIXEL_BUFFER_OBJECT]) return;
515 while (glGetError());
516 glGenTextures(1, &texture);
517 glBindTexture(GL_TEXTURE_2D, texture);
519 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
520 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 4, 4, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, 0);
521 checkGLcall("Specifying the PBO test texture");
523 GL_EXTCALL(glGenBuffersARB(1, &pbo));
524 GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, pbo));
525 GL_EXTCALL(glBufferDataARB(GL_PIXEL_UNPACK_BUFFER_ARB, sizeof(pattern), pattern, GL_STREAM_DRAW_ARB));
526 checkGLcall("Specifying the PBO test pbo");
528 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 4, 4, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL);
529 checkGLcall("Loading the PBO test texture");
531 GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0));
534 wglFinish(); /* just to be sure */
536 memset(check, 0, sizeof(check));
538 glGetTexImage(GL_TEXTURE_2D, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, check);
539 checkGLcall("Reading back the PBO test texture");
541 glDeleteTextures(1, &texture);
542 GL_EXTCALL(glDeleteBuffersARB(1, &pbo));
543 checkGLcall("PBO test cleanup");
547 if (memcmp(check, pattern, sizeof(check)))
549 WARN_(d3d_caps)("PBO test failed, read back data doesn't match original.\n");
550 WARN_(d3d_caps)("Disabling PBOs. This may result in slower performance.\n");
551 gl_info->supported[ARB_PIXEL_BUFFER_OBJECT] = FALSE;
555 TRACE_(d3d_caps)("PBO test successful.\n");
559 static BOOL match_apple_intel(const struct wined3d_gl_info *gl_info, const char *gl_renderer,
560 enum wined3d_gl_vendor gl_vendor, enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device)
562 return (card_vendor == HW_VENDOR_INTEL) && (gl_vendor == GL_VENDOR_APPLE);
565 static BOOL match_apple_nonr500ati(const struct wined3d_gl_info *gl_info, const char *gl_renderer,
566 enum wined3d_gl_vendor gl_vendor, enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device)
568 if (gl_vendor != GL_VENDOR_APPLE) return FALSE;
569 if (card_vendor != HW_VENDOR_ATI) return FALSE;
570 if (device == CARD_ATI_RADEON_X1600) return FALSE;
574 static BOOL match_fglrx(const struct wined3d_gl_info *gl_info, const char *gl_renderer,
575 enum wined3d_gl_vendor gl_vendor, enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device)
577 return gl_vendor == GL_VENDOR_FGLRX;
581 static BOOL match_dx10_capable(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 /* DX9 cards support 40 single float varyings in hardware, most drivers report 32. ATI misreports
585 * 44 varyings. So assume that if we have more than 44 varyings we have a dx10 card.
586 * This detection is for the gl_ClipPos varying quirk. If a d3d9 card really supports more than 44
587 * varyings and we subtract one in dx9 shaders its not going to hurt us because the dx9 limit is
590 * dx10 cards usually have 64 varyings */
591 return gl_info->limits.glsl_varyings > 44;
594 /* A GL context is provided by the caller */
595 static BOOL match_allows_spec_alpha(const struct wined3d_gl_info *gl_info, const char *gl_renderer,
596 enum wined3d_gl_vendor gl_vendor, enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device)
601 if (!gl_info->supported[EXT_SECONDARY_COLOR]) return FALSE;
605 GL_EXTCALL(glSecondaryColorPointerEXT)(4, GL_UNSIGNED_BYTE, 4, data);
606 error = glGetError();
609 if(error == GL_NO_ERROR)
611 TRACE("GL Implementation accepts 4 component specular color pointers\n");
616 TRACE("GL implementation does not accept 4 component specular colors, error %s\n",
617 debug_glerror(error));
622 static BOOL match_apple_nvts(const struct wined3d_gl_info *gl_info, const char *gl_renderer,
623 enum wined3d_gl_vendor gl_vendor, enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device)
625 if (!match_apple(gl_info, gl_renderer, gl_vendor, card_vendor, device)) return FALSE;
626 return gl_info->supported[NV_TEXTURE_SHADER];
629 /* A GL context is provided by the caller */
630 static BOOL match_broken_nv_clip(const struct wined3d_gl_info *gl_info, const char *gl_renderer,
631 enum wined3d_gl_vendor gl_vendor, enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device)
636 const char *testcode =
638 "OPTION NV_vertex_program2;\n"
639 "MOV result.clip[0], 0.0;\n"
640 "MOV result.position, 0.0;\n"
643 if (!gl_info->supported[NV_VERTEX_PROGRAM2_OPTION]) return FALSE;
648 GL_EXTCALL(glGenProgramsARB(1, &prog));
651 ERR("Failed to create the NVvp clip test program\n");
655 GL_EXTCALL(glBindProgramARB(GL_VERTEX_PROGRAM_ARB, prog));
656 GL_EXTCALL(glProgramStringARB(GL_VERTEX_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB,
657 strlen(testcode), testcode));
658 glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB, &pos);
661 WARN("GL_NV_vertex_program2_option result.clip[] test failed\n");
662 TRACE("error: %s\n", debugstr_a((const char *)glGetString(GL_PROGRAM_ERROR_STRING_ARB)));
666 else TRACE("GL_NV_vertex_program2_option result.clip[] test passed\n");
668 GL_EXTCALL(glBindProgramARB(GL_VERTEX_PROGRAM_ARB, 0));
669 GL_EXTCALL(glDeleteProgramsARB(1, &prog));
670 checkGLcall("GL_NV_vertex_program2_option result.clip[] test cleanup");
676 /* Context activation is done by the caller. */
677 static BOOL match_fbo_tex_update(const struct wined3d_gl_info *gl_info, const char *gl_renderer,
678 enum wined3d_gl_vendor gl_vendor, enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device)
680 char data[4 * 4 * 4];
684 if (wined3d_settings.offscreen_rendering_mode != ORM_FBO) return FALSE;
686 memset(data, 0xcc, sizeof(data));
690 glGenTextures(1, &tex);
691 glBindTexture(GL_TEXTURE_2D, tex);
692 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
693 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
694 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 4, 4, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL);
695 checkGLcall("glTexImage2D");
697 gl_info->fbo_ops.glGenFramebuffers(1, &fbo);
698 gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, fbo);
699 gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
700 checkGLcall("glFramebufferTexture2D");
702 status = gl_info->fbo_ops.glCheckFramebufferStatus(GL_FRAMEBUFFER);
703 if (status != GL_FRAMEBUFFER_COMPLETE) ERR("FBO status %#x\n", status);
704 checkGLcall("glCheckFramebufferStatus");
706 memset(data, 0x11, sizeof(data));
707 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 4, 4, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, data);
708 checkGLcall("glTexSubImage2D");
710 glClearColor(0.996, 0.729, 0.745, 0.792);
711 glClear(GL_COLOR_BUFFER_BIT);
712 checkGLcall("glClear");
714 glGetTexImage(GL_TEXTURE_2D, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, data);
715 checkGLcall("glGetTexImage");
717 gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
718 gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, 0);
719 glBindTexture(GL_TEXTURE_2D, 0);
720 checkGLcall("glBindTexture");
722 gl_info->fbo_ops.glDeleteFramebuffers(1, &fbo);
723 glDeleteTextures(1, &tex);
724 checkGLcall("glDeleteTextures");
728 return *(DWORD *)data == 0x11111111;
731 static void quirk_arb_constants(struct wined3d_gl_info *gl_info)
733 TRACE_(d3d_caps)("Using ARB vs constant limit(=%u) for GLSL.\n", gl_info->limits.arb_vs_native_constants);
734 gl_info->limits.glsl_vs_float_constants = gl_info->limits.arb_vs_native_constants;
735 TRACE_(d3d_caps)("Using ARB ps constant limit(=%u) for GLSL.\n", gl_info->limits.arb_ps_native_constants);
736 gl_info->limits.glsl_ps_float_constants = gl_info->limits.arb_ps_native_constants;
739 static void quirk_apple_glsl_constants(struct wined3d_gl_info *gl_info)
741 quirk_arb_constants(gl_info);
742 /* MacOS needs uniforms for relative addressing offsets. This can accumulate to quite a few uniforms.
743 * Beyond that the general uniform isn't optimal, so reserve a number of uniforms. 12 vec4's should
744 * allow 48 different offsets or other helper immediate values. */
745 TRACE_(d3d_caps)("Reserving 12 GLSL constants for compiler private use.\n");
746 gl_info->reserved_glsl_constants = max(gl_info->reserved_glsl_constants, 12);
749 /* fglrx crashes with a very bad kernel panic if GL_POINT_SPRITE_ARB is set to GL_COORD_REPLACE_ARB
750 * on more than one texture unit. This means that the d3d9 visual point size test will cause a
751 * kernel panic on any machine running fglrx 9.3(latest that supports r300 to r500 cards). This
752 * quirk only enables point sprites on the first texture unit. This keeps point sprites working in
753 * most games, but avoids the crash
755 * A more sophisticated way would be to find all units that need texture coordinates and enable
756 * point sprites for one if only one is found, and software emulate point sprites in drawStridedSlow
757 * if more than one unit needs texture coordinates(This requires software ffp and vertex shaders though)
759 * Note that disabling the extension entirely does not gain predictability because there is no point
760 * sprite capability flag in d3d, so the potential rendering bugs are the same if we disable the extension. */
761 static void quirk_one_point_sprite(struct wined3d_gl_info *gl_info)
763 if (gl_info->supported[ARB_POINT_SPRITE])
765 TRACE("Limiting point sprites to one texture unit.\n");
766 gl_info->limits.point_sprite_units = 1;
770 static void quirk_ati_dx9(struct wined3d_gl_info *gl_info)
772 quirk_arb_constants(gl_info);
774 /* MacOS advertises GL_ARB_texture_non_power_of_two on ATI r500 and earlier cards, although
775 * these cards only support GL_ARB_texture_rectangle(D3DPTEXTURECAPS_NONPOW2CONDITIONAL).
776 * If real NP2 textures are used, the driver falls back to software. We could just remove the
777 * extension and use GL_ARB_texture_rectangle instead, but texture_rectangle is inconventient
778 * due to the non-normalized texture coordinates. Thus set an internal extension flag,
779 * GL_WINE_normalized_texrect, which signals the code that it can use non power of two textures
780 * as per GL_ARB_texture_non_power_of_two, but has to stick to the texture_rectangle limits.
782 * fglrx doesn't advertise GL_ARB_texture_non_power_of_two, but it advertises opengl 2.0 which
783 * has this extension promoted to core. The extension loading code sets this extension supported
784 * due to that, so this code works on fglrx as well. */
785 if(gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO])
787 TRACE("GL_ARB_texture_non_power_of_two advertised on R500 or earlier card, removing.\n");
788 gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO] = FALSE;
789 gl_info->supported[WINE_NORMALIZED_TEXRECT] = TRUE;
792 /* fglrx has the same structural issues as the one described in quirk_apple_glsl_constants, although
793 * it is generally more efficient. Reserve just 8 constants. */
794 TRACE_(d3d_caps)("Reserving 8 GLSL constants for compiler private use.\n");
795 gl_info->reserved_glsl_constants = max(gl_info->reserved_glsl_constants, 8);
798 static void quirk_no_np2(struct wined3d_gl_info *gl_info)
800 /* The nVidia GeForceFX series reports OpenGL 2.0 capabilities with the latest drivers versions, but
801 * doesn't explicitly advertise the ARB_tex_npot extension in the GL extension string.
802 * This usually means that ARB_tex_npot is supported in hardware as long as the application is staying
803 * within the limits enforced by the ARB_texture_rectangle extension. This however is not true for the
804 * FX series, which instantly falls back to a slower software path as soon as ARB_tex_npot is used.
805 * We therefore completely remove ARB_tex_npot from the list of supported extensions.
807 * Note that wine_normalized_texrect can't be used in this case because internally it uses ARB_tex_npot,
808 * triggering the software fallback. There is not much we can do here apart from disabling the
809 * software-emulated extension and reenable ARB_tex_rect (which was previously disabled
810 * in IWineD3DImpl_FillGLCaps).
811 * This fixup removes performance problems on both the FX 5900 and FX 5700 (e.g. for framebuffer
812 * post-processing effects in the game "Max Payne 2").
813 * The behaviour can be verified through a simple test app attached in bugreport #14724. */
814 TRACE("GL_ARB_texture_non_power_of_two advertised through OpenGL 2.0 on NV FX card, removing.\n");
815 gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO] = FALSE;
816 gl_info->supported[ARB_TEXTURE_RECTANGLE] = TRUE;
819 static void quirk_texcoord_w(struct wined3d_gl_info *gl_info)
821 /* The Intel GPUs on MacOS set the .w register of texcoords to 0.0 by default, which causes problems
822 * with fixed function fragment processing. Ideally this flag should be detected with a test shader
823 * and OpenGL feedback mode, but some GL implementations (MacOS ATI at least, probably all MacOS ones)
824 * do not like vertex shaders in feedback mode and return an error, even though it should be valid
825 * according to the spec.
827 * We don't want to enable this on all cards, as it adds an extra instruction per texcoord used. This
828 * makes the shader slower and eats instruction slots which should be available to the d3d app.
830 * ATI Radeon HD 2xxx cards on MacOS have the issue. Instead of checking for the buggy cards, blacklist
831 * all radeon cards on Macs and whitelist the good ones. That way we're prepared for the future. If
832 * this workaround is activated on cards that do not need it, it won't break things, just affect
833 * performance negatively. */
834 TRACE("Enabling vertex texture coord fixes in vertex shaders.\n");
835 gl_info->quirks |= WINED3D_QUIRK_SET_TEXCOORD_W;
838 static void quirk_clip_varying(struct wined3d_gl_info *gl_info)
840 gl_info->quirks |= WINED3D_QUIRK_GLSL_CLIP_VARYING;
843 static void quirk_allows_specular_alpha(struct wined3d_gl_info *gl_info)
845 gl_info->quirks |= WINED3D_QUIRK_ALLOWS_SPECULAR_ALPHA;
848 static void quirk_apple_nvts(struct wined3d_gl_info *gl_info)
850 gl_info->supported[NV_TEXTURE_SHADER] = FALSE;
851 gl_info->supported[NV_TEXTURE_SHADER2] = FALSE;
854 static void quirk_disable_nvvp_clip(struct wined3d_gl_info *gl_info)
856 gl_info->quirks |= WINED3D_QUIRK_NV_CLIP_BROKEN;
859 static void quirk_fbo_tex_update(struct wined3d_gl_info *gl_info)
861 gl_info->quirks |= WINED3D_QUIRK_FBO_TEX_UPDATE;
866 BOOL (*match)(const struct wined3d_gl_info *gl_info, const char *gl_renderer,
867 enum wined3d_gl_vendor gl_vendor, enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device);
868 void (*apply)(struct wined3d_gl_info *gl_info);
869 const char *description;
872 static const struct driver_quirk quirk_table[] =
875 match_ati_r300_to_500,
877 "ATI GLSL constant and normalized texrect quirk"
879 /* MacOS advertises more GLSL vertex shader uniforms than supported by the hardware, and if more are
880 * used it falls back to software. While the compiler can detect if the shader uses all declared
881 * uniforms, the optimization fails if the shader uses relative addressing. So any GLSL shader
882 * using relative addressing falls back to software.
884 * ARB vp gives the correct amount of uniforms, so use it instead of GLSL. */
887 quirk_apple_glsl_constants,
888 "Apple GLSL uniform override"
893 "Geforce 5 NP2 disable"
898 "Init texcoord .w for Apple Intel GPU driver"
901 match_apple_nonr500ati,
903 "Init texcoord .w for Apple ATI >= r600 GPU driver"
907 quirk_one_point_sprite,
908 "Fglrx point sprite crash workaround"
913 "Reserved varying for gl_ClipPos"
916 /* GL_EXT_secondary_color does not allow 4 component secondary colors, but most
917 * GL implementations accept it. The Mac GL is the only implementation known to
920 * If we can pass 4 component specular colors, do it, because (a) we don't have
921 * to screw around with the data, and (b) the D3D fixed function vertex pipeline
922 * passes specular alpha to the pixel shader if any is used. Otherwise the
923 * specular alpha is used to pass the fog coordinate, which we pass to opengl
924 * via GL_EXT_fog_coord.
926 match_allows_spec_alpha,
927 quirk_allows_specular_alpha,
928 "Allow specular alpha quirk"
931 /* The pixel formats provided by GL_NV_texture_shader are broken on OSX
936 "Apple NV_texture_shader disable"
939 match_broken_nv_clip,
940 quirk_disable_nvvp_clip,
941 "Apple NV_vertex_program clip bug quirk"
944 match_fbo_tex_update,
945 quirk_fbo_tex_update,
946 "FBO rebind for attachment updates"
950 /* Certain applications (Steam) complain if we report an outdated driver version. In general,
951 * reporting a driver version is moot because we are not the Windows driver, and we have different
952 * bugs, features, etc.
954 * The driver version has the form "x.y.z.w".
956 * "x" is the Windows version the driver is meant for:
963 * "y" is the Direct3D level the driver supports:
970 * "z" is unknown, possibly vendor specific.
972 * "w" is the vendor specific driver version.
974 struct driver_version_information
976 WORD vendor; /* reported PCI card vendor ID */
977 WORD card; /* reported PCI card device ID */
978 const char *description; /* Description of the card e.g. NVIDIA RIVA TNT */
979 WORD d3d_level; /* driver hiword to report */
980 WORD lopart_hi, lopart_lo; /* driver loword to report */
983 static const struct driver_version_information driver_version_table[] =
985 /* Nvidia drivers. Geforce6 and newer cards are supported by the current driver (180.x)
986 * GeforceFX support is up to 173.x, - driver uses numbering x.y.11.7341 for 173.41 where x is the windows revision (6=2000/xp, 7=vista), y is unknown
987 * Geforce2MX/3/4 up to 96.x - driver uses numbering 9.6.8.9 for 96.89
988 * TNT/Geforce1/2 up to 71.x - driver uses numbering 7.1.8.6 for 71.86
990 * All version numbers used below are from the Linux nvidia drivers. */
991 {HW_VENDOR_NVIDIA, CARD_NVIDIA_RIVA_TNT, "NVIDIA RIVA TNT", 1, 8, 6 },
992 {HW_VENDOR_NVIDIA, CARD_NVIDIA_RIVA_TNT2, "NVIDIA RIVA TNT2/TNT2 Pro", 1, 8, 6 },
993 {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE, "NVIDIA GeForce 256", 1, 8, 6 },
994 {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE2_MX, "NVIDIA GeForce2 MX/MX 400", 6, 4, 3 },
995 {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE2, "NVIDIA GeForce2 GTS/GeForce2 Pro", 1, 8, 6 },
996 {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE3, "NVIDIA GeForce3", 6, 10, 9371 },
997 {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE4_MX, "NVIDIA GeForce4 MX 460", 6, 10, 9371 },
998 {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE4_TI4200, "NVIDIA GeForce4 Ti 4200", 6, 10, 9371 },
999 {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCEFX_5200, "NVIDIA GeForce FX 5200", 15, 11, 7516 },
1000 {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCEFX_5600, "NVIDIA GeForce FX 5600", 15, 11, 7516 },
1001 {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCEFX_5800, "NVIDIA GeForce FX 5800", 15, 11, 7516 },
1002 {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_6200, "NVIDIA GeForce 6200", 15, 11, 9745 },
1003 {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_6600GT, "NVIDIA GeForce 6600 GT", 15, 11, 9745 },
1004 {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_6800, "NVIDIA GeForce 6800", 15, 11, 9745 },
1005 {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_7300, "NVIDIA GeForce Go 7300", 15, 11, 9745 },
1006 {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_7400, "NVIDIA GeForce Go 7400", 15, 11, 9745 },
1007 {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_7600, "NVIDIA GeForce 7600 GT", 15, 11, 9745 },
1008 {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_7800GT, "NVIDIA GeForce 7800 GT", 15, 11, 9745 },
1009 {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_8300GS, "NVIDIA GeForce 8300 GS", 15, 11, 9745 },
1010 {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_8600GT, "NVIDIA GeForce 8600 GT", 15, 11, 9745 },
1011 {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_8600MGT, "NVIDIA GeForce 8600M GT", 15, 11, 9745 },
1012 {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_8800GTS, "NVIDIA GeForce 8800 GTS", 15, 11, 9745 },
1013 {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_9200, "NVIDIA GeForce 9200", 15, 11, 9745 },
1014 {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_9400GT, "NVIDIA GeForce 9400 GT", 15, 11, 9745 },
1015 {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_9500GT, "NVIDIA GeForce 9500 GT", 15, 11, 9745 },
1016 {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_9600GT, "NVIDIA GeForce 9600 GT", 15, 11, 9745 },
1017 {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_9800GT, "NVIDIA GeForce 9800 GT", 15, 11, 9745 },
1018 {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_210, "NVIDIA GeForce 210", 15, 11, 9745 },
1019 {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GT220, "NVIDIA GeForce GT 220", 15, 11, 9745 },
1020 {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GT240, "NVIDIA GeForce GT 240", 15, 11, 9745 },
1021 {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX260, "NVIDIA GeForce GTX 260", 15, 11, 9745 },
1022 {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX275, "NVIDIA GeForce GTX 275", 15, 11, 9745 },
1023 {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX280, "NVIDIA GeForce GTX 280", 15, 11, 9745 },
1024 {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GT325M, "NVIDIA GeForce GT 325M", 15, 11, 9745 },
1025 {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTS350M, "NVIDIA GeForce GTS 350M", 15, 11, 9745 },
1026 {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX470, "NVIDIA GeForce GTX 470", 15, 11, 9775 },
1027 {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX480, "NVIDIA GeForce GTX 480", 15, 11, 9775 },
1028 /* ATI cards. The driver versions are somewhat similar, but not quite the same. Let's hardcode. */
1029 {HW_VENDOR_ATI, CARD_ATI_RADEON_9500, "ATI Radeon 9500", 14, 10, 6764 },
1030 {HW_VENDOR_ATI, CARD_ATI_RADEON_X700, "ATI Radeon X700 SE", 14, 10, 6764 },
1031 {HW_VENDOR_ATI, CARD_ATI_RADEON_X1600, "ATI Radeon X1600 Series", 14, 10, 6764 },
1032 {HW_VENDOR_ATI, CARD_ATI_RADEON_HD2350, "ATI Mobility Radeon HD 2350", 14, 10, 6764 },
1033 {HW_VENDOR_ATI, CARD_ATI_RADEON_HD2600, "ATI Mobility Radeon HD 2600", 14, 10, 6764 },
1034 {HW_VENDOR_ATI, CARD_ATI_RADEON_HD2900, "ATI Radeon HD 2900 XT", 14, 10, 6764 },
1035 {HW_VENDOR_ATI, CARD_ATI_RADEON_HD4350, "ATI Radeon HD 4350", 14, 10, 6764 },
1036 {HW_VENDOR_ATI, CARD_ATI_RADEON_HD4600, "ATI Radeon HD 4600 Series", 14, 10, 6764 },
1037 {HW_VENDOR_ATI, CARD_ATI_RADEON_HD4700, "ATI Radeon HD 4700 Series", 14, 10, 6764 },
1038 {HW_VENDOR_ATI, CARD_ATI_RADEON_HD4800, "ATI Radeon HD 4800 Series", 14, 10, 6764 },
1039 {HW_VENDOR_ATI, CARD_ATI_RADEON_HD5700, "ATI Radeon HD 5700 Series", 14, 10, 8681 },
1040 {HW_VENDOR_ATI, CARD_ATI_RADEON_HD5800, "ATI Radeon HD 5800 Series", 14, 10, 8681 },
1042 /* TODO: Add information about legacy ATI hardware, Intel and other cards. */
1045 static void init_driver_info(struct wined3d_driver_info *driver_info,
1046 enum wined3d_pci_vendor vendor, enum wined3d_pci_device device)
1048 OSVERSIONINFOW os_version;
1049 WORD driver_os_version;
1052 if (wined3d_settings.pci_vendor_id != PCI_VENDOR_NONE)
1054 TRACE_(d3d_caps)("Overriding PCI vendor ID with: %04x\n", wined3d_settings.pci_vendor_id);
1055 vendor = wined3d_settings.pci_vendor_id;
1057 driver_info->vendor = vendor;
1059 if (wined3d_settings.pci_device_id != PCI_DEVICE_NONE)
1061 TRACE_(d3d_caps)("Overriding PCI device ID with: %04x\n", wined3d_settings.pci_device_id);
1062 device = wined3d_settings.pci_device_id;
1064 driver_info->device = device;
1069 driver_info->name = "ati2dvag.dll";
1072 case HW_VENDOR_NVIDIA:
1073 driver_info->name = "nv4_disp.dll";
1076 case HW_VENDOR_INTEL:
1078 FIXME_(d3d_caps)("Unhandled vendor %04x.\n", vendor);
1079 driver_info->name = "Display";
1083 memset(&os_version, 0, sizeof(os_version));
1084 os_version.dwOSVersionInfoSize = sizeof(os_version);
1085 if (!GetVersionExW(&os_version))
1087 ERR("Failed to get OS version, reporting 2000/XP.\n");
1088 driver_os_version = 6;
1092 TRACE("OS version %u.%u.\n", os_version.dwMajorVersion, os_version.dwMinorVersion);
1093 switch (os_version.dwMajorVersion)
1096 driver_os_version = 4;
1100 driver_os_version = 6;
1104 if (os_version.dwMinorVersion == 0)
1106 driver_os_version = 7;
1110 if (os_version.dwMinorVersion > 1)
1112 FIXME("Unhandled OS version %u.%u, reporting Win 7.\n",
1113 os_version.dwMajorVersion, os_version.dwMinorVersion);
1115 driver_os_version = 8;
1120 FIXME("Unhandled OS version %u.%u, reporting 2000/XP.\n",
1121 os_version.dwMajorVersion, os_version.dwMinorVersion);
1122 driver_os_version = 6;
1127 driver_info->description = "Direct3D HAL";
1128 driver_info->version_high = MAKEDWORD_VERSION(driver_os_version, 15);
1129 driver_info->version_low = MAKEDWORD_VERSION(8, 6); /* Nvidia RIVA TNT, arbitrary */
1131 for (i = 0; i < (sizeof(driver_version_table) / sizeof(driver_version_table[0])); ++i)
1133 if (vendor == driver_version_table[i].vendor && device == driver_version_table[i].card)
1135 TRACE_(d3d_caps)("Found card %04x:%04x in driver DB.\n", vendor, device);
1137 driver_info->description = driver_version_table[i].description;
1138 driver_info->version_high = MAKEDWORD_VERSION(driver_os_version, driver_version_table[i].d3d_level);
1139 driver_info->version_low = MAKEDWORD_VERSION(driver_version_table[i].lopart_hi,
1140 driver_version_table[i].lopart_lo);
1145 TRACE_(d3d_caps)("Reporting (fake) driver version 0x%08x-0x%08x.\n",
1146 driver_info->version_high, driver_info->version_low);
1149 /* Context activation is done by the caller. */
1150 static void fixup_extensions(struct wined3d_gl_info *gl_info, const char *gl_renderer,
1151 enum wined3d_gl_vendor gl_vendor, enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device)
1155 for (i = 0; i < (sizeof(quirk_table) / sizeof(*quirk_table)); ++i)
1157 if (!quirk_table[i].match(gl_info, gl_renderer, gl_vendor, card_vendor, device)) continue;
1158 TRACE_(d3d_caps)("Applying driver quirk \"%s\".\n", quirk_table[i].description);
1159 quirk_table[i].apply(gl_info);
1162 /* Find out if PBOs work as they are supposed to. */
1163 test_pbo_functionality(gl_info);
1166 static DWORD wined3d_parse_gl_version(const char *gl_version)
1168 const char *ptr = gl_version;
1172 if (major <= 0) ERR_(d3d_caps)("Invalid opengl major version: %d.\n", major);
1174 while (isdigit(*ptr)) ++ptr;
1175 if (*ptr++ != '.') ERR_(d3d_caps)("Invalid opengl version string: %s.\n", debugstr_a(gl_version));
1179 TRACE_(d3d_caps)("Found OpenGL version: %d.%d.\n", major, minor);
1181 return MAKEDWORD_VERSION(major, minor);
1184 static enum wined3d_gl_vendor wined3d_guess_gl_vendor(struct wined3d_gl_info *gl_info, const char *gl_vendor_string, const char *gl_renderer)
1187 /* MacOS has various specialities in the extensions it advertises. Some have to be loaded from
1188 * the opengl 1.2+ core, while other extensions are advertised, but software emulated. So try to
1189 * detect the Apple OpenGL implementation to apply some extension fixups afterwards.
1191 * Detecting this isn't really easy. The vendor string doesn't mention Apple. Compile-time checks
1192 * aren't sufficient either because a Linux binary may display on a macos X server via remote X11.
1193 * So try to detect the GL implementation by looking at certain Apple extensions. Some extensions
1194 * like client storage might be supported on other implementations too, but GL_APPLE_flush_render
1195 * is specific to the Mac OS X window management, and GL_APPLE_ycbcr_422 is QuickTime specific. So
1196 * the chance that other implementations support them is rather small since Win32 QuickTime uses
1197 * DirectDraw, not OpenGL. */
1198 if (gl_info->supported[APPLE_FENCE]
1199 && gl_info->supported[APPLE_CLIENT_STORAGE]
1200 && gl_info->supported[APPLE_FLUSH_RENDER]
1201 && gl_info->supported[APPLE_YCBCR_422])
1202 return GL_VENDOR_APPLE;
1204 if (strstr(gl_vendor_string, "NVIDIA"))
1205 return GL_VENDOR_NVIDIA;
1207 if (strstr(gl_vendor_string, "ATI"))
1208 return GL_VENDOR_FGLRX;
1210 if (strstr(gl_vendor_string, "Intel(R)")
1211 /* Intel switched from Intel(R) to Intel® recently, so just match Intel. */
1212 || strstr(gl_renderer, "Intel")
1213 || strstr(gl_vendor_string, "Intel Inc."))
1214 return GL_VENDOR_INTEL;
1216 if (strstr(gl_vendor_string, "Mesa")
1217 || strstr(gl_vendor_string, "Advanced Micro Devices, Inc.")
1218 || strstr(gl_vendor_string, "DRI R300 Project")
1219 || strstr(gl_vendor_string, "X.Org R300 Project")
1220 || strstr(gl_vendor_string, "Tungsten Graphics, Inc")
1221 || strstr(gl_vendor_string, "VMware, Inc.")
1222 || strstr(gl_renderer, "Mesa")
1223 || strstr(gl_renderer, "Gallium"))
1224 return GL_VENDOR_MESA;
1226 FIXME_(d3d_caps)("Received unrecognized GL_VENDOR %s. Returning GL_VENDOR_UNKNOWN.\n",
1227 debugstr_a(gl_vendor_string));
1229 return GL_VENDOR_UNKNOWN;
1232 static enum wined3d_pci_vendor wined3d_guess_card_vendor(const char *gl_vendor_string, const char *gl_renderer)
1234 if (strstr(gl_vendor_string, "NVIDIA"))
1235 return HW_VENDOR_NVIDIA;
1237 if (strstr(gl_vendor_string, "ATI")
1238 || strstr(gl_vendor_string, "Advanced Micro Devices, Inc.")
1239 || strstr(gl_vendor_string, "X.Org R300 Project")
1240 || strstr(gl_vendor_string, "DRI R300 Project"))
1241 return HW_VENDOR_ATI;
1243 if (strstr(gl_vendor_string, "Intel(R)")
1244 /* Intel switched from Intel(R) to Intel® recently, so just match Intel. */
1245 || strstr(gl_renderer, "Intel")
1246 || strstr(gl_vendor_string, "Intel Inc."))
1247 return HW_VENDOR_INTEL;
1249 if (strstr(gl_vendor_string, "Mesa")
1250 || strstr(gl_vendor_string, "Tungsten Graphics, Inc")
1251 || strstr(gl_vendor_string, "VMware, Inc."))
1252 return HW_VENDOR_SOFTWARE;
1254 FIXME_(d3d_caps)("Received unrecognized GL_VENDOR %s. Returning HW_VENDOR_NVIDIA.\n", debugstr_a(gl_vendor_string));
1256 return HW_VENDOR_NVIDIA;
1261 static enum wined3d_pci_device select_card_nvidia_binary(const struct wined3d_gl_info *gl_info,
1262 const char *gl_renderer, unsigned int *vidmem)
1264 if (WINE_D3D10_CAPABLE(gl_info))
1266 /* Geforce 400 - highend */
1267 if (strstr(gl_renderer, "GTX 480"))
1270 return CARD_NVIDIA_GEFORCE_GTX480;
1273 /* Geforce 400 - midend high */
1274 if (strstr(gl_renderer, "GTX 470"))
1277 return CARD_NVIDIA_GEFORCE_GTX470;
1280 /* Geforce 300 highend mobile */
1281 if (strstr(gl_renderer, "GTS 350M")
1282 || strstr(gl_renderer, "GTS 360M"))
1285 return CARD_NVIDIA_GEFORCE_GTS350M;
1288 /* Geforce 300 midend mobile (Geforce GT 325M/330M use the same core) */
1289 if (strstr(gl_renderer, "GT 325M")
1290 || strstr(gl_renderer, "GT 330M"))
1293 return CARD_NVIDIA_GEFORCE_GT325M;
1296 /* Geforce 200 - highend */
1297 if (strstr(gl_renderer, "GTX 280")
1298 || strstr(gl_renderer, "GTX 285")
1299 || strstr(gl_renderer, "GTX 295"))
1302 return CARD_NVIDIA_GEFORCE_GTX280;
1305 /* Geforce 200 - midend high */
1306 if (strstr(gl_renderer, "GTX 275"))
1309 return CARD_NVIDIA_GEFORCE_GTX275;
1312 /* Geforce 200 - midend */
1313 if (strstr(gl_renderer, "GTX 260"))
1316 return CARD_NVIDIA_GEFORCE_GTX260;
1318 /* Geforce 200 - midend */
1319 if (strstr(gl_renderer, "GT 240"))
1322 return CARD_NVIDIA_GEFORCE_GT240;
1325 /* Geforce 200 lowend */
1326 if (strstr(gl_renderer, "GT 220"))
1328 *vidmem = 512; /* The GT 220 has 512-1024MB */
1329 return CARD_NVIDIA_GEFORCE_GT220;
1331 /* Geforce 200 lowend (Geforce 305/310 use the same core) */
1332 if (strstr(gl_renderer, "Geforce 210")
1333 || strstr(gl_renderer, "G 210")
1334 || strstr(gl_renderer, "Geforce 305")
1335 || strstr(gl_renderer, "Geforce 310"))
1338 return CARD_NVIDIA_GEFORCE_210;
1341 /* Geforce9 - highend / Geforce 200 - midend (GTS 150/250 are based on the same core) */
1342 if (strstr(gl_renderer, "9800")
1343 || strstr(gl_renderer, "GTS 150")
1344 || strstr(gl_renderer, "GTS 250"))
1347 return CARD_NVIDIA_GEFORCE_9800GT;
1350 /* Geforce9 - midend (GT 140 uses the same core as the 9600GT) */
1351 if (strstr(gl_renderer, "9600")
1352 || strstr(gl_renderer, "GT 140"))
1354 *vidmem = 384; /* The 9600GSO has 384MB, the 9600GT has 512-1024MB */
1355 return CARD_NVIDIA_GEFORCE_9600GT;
1358 /* Geforce9 - midend low / Geforce 200 - low */
1359 if (strstr(gl_renderer, "9500")
1360 || strstr(gl_renderer, "GT 120")
1361 || strstr(gl_renderer, "GT 130"))
1363 *vidmem = 256; /* The 9500GT has 256-1024MB */
1364 return CARD_NVIDIA_GEFORCE_9500GT;
1367 /* Geforce9 - lowend */
1368 if (strstr(gl_renderer, "9400"))
1370 *vidmem = 256; /* The 9400GT has 256-1024MB */
1371 return CARD_NVIDIA_GEFORCE_9400GT;
1374 /* Geforce9 - lowend low */
1375 if (strstr(gl_renderer, "9100")
1376 || strstr(gl_renderer, "9200")
1377 || strstr(gl_renderer, "9300")
1378 || strstr(gl_renderer, "G 100"))
1380 *vidmem = 256; /* The 9100-9300 cards have 256MB */
1381 return CARD_NVIDIA_GEFORCE_9200;
1384 /* Geforce8 - highend */
1385 if (strstr(gl_renderer, "8800"))
1387 *vidmem = 320; /* The 8800GTS uses 320MB, a 8800GTX can have 768MB */
1388 return CARD_NVIDIA_GEFORCE_8800GTS;
1391 /* Geforce8 - midend mobile */
1392 if (strstr(gl_renderer, "8600 M"))
1395 return CARD_NVIDIA_GEFORCE_8600MGT;
1398 /* Geforce8 - midend */
1399 if (strstr(gl_renderer, "8600")
1400 || strstr(gl_renderer, "8700"))
1403 return CARD_NVIDIA_GEFORCE_8600GT;
1406 /* Geforce8 - lowend */
1407 if (strstr(gl_renderer, "8100")
1408 || strstr(gl_renderer, "8200")
1409 || strstr(gl_renderer, "8300")
1410 || strstr(gl_renderer, "8400")
1411 || strstr(gl_renderer, "8500"))
1413 *vidmem = 128; /* 128-256MB for a 8300, 256-512MB for a 8400 */
1414 return CARD_NVIDIA_GEFORCE_8300GS;
1417 /* Geforce8-compatible fall back if the GPU is not in the list yet */
1419 return CARD_NVIDIA_GEFORCE_8300GS;
1422 /* Both the GeforceFX, 6xxx and 7xxx series support D3D9. The last two types have more
1423 * shader capabilities, so we use the shader capabilities to distinguish between FX and 6xxx/7xxx.
1425 if (WINE_D3D9_CAPABLE(gl_info) && gl_info->supported[NV_VERTEX_PROGRAM3])
1427 /* Geforce7 - highend */
1428 if (strstr(gl_renderer, "7800")
1429 || strstr(gl_renderer, "7900")
1430 || strstr(gl_renderer, "7950")
1431 || strstr(gl_renderer, "Quadro FX 4")
1432 || strstr(gl_renderer, "Quadro FX 5"))
1434 *vidmem = 256; /* A 7800GT uses 256MB while highend 7900 cards can use 512MB */
1435 return CARD_NVIDIA_GEFORCE_7800GT;
1438 /* Geforce7 midend */
1439 if (strstr(gl_renderer, "7600")
1440 || strstr(gl_renderer, "7700"))
1442 *vidmem = 256; /* The 7600 uses 256-512MB */
1443 return CARD_NVIDIA_GEFORCE_7600;
1446 /* Geforce7 lower medium */
1447 if (strstr(gl_renderer, "7400"))
1449 *vidmem = 256; /* The 7400 uses 256-512MB */
1450 return CARD_NVIDIA_GEFORCE_7400;
1453 /* Geforce7 lowend */
1454 if (strstr(gl_renderer, "7300"))
1456 *vidmem = 256; /* Mac Pros with this card have 256 MB */
1457 return CARD_NVIDIA_GEFORCE_7300;
1460 /* Geforce6 highend */
1461 if (strstr(gl_renderer, "6800"))
1463 *vidmem = 128; /* The 6800 uses 128-256MB, the 7600 uses 256-512MB */
1464 return CARD_NVIDIA_GEFORCE_6800;
1467 /* Geforce6 - midend */
1468 if (strstr(gl_renderer, "6600")
1469 || strstr(gl_renderer, "6610")
1470 || strstr(gl_renderer, "6700"))
1472 *vidmem = 128; /* A 6600GT has 128-256MB */
1473 return CARD_NVIDIA_GEFORCE_6600GT;
1476 /* Geforce6/7 lowend */
1478 return CARD_NVIDIA_GEFORCE_6200; /* Geforce 6100/6150/6200/7300/7400/7500 */
1481 if (WINE_D3D9_CAPABLE(gl_info))
1483 /* GeforceFX - highend */
1484 if (strstr(gl_renderer, "5800")
1485 || strstr(gl_renderer, "5900")
1486 || strstr(gl_renderer, "5950")
1487 || strstr(gl_renderer, "Quadro FX"))
1489 *vidmem = 256; /* 5800-5900 cards use 256MB */
1490 return CARD_NVIDIA_GEFORCEFX_5800;
1493 /* GeforceFX - midend */
1494 if (strstr(gl_renderer, "5600")
1495 || strstr(gl_renderer, "5650")
1496 || strstr(gl_renderer, "5700")
1497 || strstr(gl_renderer, "5750"))
1499 *vidmem = 128; /* A 5600 uses 128-256MB */
1500 return CARD_NVIDIA_GEFORCEFX_5600;
1503 /* GeforceFX - lowend */
1504 *vidmem = 64; /* Normal FX5200 cards use 64-256MB; laptop (non-standard) can have less */
1505 return CARD_NVIDIA_GEFORCEFX_5200; /* GeforceFX 5100/5200/5250/5300/5500 */
1508 if (WINE_D3D8_CAPABLE(gl_info))
1510 if (strstr(gl_renderer, "GeForce4 Ti") || strstr(gl_renderer, "Quadro4"))
1512 *vidmem = 64; /* Geforce4 Ti cards have 64-128MB */
1513 return CARD_NVIDIA_GEFORCE4_TI4200; /* Geforce4 Ti4200/Ti4400/Ti4600/Ti4800, Quadro4 */
1516 *vidmem = 64; /* Geforce3 cards have 64-128MB */
1517 return CARD_NVIDIA_GEFORCE3; /* Geforce3 standard/Ti200/Ti500, Quadro DCC */
1520 if (WINE_D3D7_CAPABLE(gl_info))
1522 if (strstr(gl_renderer, "GeForce4 MX"))
1524 /* Most Geforce4MX GPUs have at least 64MB of memory, some
1525 * early models had 32MB but most have 64MB or even 128MB. */
1527 return CARD_NVIDIA_GEFORCE4_MX; /* MX420/MX440/MX460/MX4000 */
1530 if (strstr(gl_renderer, "GeForce2 MX") || strstr(gl_renderer, "Quadro2 MXR"))
1532 *vidmem = 32; /* Geforce2MX GPUs have 32-64MB of video memory */
1533 return CARD_NVIDIA_GEFORCE2_MX; /* Geforce2 standard/MX100/MX200/MX400, Quadro2 MXR */
1536 if (strstr(gl_renderer, "GeForce2") || strstr(gl_renderer, "Quadro2"))
1538 *vidmem = 32; /* Geforce2 GPUs have 32-64MB of video memory */
1539 return CARD_NVIDIA_GEFORCE2; /* Geforce2 GTS/Pro/Ti/Ultra, Quadro2 */
1542 /* Most Geforce1 cards have 32MB, there are also some rare 16
1543 * and 64MB (Dell) models. */
1545 return CARD_NVIDIA_GEFORCE; /* Geforce 256/DDR, Quadro */
1548 if (strstr(gl_renderer, "TNT2"))
1550 *vidmem = 32; /* Most TNT2 boards have 32MB, though there are 16MB boards too */
1551 return CARD_NVIDIA_RIVA_TNT2; /* Riva TNT2 standard/M64/Pro/Ultra */
1554 *vidmem = 16; /* Most TNT boards have 16MB, some rare models have 8MB */
1555 return CARD_NVIDIA_RIVA_TNT; /* Riva TNT, Vanta */
1559 static enum wined3d_pci_device select_card_ati_binary(const struct wined3d_gl_info *gl_info,
1560 const char *gl_renderer, unsigned int *vidmem)
1562 /* See http://developer.amd.com/drivers/pc_vendor_id/Pages/default.aspx
1564 * Beware: renderer string do not match exact card model,
1565 * eg HD 4800 is returned for multiple cards, even for RV790 based ones. */
1566 if (WINE_D3D10_CAPABLE(gl_info))
1568 /* Radeon EG CYPRESS XT / PRO HD5800 - highend */
1569 if (strstr(gl_renderer, "HD 5800") /* Radeon EG CYPRESS HD58xx generic renderer string */
1570 || strstr(gl_renderer, "HD 5850") /* Radeon EG CYPRESS XT */
1571 || strstr(gl_renderer, "HD 5870")) /* Radeon EG CYPRESS PRO */
1573 *vidmem = 1024; /* note: HD58xx cards use 1024MB */
1574 return CARD_ATI_RADEON_HD5800;
1577 /* Radeon EG JUNIPER XT / LE HD5700 - midend */
1578 if (strstr(gl_renderer, "HD 5700") /* Radeon EG JUNIPER HD57xx generic renderer string */
1579 || strstr(gl_renderer, "HD 5750") /* Radeon EG JUNIPER LE */
1580 || strstr(gl_renderer, "HD 5770")) /* Radeon EG JUNIPER XT */
1582 *vidmem = 512; /* note: HD5770 cards use 1024MB and HD5750 cards use 512MB or 1024MB */
1583 return CARD_ATI_RADEON_HD5700;
1586 /* Radeon R7xx HD4800 - highend */
1587 if (strstr(gl_renderer, "HD 4800") /* Radeon RV7xx HD48xx generic renderer string */
1588 || strstr(gl_renderer, "HD 4830") /* Radeon RV770 */
1589 || strstr(gl_renderer, "HD 4850") /* Radeon RV770 */
1590 || strstr(gl_renderer, "HD 4870") /* Radeon RV770 */
1591 || strstr(gl_renderer, "HD 4890")) /* Radeon RV790 */
1593 *vidmem = 512; /* note: HD4890 cards use 1024MB */
1594 return CARD_ATI_RADEON_HD4800;
1597 /* Radeon R740 HD4700 - midend */
1598 if (strstr(gl_renderer, "HD 4700") /* Radeon RV770 */
1599 || strstr(gl_renderer, "HD 4770")) /* Radeon RV740 */
1602 return CARD_ATI_RADEON_HD4700;
1605 /* Radeon R730 HD4600 - midend */
1606 if (strstr(gl_renderer, "HD 4600") /* Radeon RV730 */
1607 || strstr(gl_renderer, "HD 4650") /* Radeon RV730 */
1608 || strstr(gl_renderer, "HD 4670")) /* Radeon RV730 */
1611 return CARD_ATI_RADEON_HD4600;
1614 /* Radeon R710 HD4500/HD4350 - lowend */
1615 if (strstr(gl_renderer, "HD 4350") /* Radeon RV710 */
1616 || strstr(gl_renderer, "HD 4550")) /* Radeon RV710 */
1619 return CARD_ATI_RADEON_HD4350;
1622 /* Radeon R6xx HD2900/HD3800 - highend */
1623 if (strstr(gl_renderer, "HD 2900")
1624 || strstr(gl_renderer, "HD 3870")
1625 || strstr(gl_renderer, "HD 3850"))
1627 *vidmem = 512; /* HD2900/HD3800 uses 256-1024MB */
1628 return CARD_ATI_RADEON_HD2900;
1631 /* Radeon R6xx HD2600/HD3600 - midend; HD3830 is China-only midend */
1632 if (strstr(gl_renderer, "HD 2600")
1633 || strstr(gl_renderer, "HD 3830")
1634 || strstr(gl_renderer, "HD 3690")
1635 || strstr(gl_renderer, "HD 3650"))
1637 *vidmem = 256; /* HD2600/HD3600 uses 256-512MB */
1638 return CARD_ATI_RADEON_HD2600;
1641 /* Radeon R6xx HD2350/HD2400/HD3400 - lowend
1642 * Note HD2300=DX9, HD2350=DX10 */
1643 if (strstr(gl_renderer, "HD 2350")
1644 || strstr(gl_renderer, "HD 2400")
1645 || strstr(gl_renderer, "HD 3470")
1646 || strstr(gl_renderer, "HD 3450")
1647 || strstr(gl_renderer, "HD 3430")
1648 || strstr(gl_renderer, "HD 3400"))
1650 *vidmem = 256; /* HD2350/2400 use 256MB, HD34xx use 256-512MB */
1651 return CARD_ATI_RADEON_HD2350;
1654 /* Radeon R6xx/R7xx integrated */
1655 if (strstr(gl_renderer, "HD 3100")
1656 || strstr(gl_renderer, "HD 3200")
1657 || strstr(gl_renderer, "HD 3300"))
1659 *vidmem = 128; /* 128MB */
1660 return CARD_ATI_RADEON_HD3200;
1663 /* Default for when no GPU has been found */
1664 *vidmem = 128; /* 128MB */
1665 return CARD_ATI_RADEON_HD3200;
1668 if (WINE_D3D8_CAPABLE(gl_info))
1671 if (strstr(gl_renderer, "X1600")
1672 || strstr(gl_renderer, "X1650")
1673 || strstr(gl_renderer, "X1800")
1674 || strstr(gl_renderer, "X1900")
1675 || strstr(gl_renderer, "X1950"))
1677 *vidmem = 128; /* X1600 uses 128-256MB, >=X1800 uses 256MB */
1678 return CARD_ATI_RADEON_X1600;
1681 /* Radeon R4xx + X1300/X1400/X1450/X1550/X2300/X2500/HD2300 (lowend R5xx)
1682 * Note X2300/X2500/HD2300 are R5xx GPUs with a 2xxx naming but they are still DX9-only */
1683 if (strstr(gl_renderer, "X700")
1684 || strstr(gl_renderer, "X800")
1685 || strstr(gl_renderer, "X850")
1686 || strstr(gl_renderer, "X1300")
1687 || strstr(gl_renderer, "X1400")
1688 || strstr(gl_renderer, "X1450")
1689 || strstr(gl_renderer, "X1550")
1690 || strstr(gl_renderer, "X2300")
1691 || strstr(gl_renderer, "X2500")
1692 || strstr(gl_renderer, "HD 2300")
1695 *vidmem = 128; /* x700/x8*0 use 128-256MB, >=x1300 128-512MB */
1696 return CARD_ATI_RADEON_X700;
1699 /* Radeon Xpress Series - onboard, DX9b, Shader 2.0, 300-400MHz */
1700 if (strstr(gl_renderer, "Radeon Xpress"))
1702 *vidmem = 64; /* Shared RAM, BIOS configurable, 64-256M */
1703 return CARD_ATI_RADEON_XPRESS_200M;
1707 *vidmem = 64; /* Radeon 9500 uses 64MB, higher models use up to 256MB */
1708 return CARD_ATI_RADEON_9500; /* Radeon 9500/9550/9600/9700/9800/X300/X550/X600 */
1711 if (WINE_D3D8_CAPABLE(gl_info))
1713 *vidmem = 64; /* 8500/9000 cards use mostly 64MB, though there are 32MB and 128MB models */
1714 return CARD_ATI_RADEON_8500; /* Radeon 8500/9000/9100/9200/9300 */
1717 if (WINE_D3D7_CAPABLE(gl_info))
1719 *vidmem = 32; /* There are models with up to 64MB */
1720 return CARD_ATI_RADEON_7200; /* Radeon 7000/7100/7200/7500 */
1723 *vidmem = 16; /* There are 16-32MB models */
1724 return CARD_ATI_RAGE_128PRO;
1728 static enum wined3d_pci_device select_card_intel_binary(const struct wined3d_gl_info *gl_info,
1729 const char *gl_renderer, unsigned int *vidmem)
1731 if (strstr(gl_renderer, "X3100"))
1733 /* MacOS calls the card GMA X3100, otherwise known as GM965/GL960 */
1735 return CARD_INTEL_X3100;
1738 if (strstr(gl_renderer, "GMA 950") || strstr(gl_renderer, "945GM"))
1740 /* MacOS calls the card GMA 950, but everywhere else the PCI ID is named 945GM */
1742 return CARD_INTEL_I945GM;
1745 if (strstr(gl_renderer, "915GM")) return CARD_INTEL_I915GM;
1746 if (strstr(gl_renderer, "915G")) return CARD_INTEL_I915G;
1747 if (strstr(gl_renderer, "865G")) return CARD_INTEL_I865G;
1748 if (strstr(gl_renderer, "855G")) return CARD_INTEL_I855G;
1749 if (strstr(gl_renderer, "830G")) return CARD_INTEL_I830G;
1750 return CARD_INTEL_I915G;
1754 static enum wined3d_pci_device select_card_ati_mesa(const struct wined3d_gl_info *gl_info,
1755 const char *gl_renderer, unsigned int *vidmem)
1757 /* See http://developer.amd.com/drivers/pc_vendor_id/Pages/default.aspx
1759 * Beware: renderer string do not match exact card model,
1760 * eg HD 4800 is returned for multiple cards, even for RV790 based ones. */
1761 if (strstr(gl_renderer, "Gallium"))
1763 /* Radeon R7xx HD4800 - highend */
1764 if (strstr(gl_renderer, "R700") /* Radeon R7xx HD48xx generic renderer string */
1765 || strstr(gl_renderer, "RV770") /* Radeon RV770 */
1766 || strstr(gl_renderer, "RV790")) /* Radeon RV790 */
1768 *vidmem = 512; /* note: HD4890 cards use 1024MB */
1769 return CARD_ATI_RADEON_HD4800;
1772 /* Radeon R740 HD4700 - midend */
1773 if (strstr(gl_renderer, "RV740")) /* Radeon RV740 */
1776 return CARD_ATI_RADEON_HD4700;
1779 /* Radeon R730 HD4600 - midend */
1780 if (strstr(gl_renderer, "RV730")) /* Radeon RV730 */
1783 return CARD_ATI_RADEON_HD4600;
1786 /* Radeon R710 HD4500/HD4350 - lowend */
1787 if (strstr(gl_renderer, "RV710")) /* Radeon RV710 */
1790 return CARD_ATI_RADEON_HD4350;
1793 /* Radeon R6xx HD2900/HD3800 - highend */
1794 if (strstr(gl_renderer, "R600")
1795 || strstr(gl_renderer, "RV670")
1796 || strstr(gl_renderer, "R680"))
1798 *vidmem = 512; /* HD2900/HD3800 uses 256-1024MB */
1799 return CARD_ATI_RADEON_HD2900;
1802 /* Radeon R6xx HD2600/HD3600 - midend; HD3830 is China-only midend */
1803 if (strstr(gl_renderer, "RV630")
1804 || strstr(gl_renderer, "RV635"))
1806 *vidmem = 256; /* HD2600/HD3600 uses 256-512MB */
1807 return CARD_ATI_RADEON_HD2600;
1810 /* Radeon R6xx HD2350/HD2400/HD3400 - lowend */
1811 if (strstr(gl_renderer, "RV610")
1812 || strstr(gl_renderer, "RV620"))
1814 *vidmem = 256; /* HD2350/2400 use 256MB, HD34xx use 256-512MB */
1815 return CARD_ATI_RADEON_HD2350;
1818 /* Radeon R6xx/R7xx integrated */
1819 if (strstr(gl_renderer, "RS780")
1820 || strstr(gl_renderer, "RS880"))
1822 *vidmem = 128; /* 128MB */
1823 return CARD_ATI_RADEON_HD3200;
1827 if (strstr(gl_renderer, "RV530")
1828 || strstr(gl_renderer, "RV535")
1829 || strstr(gl_renderer, "RV560")
1830 || strstr(gl_renderer, "R520")
1831 || strstr(gl_renderer, "RV570")
1832 || strstr(gl_renderer, "R580"))
1834 *vidmem = 128; /* X1600 uses 128-256MB, >=X1800 uses 256MB */
1835 return CARD_ATI_RADEON_X1600;
1838 /* Radeon R4xx + X1300/X1400/X1450/X1550/X2300 (lowend R5xx) */
1839 if (strstr(gl_renderer, "R410")
1840 || strstr(gl_renderer, "R420")
1841 || strstr(gl_renderer, "R423")
1842 || strstr(gl_renderer, "R430")
1843 || strstr(gl_renderer, "R480")
1844 || strstr(gl_renderer, "R481")
1845 || strstr(gl_renderer, "RV410")
1846 || strstr(gl_renderer, "RV515")
1847 || strstr(gl_renderer, "RV516"))
1849 *vidmem = 128; /* x700/x8*0 use 128-256MB, >=x1300 128-512MB */
1850 return CARD_ATI_RADEON_X700;
1853 /* Radeon Xpress Series - onboard, DX9b, Shader 2.0, 300-400MHz */
1854 if (strstr(gl_renderer, "RS400")
1855 || strstr(gl_renderer, "RS480")
1856 || strstr(gl_renderer, "RS482")
1857 || strstr(gl_renderer, "RS485")
1858 || strstr(gl_renderer, "RS600")
1859 || strstr(gl_renderer, "RS690")
1860 || strstr(gl_renderer, "RS740"))
1862 *vidmem = 64; /* Shared RAM, BIOS configurable, 64-256M */
1863 return CARD_ATI_RADEON_XPRESS_200M;
1867 if (strstr(gl_renderer, "R300")
1868 || strstr(gl_renderer, "RV350")
1869 || strstr(gl_renderer, "RV351")
1870 || strstr(gl_renderer, "RV360")
1871 || strstr(gl_renderer, "RV370")
1872 || strstr(gl_renderer, "R350")
1873 || strstr(gl_renderer, "R360"))
1875 *vidmem = 64; /* Radeon 9500 uses 64MB, higher models use up to 256MB */
1876 return CARD_ATI_RADEON_9500; /* Radeon 9500/9550/9600/9700/9800/X300/X550/X600 */
1880 if (WINE_D3D9_CAPABLE(gl_info))
1882 /* Radeon R7xx HD4800 - highend */
1883 if (strstr(gl_renderer, "(R700") /* Radeon R7xx HD48xx generic renderer string */
1884 || strstr(gl_renderer, "(RV770") /* Radeon RV770 */
1885 || strstr(gl_renderer, "(RV790")) /* Radeon RV790 */
1887 *vidmem = 512; /* note: HD4890 cards use 1024MB */
1888 return CARD_ATI_RADEON_HD4800;
1891 /* Radeon R740 HD4700 - midend */
1892 if (strstr(gl_renderer, "(RV740")) /* Radeon RV740 */
1895 return CARD_ATI_RADEON_HD4700;
1898 /* Radeon R730 HD4600 - midend */
1899 if (strstr(gl_renderer, "(RV730")) /* Radeon RV730 */
1902 return CARD_ATI_RADEON_HD4600;
1905 /* Radeon R710 HD4500/HD4350 - lowend */
1906 if (strstr(gl_renderer, "(RV710")) /* Radeon RV710 */
1909 return CARD_ATI_RADEON_HD4350;
1912 /* Radeon R6xx HD2900/HD3800 - highend */
1913 if (strstr(gl_renderer, "(R600")
1914 || strstr(gl_renderer, "(RV670")
1915 || strstr(gl_renderer, "(R680"))
1917 *vidmem = 512; /* HD2900/HD3800 uses 256-1024MB */
1918 return CARD_ATI_RADEON_HD2900;
1921 /* Radeon R6xx HD2600/HD3600 - midend; HD3830 is China-only midend */
1922 if (strstr(gl_renderer, "(RV630")
1923 || strstr(gl_renderer, "(RV635"))
1925 *vidmem = 256; /* HD2600/HD3600 uses 256-512MB */
1926 return CARD_ATI_RADEON_HD2600;
1929 /* Radeon R6xx HD2300/HD2400/HD3400 - lowend */
1930 if (strstr(gl_renderer, "(RV610")
1931 || strstr(gl_renderer, "(RV620"))
1933 *vidmem = 256; /* HD2350/2400 use 256MB, HD34xx use 256-512MB */
1934 return CARD_ATI_RADEON_HD2350;
1937 /* Radeon R6xx/R7xx integrated */
1938 if (strstr(gl_renderer, "(RS780")
1939 || strstr(gl_renderer, "(RS880"))
1941 *vidmem = 128; /* 128MB */
1942 return CARD_ATI_RADEON_HD3200;
1946 if (WINE_D3D8_CAPABLE(gl_info))
1948 *vidmem = 64; /* 8500/9000 cards use mostly 64MB, though there are 32MB and 128MB models */
1949 return CARD_ATI_RADEON_8500; /* Radeon 8500/9000/9100/9200/9300 */
1952 if (WINE_D3D7_CAPABLE(gl_info))
1954 *vidmem = 32; /* There are models with up to 64MB */
1955 return CARD_ATI_RADEON_7200; /* Radeon 7000/7100/7200/7500 */
1958 *vidmem = 16; /* There are 16-32MB models */
1959 return CARD_ATI_RAGE_128PRO;
1963 static enum wined3d_pci_device select_card_nvidia_mesa(const struct wined3d_gl_info *gl_info,
1964 const char *gl_renderer, unsigned int *vidmem)
1966 FIXME_(d3d_caps)("Card selection not handled for Mesa Nouveau driver\n");
1967 if (WINE_D3D9_CAPABLE(gl_info)) return CARD_NVIDIA_GEFORCEFX_5600;
1968 if (WINE_D3D8_CAPABLE(gl_info)) return CARD_NVIDIA_GEFORCE3;
1969 if (WINE_D3D7_CAPABLE(gl_info)) return CARD_NVIDIA_GEFORCE;
1970 if (WINE_D3D6_CAPABLE(gl_info)) return CARD_NVIDIA_RIVA_TNT;
1971 return CARD_NVIDIA_RIVA_128;
1974 static enum wined3d_pci_device select_card_intel_mesa(const struct wined3d_gl_info *gl_info,
1975 const char *gl_renderer, unsigned int *vidmem)
1977 FIXME_(d3d_caps)("Card selection not handled for Mesa Intel driver\n");
1978 return CARD_INTEL_I915G;
1982 struct vendor_card_selection
1984 enum wined3d_gl_vendor gl_vendor;
1985 enum wined3d_pci_vendor card_vendor;
1986 const char *description; /* Description of the card selector i.e. Apple OS/X Intel */
1987 enum wined3d_pci_device (*select_card)(const struct wined3d_gl_info *gl_info, const char *gl_renderer,
1988 unsigned int *vidmem );
1991 static const struct vendor_card_selection vendor_card_select_table[] =
1993 {GL_VENDOR_NVIDIA, HW_VENDOR_NVIDIA, "Nvidia binary driver", select_card_nvidia_binary},
1994 {GL_VENDOR_APPLE, HW_VENDOR_NVIDIA, "Apple OSX NVidia binary driver", select_card_nvidia_binary},
1995 {GL_VENDOR_APPLE, HW_VENDOR_ATI, "Apple OSX AMD/ATI binary driver", select_card_ati_binary},
1996 {GL_VENDOR_APPLE, HW_VENDOR_INTEL, "Apple OSX Intel binary driver", select_card_intel_binary},
1997 {GL_VENDOR_FGLRX, HW_VENDOR_ATI, "AMD/ATI binary driver", select_card_ati_binary},
1998 {GL_VENDOR_MESA, HW_VENDOR_ATI, "Mesa AMD/ATI driver", select_card_ati_mesa},
1999 {GL_VENDOR_MESA, HW_VENDOR_NVIDIA, "Mesa Nouveau driver", select_card_nvidia_mesa},
2000 {GL_VENDOR_MESA, HW_VENDOR_INTEL, "Mesa Intel driver", select_card_intel_mesa},
2001 {GL_VENDOR_INTEL, HW_VENDOR_INTEL, "Mesa Intel driver", select_card_intel_mesa}
2005 static enum wined3d_pci_device wined3d_guess_card(const struct wined3d_gl_info *gl_info, const char *gl_renderer,
2006 enum wined3d_gl_vendor *gl_vendor, enum wined3d_pci_vendor *card_vendor, unsigned int *vidmem)
2008 /* Above is a list of Nvidia and ATI GPUs. Both vendors have dozens of
2009 * different GPUs with roughly the same features. In most cases GPUs from a
2010 * certain family differ in clockspeeds, the amount of video memory and the
2011 * number of shader pipelines.
2013 * A Direct3D device object contains the PCI id (vendor + device) of the
2014 * videocard which is used for rendering. Various applications use this
2015 * information to get a rough estimation of the features of the card and
2016 * some might use it for enabling 3d effects only on certain types of
2017 * videocards. In some cases games might even use it to work around bugs
2018 * which happen on certain videocards/driver combinations. The problem is
2019 * that OpenGL only exposes a rendering string containing the name of the
2020 * videocard and not the PCI id.
2022 * Various games depend on the PCI id, so somehow we need to provide one.
2023 * A simple option is to parse the renderer string and translate this to
2024 * the right PCI id. This is a lot of work because there are more than 200
2025 * GPUs just for Nvidia. Various cards share the same renderer string, so
2026 * the amount of code might be 'small' but there are quite a number of
2027 * exceptions which would make this a pain to maintain. Another way would
2028 * be to query the PCI id from the operating system (assuming this is the
2029 * videocard which is used for rendering which is not always the case).
2030 * This would work but it is not very portable. Second it would not work
2031 * well in, let's say, a remote X situation in which the amount of 3d
2032 * features which can be used is limited.
2034 * As said most games only use the PCI id to get an indication of the
2035 * capabilities of the card. It doesn't really matter if the given id is
2036 * the correct one if we return the id of a card with similar 3d features.
2038 * The code below checks the OpenGL capabilities of a videocard and matches
2039 * that to a certain level of Direct3D functionality. Once a card passes
2040 * the Direct3D9 check, we know that the card (in case of Nvidia) is at
2041 * least a GeforceFX. To give a better estimate we do a basic check on the
2042 * renderer string but if that won't pass we return a default card. This
2043 * way is better than maintaining a full card database as even without a
2044 * full database we can return a card with similar features. Second the
2045 * size of the database can be made quite small because when you know what
2046 * type of 3d functionality a card has, you know to which GPU family the
2047 * GPU must belong. Because of this you only have to check a small part of
2048 * the renderer string to distinguishes between different models from that
2051 * The code also selects a default amount of video memory which we will
2052 * use for an estimation of the amount of free texture memory. In case of
2053 * real D3D the amount of texture memory includes video memory and system
2054 * memory (to be specific AGP memory or in case of PCIE TurboCache /
2055 * HyperMemory). We don't know how much system memory can be addressed by
2056 * the system but we can make a reasonable estimation about the amount of
2057 * video memory. If the value is slightly wrong it doesn't matter as we
2058 * didn't include AGP-like memory which makes the amount of addressable
2059 * memory higher and second OpenGL isn't that critical it moves to system
2060 * memory behind our backs if really needed. Note that the amount of video
2061 * memory can be overruled using a registry setting. */
2065 for (i = 0; i < (sizeof(vendor_card_select_table) / sizeof(*vendor_card_select_table)); ++i)
2067 if ((vendor_card_select_table[i].gl_vendor != *gl_vendor)
2068 || (vendor_card_select_table[i].card_vendor != *card_vendor))
2070 TRACE_(d3d_caps)("Applying card_selector \"%s\".\n", vendor_card_select_table[i].description);
2071 return vendor_card_select_table[i].select_card(gl_info, gl_renderer, vidmem);
2074 FIXME_(d3d_caps)("No card selector available for GL vendor %d and card vendor %04x.\n",
2075 *gl_vendor, *card_vendor);
2077 /* Default to generic Nvidia hardware based on the supported OpenGL extensions. The choice
2078 * for Nvidia was because the hardware and drivers they make are of good quality. This makes
2079 * them a good generic choice. */
2080 *card_vendor = HW_VENDOR_NVIDIA;
2081 if (WINE_D3D9_CAPABLE(gl_info)) return CARD_NVIDIA_GEFORCEFX_5600;
2082 if (WINE_D3D8_CAPABLE(gl_info)) return CARD_NVIDIA_GEFORCE3;
2083 if (WINE_D3D7_CAPABLE(gl_info)) return CARD_NVIDIA_GEFORCE;
2084 if (WINE_D3D6_CAPABLE(gl_info)) return CARD_NVIDIA_RIVA_TNT;
2085 return CARD_NVIDIA_RIVA_128;
2088 static const struct fragment_pipeline *select_fragment_implementation(struct wined3d_adapter *adapter)
2090 const struct wined3d_gl_info *gl_info = &adapter->gl_info;
2091 int vs_selected_mode, ps_selected_mode;
2093 select_shader_mode(gl_info, &ps_selected_mode, &vs_selected_mode);
2094 if ((ps_selected_mode == SHADER_ARB || ps_selected_mode == SHADER_GLSL)
2095 && gl_info->supported[ARB_FRAGMENT_PROGRAM]) return &arbfp_fragment_pipeline;
2096 else if (ps_selected_mode == SHADER_ATI) return &atifs_fragment_pipeline;
2097 else if (gl_info->supported[NV_REGISTER_COMBINERS]
2098 && gl_info->supported[NV_TEXTURE_SHADER2]) return &nvts_fragment_pipeline;
2099 else if (gl_info->supported[NV_REGISTER_COMBINERS]) return &nvrc_fragment_pipeline;
2100 else return &ffp_fragment_pipeline;
2103 static const shader_backend_t *select_shader_backend(struct wined3d_adapter *adapter)
2105 int vs_selected_mode, ps_selected_mode;
2107 select_shader_mode(&adapter->gl_info, &ps_selected_mode, &vs_selected_mode);
2108 if (vs_selected_mode == SHADER_GLSL || ps_selected_mode == SHADER_GLSL) return &glsl_shader_backend;
2109 if (vs_selected_mode == SHADER_ARB || ps_selected_mode == SHADER_ARB) return &arb_program_shader_backend;
2110 return &none_shader_backend;
2113 static const struct blit_shader *select_blit_implementation(struct wined3d_adapter *adapter)
2115 const struct wined3d_gl_info *gl_info = &adapter->gl_info;
2116 int vs_selected_mode, ps_selected_mode;
2118 select_shader_mode(gl_info, &ps_selected_mode, &vs_selected_mode);
2119 if ((ps_selected_mode == SHADER_ARB || ps_selected_mode == SHADER_GLSL)
2120 && gl_info->supported[ARB_FRAGMENT_PROGRAM]) return &arbfp_blit;
2121 else return &ffp_blit;
2124 /* Context activation is done by the caller. */
2125 static BOOL IWineD3DImpl_FillGLCaps(struct wined3d_adapter *adapter)
2127 struct wined3d_driver_info *driver_info = &adapter->driver_info;
2128 struct wined3d_gl_info *gl_info = &adapter->gl_info;
2129 const char *GL_Extensions = NULL;
2130 const char *WGL_Extensions = NULL;
2131 const char *gl_vendor_str, *gl_renderer_str, *gl_version_str;
2132 struct fragment_caps fragment_caps;
2133 enum wined3d_gl_vendor gl_vendor;
2134 enum wined3d_pci_vendor card_vendor;
2135 enum wined3d_pci_device device;
2137 GLfloat gl_floatv[2];
2140 unsigned int vidmem=0;
2144 TRACE_(d3d_caps)("(%p)\n", gl_info);
2148 gl_renderer_str = (const char *)glGetString(GL_RENDERER);
2149 TRACE_(d3d_caps)("GL_RENDERER: %s.\n", debugstr_a(gl_renderer_str));
2150 if (!gl_renderer_str)
2153 ERR_(d3d_caps)("Received a NULL GL_RENDERER.\n");
2157 gl_vendor_str = (const char *)glGetString(GL_VENDOR);
2158 TRACE_(d3d_caps)("GL_VENDOR: %s.\n", debugstr_a(gl_vendor_str));
2162 ERR_(d3d_caps)("Received a NULL GL_VENDOR.\n");
2166 /* Parse the GL_VERSION field into major and minor information */
2167 gl_version_str = (const char *)glGetString(GL_VERSION);
2168 TRACE_(d3d_caps)("GL_VERSION: %s.\n", debugstr_a(gl_version_str));
2169 if (!gl_version_str)
2172 ERR_(d3d_caps)("Received a NULL GL_VERSION.\n");
2175 gl_version = wined3d_parse_gl_version(gl_version_str);
2178 * Initialize openGL extension related variables
2179 * with Default values
2181 memset(gl_info->supported, 0, sizeof(gl_info->supported));
2182 gl_info->limits.blends = 1;
2183 gl_info->limits.buffers = 1;
2184 gl_info->limits.textures = 1;
2185 gl_info->limits.fragment_samplers = 1;
2186 gl_info->limits.vertex_samplers = 0;
2187 gl_info->limits.combined_samplers = gl_info->limits.fragment_samplers + gl_info->limits.vertex_samplers;
2188 gl_info->limits.sampler_stages = 1;
2189 gl_info->limits.glsl_vs_float_constants = 0;
2190 gl_info->limits.glsl_ps_float_constants = 0;
2191 gl_info->limits.arb_vs_float_constants = 0;
2192 gl_info->limits.arb_vs_native_constants = 0;
2193 gl_info->limits.arb_vs_instructions = 0;
2194 gl_info->limits.arb_vs_temps = 0;
2195 gl_info->limits.arb_ps_float_constants = 0;
2196 gl_info->limits.arb_ps_local_constants = 0;
2197 gl_info->limits.arb_ps_instructions = 0;
2198 gl_info->limits.arb_ps_temps = 0;
2200 /* Retrieve opengl defaults */
2201 glGetIntegerv(GL_MAX_CLIP_PLANES, &gl_max);
2202 gl_info->limits.clipplanes = min(WINED3DMAXUSERCLIPPLANES, gl_max);
2203 TRACE_(d3d_caps)("ClipPlanes support - num Planes=%d\n", gl_max);
2205 glGetIntegerv(GL_MAX_LIGHTS, &gl_max);
2206 gl_info->limits.lights = gl_max;
2207 TRACE_(d3d_caps)("Lights support - max lights=%d\n", gl_max);
2209 glGetIntegerv(GL_MAX_TEXTURE_SIZE, &gl_max);
2210 gl_info->limits.texture_size = gl_max;
2211 TRACE_(d3d_caps)("Maximum texture size support - max texture size=%d\n", gl_max);
2213 glGetFloatv(GL_ALIASED_POINT_SIZE_RANGE, gl_floatv);
2214 gl_info->limits.pointsize_min = gl_floatv[0];
2215 gl_info->limits.pointsize_max = gl_floatv[1];
2216 TRACE_(d3d_caps)("Maximum point size support - max point size=%f\n", gl_floatv[1]);
2218 /* Parse the gl supported features, in theory enabling parts of our code appropriately. */
2219 GL_Extensions = (const char *)glGetString(GL_EXTENSIONS);
2223 ERR_(d3d_caps)("Received a NULL GL_EXTENSIONS.\n");
2229 TRACE_(d3d_caps)("GL_Extensions reported:\n");
2231 gl_info->supported[WINED3D_GL_EXT_NONE] = TRUE;
2233 while (*GL_Extensions)
2236 char current_ext[256];
2238 while (isspace(*GL_Extensions)) ++GL_Extensions;
2239 start = GL_Extensions;
2240 while (!isspace(*GL_Extensions) && *GL_Extensions) ++GL_Extensions;
2242 len = GL_Extensions - start;
2243 if (!len || len >= sizeof(current_ext)) continue;
2245 memcpy(current_ext, start, len);
2246 current_ext[len] = '\0';
2247 TRACE_(d3d_caps)("- %s\n", debugstr_a(current_ext));
2249 for (i = 0; i < (sizeof(EXTENSION_MAP) / sizeof(*EXTENSION_MAP)); ++i)
2251 if (!strcmp(current_ext, EXTENSION_MAP[i].extension_string))
2253 TRACE_(d3d_caps)(" FOUND: %s support.\n", EXTENSION_MAP[i].extension_string);
2254 gl_info->supported[EXTENSION_MAP[i].extension] = TRUE;
2260 /* Now work out what GL support this card really has */
2261 #define USE_GL_FUNC(type, pfn, ext, replace) \
2263 DWORD ver = ver_for_ext(ext); \
2264 if (gl_info->supported[ext]) gl_info->pfn = (type)pwglGetProcAddress(#pfn); \
2265 else if (ver && ver <= gl_version) gl_info->pfn = (type)pwglGetProcAddress(#replace); \
2266 else gl_info->pfn = NULL; \
2271 #define USE_GL_FUNC(type, pfn, ext, replace) gl_info->pfn = (type)pwglGetProcAddress(#pfn);
2277 /* Now mark all the extensions supported which are included in the opengl core version. Do this *after*
2278 * loading the functions, otherwise the code above will load the extension entry points instead of the
2279 * core functions, which may not work. */
2280 for (i = 0; i < (sizeof(EXTENSION_MAP) / sizeof(*EXTENSION_MAP)); ++i)
2282 if (!gl_info->supported[EXTENSION_MAP[i].extension]
2283 && EXTENSION_MAP[i].version <= gl_version && EXTENSION_MAP[i].version)
2285 TRACE_(d3d_caps)(" GL CORE: %s support.\n", EXTENSION_MAP[i].extension_string);
2286 gl_info->supported[EXTENSION_MAP[i].extension] = TRUE;
2290 if (gl_version >= MAKEDWORD_VERSION(2, 0)) gl_info->supported[WINED3D_GL_VERSION_2_0] = TRUE;
2292 if (gl_info->supported[APPLE_FENCE])
2294 /* GL_NV_fence and GL_APPLE_fence provide the same functionality basically.
2295 * The apple extension interacts with some other apple exts. Disable the NV
2296 * extension if the apple one is support to prevent confusion in other parts
2298 gl_info->supported[NV_FENCE] = FALSE;
2300 if (gl_info->supported[APPLE_FLOAT_PIXELS])
2302 /* GL_APPLE_float_pixels == GL_ARB_texture_float + GL_ARB_half_float_pixel
2304 * The enums are the same:
2305 * GL_RGBA16F_ARB = GL_RGBA_FLOAT16_APPLE = 0x881A
2306 * GL_RGB16F_ARB = GL_RGB_FLOAT16_APPLE = 0x881B
2307 * GL_RGBA32F_ARB = GL_RGBA_FLOAT32_APPLE = 0x8814
2308 * GL_RGB32F_ARB = GL_RGB_FLOAT32_APPLE = 0x8815
2309 * GL_HALF_FLOAT_ARB = GL_HALF_APPLE = 0x140B
2311 if (!gl_info->supported[ARB_TEXTURE_FLOAT])
2313 TRACE_(d3d_caps)(" IMPLIED: GL_ARB_texture_float support(from GL_APPLE_float_pixels.\n");
2314 gl_info->supported[ARB_TEXTURE_FLOAT] = TRUE;
2316 if (!gl_info->supported[ARB_HALF_FLOAT_PIXEL])
2318 TRACE_(d3d_caps)(" IMPLIED: GL_ARB_half_float_pixel support(from GL_APPLE_float_pixels.\n");
2319 gl_info->supported[ARB_HALF_FLOAT_PIXEL] = TRUE;
2322 if (gl_info->supported[ARB_MAP_BUFFER_RANGE])
2324 /* GL_ARB_map_buffer_range and GL_APPLE_flush_buffer_range provide the same
2325 * functionality. Prefer the ARB extension */
2326 gl_info->supported[APPLE_FLUSH_BUFFER_RANGE] = FALSE;
2328 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
2330 TRACE_(d3d_caps)(" IMPLIED: NVIDIA (NV) Texture Gen Reflection support.\n");
2331 gl_info->supported[NV_TEXGEN_REFLECTION] = TRUE;
2333 if (!gl_info->supported[ARB_DEPTH_CLAMP] && gl_info->supported[NV_DEPTH_CLAMP])
2335 TRACE_(d3d_caps)(" IMPLIED: ARB_depth_clamp support (by NV_depth_clamp).\n");
2336 gl_info->supported[ARB_DEPTH_CLAMP] = TRUE;
2338 if (!gl_info->supported[ARB_VERTEX_ARRAY_BGRA] && gl_info->supported[EXT_VERTEX_ARRAY_BGRA])
2340 TRACE_(d3d_caps)(" IMPLIED: ARB_vertex_array_bgra support (by EXT_vertex_array_bgra).\n");
2341 gl_info->supported[ARB_VERTEX_ARRAY_BGRA] = TRUE;
2343 if (gl_info->supported[NV_TEXTURE_SHADER2])
2345 if (gl_info->supported[NV_REGISTER_COMBINERS])
2347 /* Also disable ATI_FRAGMENT_SHADER if register combiners and texture_shader2
2348 * are supported. The nv extensions provide the same functionality as the
2349 * ATI one, and a bit more(signed pixelformats). */
2350 gl_info->supported[ATI_FRAGMENT_SHADER] = FALSE;
2354 if (gl_info->supported[NV_REGISTER_COMBINERS])
2356 glGetIntegerv(GL_MAX_GENERAL_COMBINERS_NV, &gl_max);
2357 gl_info->limits.general_combiners = gl_max;
2358 TRACE_(d3d_caps)("Max general combiners: %d.\n", gl_max);
2360 if (gl_info->supported[ARB_DRAW_BUFFERS])
2362 glGetIntegerv(GL_MAX_DRAW_BUFFERS_ARB, &gl_max);
2363 gl_info->limits.buffers = gl_max;
2364 TRACE_(d3d_caps)("Max draw buffers: %u.\n", gl_max);
2366 if (gl_info->supported[ARB_MULTITEXTURE])
2368 glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, &gl_max);
2369 gl_info->limits.textures = min(MAX_TEXTURES, gl_max);
2370 TRACE_(d3d_caps)("Max textures: %d.\n", gl_info->limits.textures);
2372 if (gl_info->supported[ARB_FRAGMENT_PROGRAM])
2375 glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS_ARB, &tmp);
2376 gl_info->limits.fragment_samplers = min(MAX_FRAGMENT_SAMPLERS, tmp);
2380 gl_info->limits.fragment_samplers = max(gl_info->limits.fragment_samplers, gl_max);
2382 TRACE_(d3d_caps)("Max fragment samplers: %d.\n", gl_info->limits.fragment_samplers);
2384 if (gl_info->supported[ARB_VERTEX_SHADER])
2387 glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB, &tmp);
2388 gl_info->limits.vertex_samplers = tmp;
2389 glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB, &tmp);
2390 gl_info->limits.combined_samplers = tmp;
2392 /* Loading GLSL sampler uniforms is much simpler if we can assume that the sampler setup
2393 * is known at shader link time. In a vertex shader + pixel shader combination this isn't
2394 * an issue because then the sampler setup only depends on the two shaders. If a pixel
2395 * shader is used with fixed function vertex processing we're fine too because fixed function
2396 * vertex processing doesn't use any samplers. If fixed function fragment processing is
2397 * used we have to make sure that all vertex sampler setups are valid together with all
2398 * possible fixed function fragment processing setups. This is true if vsamplers + MAX_TEXTURES
2399 * <= max_samplers. This is true on all d3d9 cards that support vtf(gf 6 and gf7 cards).
2400 * dx9 radeon cards do not support vertex texture fetch. DX10 cards have 128 samplers, and
2401 * dx9 is limited to 8 fixed function texture stages and 4 vertex samplers. DX10 does not have
2402 * a fixed function pipeline anymore.
2404 * So this is just a check to check that our assumption holds true. If not, write a warning
2405 * and reduce the number of vertex samplers or probably disable vertex texture fetch. */
2406 if (gl_info->limits.vertex_samplers && gl_info->limits.combined_samplers < 12
2407 && MAX_TEXTURES + gl_info->limits.vertex_samplers > gl_info->limits.combined_samplers)
2409 FIXME("OpenGL implementation supports %u vertex samplers and %u total samplers.\n",
2410 gl_info->limits.vertex_samplers, gl_info->limits.combined_samplers);
2411 FIXME("Expected vertex samplers + MAX_TEXTURES(=8) > combined_samplers.\n");
2412 if (gl_info->limits.combined_samplers > MAX_TEXTURES)
2413 gl_info->limits.vertex_samplers = gl_info->limits.combined_samplers - MAX_TEXTURES;
2415 gl_info->limits.vertex_samplers = 0;
2420 gl_info->limits.combined_samplers = gl_info->limits.fragment_samplers;
2422 TRACE_(d3d_caps)("Max vertex samplers: %u.\n", gl_info->limits.vertex_samplers);
2423 TRACE_(d3d_caps)("Max combined samplers: %u.\n", gl_info->limits.combined_samplers);
2425 if (gl_info->supported[ARB_VERTEX_BLEND])
2427 glGetIntegerv(GL_MAX_VERTEX_UNITS_ARB, &gl_max);
2428 gl_info->limits.blends = gl_max;
2429 TRACE_(d3d_caps)("Max blends: %u.\n", gl_info->limits.blends);
2431 if (gl_info->supported[EXT_TEXTURE3D])
2433 glGetIntegerv(GL_MAX_3D_TEXTURE_SIZE_EXT, &gl_max);
2434 gl_info->limits.texture3d_size = gl_max;
2435 TRACE_(d3d_caps)("Max texture3D size: %d.\n", gl_info->limits.texture3d_size);
2437 if (gl_info->supported[EXT_TEXTURE_FILTER_ANISOTROPIC])
2439 glGetIntegerv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &gl_max);
2440 gl_info->limits.anisotropy = gl_max;
2441 TRACE_(d3d_caps)("Max anisotropy: %d.\n", gl_info->limits.anisotropy);
2443 if (gl_info->supported[ARB_FRAGMENT_PROGRAM])
2445 GL_EXTCALL(glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_ENV_PARAMETERS_ARB, &gl_max));
2446 gl_info->limits.arb_ps_float_constants = gl_max;
2447 TRACE_(d3d_caps)("Max ARB_FRAGMENT_PROGRAM float constants: %d.\n", gl_info->limits.arb_ps_float_constants);
2448 GL_EXTCALL(glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB, &gl_max));
2449 gl_info->limits.arb_ps_native_constants = gl_max;
2450 TRACE_(d3d_caps)("Max ARB_FRAGMENT_PROGRAM native float constants: %d.\n",
2451 gl_info->limits.arb_ps_native_constants);
2452 GL_EXTCALL(glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB, &gl_max));
2453 gl_info->limits.arb_ps_temps = gl_max;
2454 TRACE_(d3d_caps)("Max ARB_FRAGMENT_PROGRAM native temporaries: %d.\n", gl_info->limits.arb_ps_temps);
2455 GL_EXTCALL(glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB, &gl_max));
2456 gl_info->limits.arb_ps_instructions = gl_max;
2457 TRACE_(d3d_caps)("Max ARB_FRAGMENT_PROGRAM native instructions: %d.\n", gl_info->limits.arb_ps_instructions);
2458 GL_EXTCALL(glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB, &gl_max));
2459 gl_info->limits.arb_ps_local_constants = gl_max;
2460 TRACE_(d3d_caps)("Max ARB_FRAGMENT_PROGRAM local parameters: %d.\n", gl_info->limits.arb_ps_instructions);
2462 if (gl_info->supported[ARB_VERTEX_PROGRAM])
2464 GL_EXTCALL(glGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_MAX_PROGRAM_ENV_PARAMETERS_ARB, &gl_max));
2465 gl_info->limits.arb_vs_float_constants = gl_max;
2466 TRACE_(d3d_caps)("Max ARB_VERTEX_PROGRAM float constants: %d.\n", gl_info->limits.arb_vs_float_constants);
2467 GL_EXTCALL(glGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB, &gl_max));
2468 gl_info->limits.arb_vs_native_constants = gl_max;
2469 TRACE_(d3d_caps)("Max ARB_VERTEX_PROGRAM native float constants: %d.\n",
2470 gl_info->limits.arb_vs_native_constants);
2471 GL_EXTCALL(glGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB, &gl_max));
2472 gl_info->limits.arb_vs_temps = gl_max;
2473 TRACE_(d3d_caps)("Max ARB_VERTEX_PROGRAM native temporaries: %d.\n", gl_info->limits.arb_vs_temps);
2474 GL_EXTCALL(glGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB, &gl_max));
2475 gl_info->limits.arb_vs_instructions = gl_max;
2476 TRACE_(d3d_caps)("Max ARB_VERTEX_PROGRAM native instructions: %d.\n", gl_info->limits.arb_vs_instructions);
2478 if (test_arb_vs_offset_limit(gl_info)) gl_info->quirks |= WINED3D_QUIRK_ARB_VS_OFFSET_LIMIT;
2480 if (gl_info->supported[ARB_VERTEX_SHADER])
2482 glGetIntegerv(GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB, &gl_max);
2483 gl_info->limits.glsl_vs_float_constants = gl_max / 4;
2484 TRACE_(d3d_caps)("Max ARB_VERTEX_SHADER float constants: %u.\n", gl_info->limits.glsl_vs_float_constants);
2486 if (gl_info->supported[ARB_FRAGMENT_SHADER])
2488 glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB, &gl_max);
2489 gl_info->limits.glsl_ps_float_constants = gl_max / 4;
2490 TRACE_(d3d_caps)("Max ARB_FRAGMENT_SHADER float constants: %u.\n", gl_info->limits.glsl_ps_float_constants);
2491 glGetIntegerv(GL_MAX_VARYING_FLOATS_ARB, &gl_max);
2492 gl_info->limits.glsl_varyings = gl_max;
2493 TRACE_(d3d_caps)("Max GLSL varyings: %u (%u 4 component varyings).\n", gl_max, gl_max / 4);
2495 if (gl_info->supported[ARB_SHADING_LANGUAGE_100])
2497 const char *str = (const char *)glGetString(GL_SHADING_LANGUAGE_VERSION_ARB);
2498 unsigned int major, minor;
2500 TRACE_(d3d_caps)("GLSL version string: %s.\n", debugstr_a(str));
2502 /* The format of the GLSL version string is "major.minor[.release] [vendor info]". */
2503 sscanf(str, "%u.%u", &major, &minor);
2504 gl_info->glsl_version = MAKEDWORD_VERSION(major, minor);
2506 if (gl_info->supported[NV_LIGHT_MAX_EXPONENT])
2508 glGetFloatv(GL_MAX_SHININESS_NV, &gl_info->limits.shininess);
2512 gl_info->limits.shininess = 128.0f;
2514 if (gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO])
2516 /* If we have full NP2 texture support, disable
2517 * GL_ARB_texture_rectangle because we will never use it.
2518 * This saves a few redundant glDisable calls. */
2519 gl_info->supported[ARB_TEXTURE_RECTANGLE] = FALSE;
2521 if (gl_info->supported[ATI_FRAGMENT_SHADER])
2523 /* Disable NV_register_combiners and fragment shader if this is supported.
2524 * generally the NV extensions are preferred over the ATI ones, and this
2525 * extension is disabled if register_combiners and texture_shader2 are both
2526 * supported. So we reach this place only if we have incomplete NV dxlevel 8
2527 * fragment processing support. */
2528 gl_info->supported[NV_REGISTER_COMBINERS] = FALSE;
2529 gl_info->supported[NV_REGISTER_COMBINERS2] = FALSE;
2530 gl_info->supported[NV_TEXTURE_SHADER] = FALSE;
2531 gl_info->supported[NV_TEXTURE_SHADER2] = FALSE;
2533 if (gl_info->supported[NV_HALF_FLOAT])
2535 /* GL_ARB_half_float_vertex is a subset of GL_NV_half_float. */
2536 gl_info->supported[ARB_HALF_FLOAT_VERTEX] = TRUE;
2538 if (gl_info->supported[ARB_POINT_SPRITE])
2540 gl_info->limits.point_sprite_units = gl_info->limits.textures;
2544 gl_info->limits.point_sprite_units = 0;
2546 checkGLcall("extension detection");
2550 adapter->fragment_pipe = select_fragment_implementation(adapter);
2551 adapter->shader_backend = select_shader_backend(adapter);
2552 adapter->blitter = select_blit_implementation(adapter);
2554 adapter->fragment_pipe->get_caps(gl_info, &fragment_caps);
2555 gl_info->limits.texture_stages = fragment_caps.MaxTextureBlendStages;
2556 TRACE_(d3d_caps)("Max texture stages: %u.\n", gl_info->limits.texture_stages);
2558 /* In some cases the number of texture stages can be larger than the number
2559 * of samplers. The GF4 for example can use only 2 samplers (no fragment
2560 * shaders), but 8 texture stages (register combiners). */
2561 gl_info->limits.sampler_stages = max(gl_info->limits.fragment_samplers, gl_info->limits.texture_stages);
2563 if (gl_info->supported[ARB_FRAMEBUFFER_OBJECT])
2565 gl_info->fbo_ops.glIsRenderbuffer = gl_info->glIsRenderbuffer;
2566 gl_info->fbo_ops.glBindRenderbuffer = gl_info->glBindRenderbuffer;
2567 gl_info->fbo_ops.glDeleteRenderbuffers = gl_info->glDeleteRenderbuffers;
2568 gl_info->fbo_ops.glGenRenderbuffers = gl_info->glGenRenderbuffers;
2569 gl_info->fbo_ops.glRenderbufferStorage = gl_info->glRenderbufferStorage;
2570 gl_info->fbo_ops.glRenderbufferStorageMultisample = gl_info->glRenderbufferStorageMultisample;
2571 gl_info->fbo_ops.glGetRenderbufferParameteriv = gl_info->glGetRenderbufferParameteriv;
2572 gl_info->fbo_ops.glIsFramebuffer = gl_info->glIsFramebuffer;
2573 gl_info->fbo_ops.glBindFramebuffer = gl_info->glBindFramebuffer;
2574 gl_info->fbo_ops.glDeleteFramebuffers = gl_info->glDeleteFramebuffers;
2575 gl_info->fbo_ops.glGenFramebuffers = gl_info->glGenFramebuffers;
2576 gl_info->fbo_ops.glCheckFramebufferStatus = gl_info->glCheckFramebufferStatus;
2577 gl_info->fbo_ops.glFramebufferTexture1D = gl_info->glFramebufferTexture1D;
2578 gl_info->fbo_ops.glFramebufferTexture2D = gl_info->glFramebufferTexture2D;
2579 gl_info->fbo_ops.glFramebufferTexture3D = gl_info->glFramebufferTexture3D;
2580 gl_info->fbo_ops.glFramebufferRenderbuffer = gl_info->glFramebufferRenderbuffer;
2581 gl_info->fbo_ops.glGetFramebufferAttachmentParameteriv = gl_info->glGetFramebufferAttachmentParameteriv;
2582 gl_info->fbo_ops.glBlitFramebuffer = gl_info->glBlitFramebuffer;
2583 gl_info->fbo_ops.glGenerateMipmap = gl_info->glGenerateMipmap;
2587 if (gl_info->supported[EXT_FRAMEBUFFER_OBJECT])
2589 gl_info->fbo_ops.glIsRenderbuffer = gl_info->glIsRenderbufferEXT;
2590 gl_info->fbo_ops.glBindRenderbuffer = gl_info->glBindRenderbufferEXT;
2591 gl_info->fbo_ops.glDeleteRenderbuffers = gl_info->glDeleteRenderbuffersEXT;
2592 gl_info->fbo_ops.glGenRenderbuffers = gl_info->glGenRenderbuffersEXT;
2593 gl_info->fbo_ops.glRenderbufferStorage = gl_info->glRenderbufferStorageEXT;
2594 gl_info->fbo_ops.glGetRenderbufferParameteriv = gl_info->glGetRenderbufferParameterivEXT;
2595 gl_info->fbo_ops.glIsFramebuffer = gl_info->glIsFramebufferEXT;
2596 gl_info->fbo_ops.glBindFramebuffer = gl_info->glBindFramebufferEXT;
2597 gl_info->fbo_ops.glDeleteFramebuffers = gl_info->glDeleteFramebuffersEXT;
2598 gl_info->fbo_ops.glGenFramebuffers = gl_info->glGenFramebuffersEXT;
2599 gl_info->fbo_ops.glCheckFramebufferStatus = gl_info->glCheckFramebufferStatusEXT;
2600 gl_info->fbo_ops.glFramebufferTexture1D = gl_info->glFramebufferTexture1DEXT;
2601 gl_info->fbo_ops.glFramebufferTexture2D = gl_info->glFramebufferTexture2DEXT;
2602 gl_info->fbo_ops.glFramebufferTexture3D = gl_info->glFramebufferTexture3DEXT;
2603 gl_info->fbo_ops.glFramebufferRenderbuffer = gl_info->glFramebufferRenderbufferEXT;
2604 gl_info->fbo_ops.glGetFramebufferAttachmentParameteriv = gl_info->glGetFramebufferAttachmentParameterivEXT;
2605 gl_info->fbo_ops.glGenerateMipmap = gl_info->glGenerateMipmapEXT;
2607 else if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
2609 WARN_(d3d_caps)("Framebuffer objects not supported, falling back to backbuffer offscreen rendering mode.\n");
2610 wined3d_settings.offscreen_rendering_mode = ORM_BACKBUFFER;
2612 if (gl_info->supported[EXT_FRAMEBUFFER_BLIT])
2614 gl_info->fbo_ops.glBlitFramebuffer = gl_info->glBlitFramebufferEXT;
2616 if (gl_info->supported[EXT_FRAMEBUFFER_MULTISAMPLE])
2618 gl_info->fbo_ops.glRenderbufferStorageMultisample = gl_info->glRenderbufferStorageMultisampleEXT;
2622 /* MRTs are currently only supported when FBOs are used. */
2623 if (wined3d_settings.offscreen_rendering_mode != ORM_FBO)
2625 gl_info->limits.buffers = 1;
2628 gl_vendor = wined3d_guess_gl_vendor(gl_info, gl_vendor_str, gl_renderer_str);
2629 card_vendor = wined3d_guess_card_vendor(gl_vendor_str, gl_renderer_str);
2630 TRACE_(d3d_caps)("found GL_VENDOR (%s)->(0x%04x/0x%04x)\n", debugstr_a(gl_vendor_str), gl_vendor, card_vendor);
2632 device = wined3d_guess_card(gl_info, gl_renderer_str, &gl_vendor, &card_vendor, &vidmem);
2633 TRACE_(d3d_caps)("FOUND (fake) card: 0x%x (vendor id), 0x%x (device id)\n", card_vendor, device);
2635 /* If we have an estimate use it, else default to 64MB; */
2637 gl_info->vidmem = vidmem*1024*1024; /* convert from MBs to bytes */
2639 gl_info->vidmem = WINE_DEFAULT_VIDMEM;
2641 gl_info->wrap_lookup[WINED3DTADDRESS_WRAP - WINED3DTADDRESS_WRAP] = GL_REPEAT;
2642 gl_info->wrap_lookup[WINED3DTADDRESS_MIRROR - WINED3DTADDRESS_WRAP] =
2643 gl_info->supported[ARB_TEXTURE_MIRRORED_REPEAT] ? GL_MIRRORED_REPEAT_ARB : GL_REPEAT;
2644 gl_info->wrap_lookup[WINED3DTADDRESS_CLAMP - WINED3DTADDRESS_WRAP] = GL_CLAMP_TO_EDGE;
2645 gl_info->wrap_lookup[WINED3DTADDRESS_BORDER - WINED3DTADDRESS_WRAP] =
2646 gl_info->supported[ARB_TEXTURE_BORDER_CLAMP] ? GL_CLAMP_TO_BORDER_ARB : GL_REPEAT;
2647 gl_info->wrap_lookup[WINED3DTADDRESS_MIRRORONCE - WINED3DTADDRESS_WRAP] =
2648 gl_info->supported[ATI_TEXTURE_MIRROR_ONCE] ? GL_MIRROR_CLAMP_TO_EDGE_ATI : GL_REPEAT;
2650 /* Make sure there's an active HDC else the WGL extensions will fail */
2651 hdc = pwglGetCurrentDC();
2653 /* Not all GL drivers might offer WGL extensions e.g. VirtualBox */
2654 if(GL_EXTCALL(wglGetExtensionsStringARB))
2655 WGL_Extensions = GL_EXTCALL(wglGetExtensionsStringARB(hdc));
2657 if (NULL == WGL_Extensions) {
2658 ERR(" WGL_Extensions returns NULL\n");
2660 TRACE_(d3d_caps)("WGL_Extensions reported:\n");
2661 while (*WGL_Extensions != 0x00) {
2665 while (isspace(*WGL_Extensions)) WGL_Extensions++;
2666 Start = WGL_Extensions;
2667 while (!isspace(*WGL_Extensions) && *WGL_Extensions != 0x00) {
2671 len = WGL_Extensions - Start;
2672 if (len == 0 || len >= sizeof(ThisExtn))
2675 memcpy(ThisExtn, Start, len);
2676 ThisExtn[len] = '\0';
2677 TRACE_(d3d_caps)("- %s\n", debugstr_a(ThisExtn));
2679 if (!strcmp(ThisExtn, "WGL_ARB_pixel_format")) {
2680 gl_info->supported[WGL_ARB_PIXEL_FORMAT] = TRUE;
2681 TRACE_(d3d_caps)("FOUND: WGL_ARB_pixel_format support\n");
2683 if (!strcmp(ThisExtn, "WGL_WINE_pixel_format_passthrough")) {
2684 gl_info->supported[WGL_WINE_PIXEL_FORMAT_PASSTHROUGH] = TRUE;
2685 TRACE_(d3d_caps)("FOUND: WGL_WINE_pixel_format_passthrough support\n");
2691 fixup_extensions(gl_info, gl_renderer_str, gl_vendor, card_vendor, device);
2692 init_driver_info(driver_info, card_vendor, device);
2693 add_gl_compat_wrappers(gl_info);
2698 /**********************************************************
2699 * IWineD3D implementation follows
2700 **********************************************************/
2702 static UINT WINAPI IWineD3DImpl_GetAdapterCount (IWineD3D *iface) {
2703 IWineD3DImpl *This = (IWineD3DImpl *)iface;
2705 TRACE_(d3d_caps)("(%p): Reporting %u adapters\n", This, This->adapter_count);
2707 return This->adapter_count;
2710 static HRESULT WINAPI IWineD3DImpl_RegisterSoftwareDevice(IWineD3D *iface, void *init_function)
2712 FIXME("iface %p, init_function %p stub!\n", iface, init_function);
2717 static HMONITOR WINAPI IWineD3DImpl_GetAdapterMonitor(IWineD3D *iface, UINT Adapter) {
2718 IWineD3DImpl *This = (IWineD3DImpl *)iface;
2720 TRACE_(d3d_caps)("(%p)->(%d)\n", This, Adapter);
2722 if (Adapter >= IWineD3DImpl_GetAdapterCount(iface)) {
2726 return MonitorFromPoint(This->adapters[Adapter].monitorPoint, MONITOR_DEFAULTTOPRIMARY);
2729 /* FIXME: GetAdapterModeCount and EnumAdapterModes currently only returns modes
2730 of the same bpp but different resolutions */
2732 /* Note: dx9 supplies a format. Calls from d3d8 supply WINED3DFMT_UNKNOWN */
2733 static UINT WINAPI IWineD3DImpl_GetAdapterModeCount(IWineD3D *iface, UINT Adapter, WINED3DFORMAT Format) {
2734 IWineD3DImpl *This = (IWineD3DImpl *)iface;
2735 TRACE_(d3d_caps)("(%p}->(Adapter: %d, Format: %s)\n", This, Adapter, debug_d3dformat(Format));
2737 if (Adapter >= IWineD3D_GetAdapterCount(iface)) {
2741 /* TODO: Store modes per adapter and read it from the adapter structure */
2742 if (Adapter == 0) { /* Display */
2743 const struct wined3d_format_desc *format_desc = getFormatDescEntry(Format, &This->adapters[Adapter].gl_info);
2744 UINT format_bits = format_desc->byte_count * CHAR_BIT;
2749 memset(&mode, 0, sizeof(mode));
2750 mode.dmSize = sizeof(mode);
2752 while (EnumDisplaySettingsExW(NULL, j, &mode, 0))
2756 if (Format == WINED3DFMT_UNKNOWN)
2758 /* This is for D3D8, do not enumerate P8 here */
2759 if (mode.dmBitsPerPel == 32 || mode.dmBitsPerPel == 16) ++i;
2761 else if (mode.dmBitsPerPel == format_bits)
2767 TRACE_(d3d_caps)("(%p}->(Adapter: %d) => %d (out of %d)\n", This, Adapter, i, j);
2770 FIXME_(d3d_caps)("Adapter not primary display\n");
2775 /* Note: dx9 supplies a format. Calls from d3d8 supply WINED3DFMT_UNKNOWN */
2776 static HRESULT WINAPI IWineD3DImpl_EnumAdapterModes(IWineD3D *iface, UINT Adapter, WINED3DFORMAT Format, UINT Mode, WINED3DDISPLAYMODE* pMode) {
2777 IWineD3DImpl *This = (IWineD3DImpl *)iface;
2778 TRACE_(d3d_caps)("(%p}->(Adapter:%d, mode:%d, pMode:%p, format:%s)\n", This, Adapter, Mode, pMode, debug_d3dformat(Format));
2780 /* Validate the parameters as much as possible */
2781 if (NULL == pMode ||
2782 Adapter >= IWineD3DImpl_GetAdapterCount(iface) ||
2783 Mode >= IWineD3DImpl_GetAdapterModeCount(iface, Adapter, Format)) {
2784 return WINED3DERR_INVALIDCALL;
2787 /* TODO: Store modes per adapter and read it from the adapter structure */
2790 const struct wined3d_format_desc *format_desc = getFormatDescEntry(Format, &This->adapters[Adapter].gl_info);
2791 UINT format_bits = format_desc->byte_count * CHAR_BIT;
2797 ZeroMemory(&DevModeW, sizeof(DevModeW));
2798 DevModeW.dmSize = sizeof(DevModeW);
2800 /* If we are filtering to a specific format (D3D9), then need to skip
2801 all unrelated modes, but if mode is irrelevant (D3D8), then we can
2802 just count through the ones with valid bit depths */
2803 while ((i<=Mode) && EnumDisplaySettingsExW(NULL, j++, &DevModeW, 0))
2805 if (Format == WINED3DFMT_UNKNOWN)
2807 /* This is for D3D8, do not enumerate P8 here */
2808 if (DevModeW.dmBitsPerPel == 32 || DevModeW.dmBitsPerPel == 16) ++i;
2810 else if (DevModeW.dmBitsPerPel == format_bits)
2817 TRACE_(d3d_caps)("No modes found for format (%x - %s)\n", Format, debug_d3dformat(Format));
2818 return WINED3DERR_INVALIDCALL;
2822 /* Now get the display mode via the calculated index */
2823 if (EnumDisplaySettingsExW(NULL, ModeIdx, &DevModeW, 0)) {
2824 pMode->Width = DevModeW.dmPelsWidth;
2825 pMode->Height = DevModeW.dmPelsHeight;
2826 pMode->RefreshRate = DEFAULT_REFRESH_RATE;
2827 if (DevModeW.dmFields & DM_DISPLAYFREQUENCY)
2828 pMode->RefreshRate = DevModeW.dmDisplayFrequency;
2830 if (Format == WINED3DFMT_UNKNOWN) {
2831 pMode->Format = pixelformat_for_depth(DevModeW.dmBitsPerPel);
2833 pMode->Format = Format;
2836 TRACE_(d3d_caps)("Requested mode out of range %d\n", Mode);
2837 return WINED3DERR_INVALIDCALL;
2840 TRACE_(d3d_caps)("W %d H %d rr %d fmt (%x - %s) bpp %u\n", pMode->Width, pMode->Height,
2841 pMode->RefreshRate, pMode->Format, debug_d3dformat(pMode->Format),
2842 DevModeW.dmBitsPerPel);
2847 FIXME_(d3d_caps)("Adapter not primary display\n");
2853 static HRESULT WINAPI IWineD3DImpl_GetAdapterDisplayMode(IWineD3D *iface, UINT Adapter, WINED3DDISPLAYMODE *pMode)
2855 TRACE("iface %p, adapter_idx %u, display_mode %p.\n", iface, Adapter, pMode);
2857 if (NULL == pMode ||
2858 Adapter >= IWineD3D_GetAdapterCount(iface)) {
2859 return WINED3DERR_INVALIDCALL;
2862 if (Adapter == 0) { /* Display */
2866 ZeroMemory(&DevModeW, sizeof(DevModeW));
2867 DevModeW.dmSize = sizeof(DevModeW);
2869 EnumDisplaySettingsExW(NULL, ENUM_CURRENT_SETTINGS, &DevModeW, 0);
2870 pMode->Width = DevModeW.dmPelsWidth;
2871 pMode->Height = DevModeW.dmPelsHeight;
2872 bpp = DevModeW.dmBitsPerPel;
2873 pMode->RefreshRate = DEFAULT_REFRESH_RATE;
2874 if (DevModeW.dmFields&DM_DISPLAYFREQUENCY)
2876 pMode->RefreshRate = DevModeW.dmDisplayFrequency;
2879 pMode->Format = pixelformat_for_depth(bpp);
2881 FIXME_(d3d_caps)("Adapter not primary display\n");
2884 TRACE_(d3d_caps)("returning w:%d, h:%d, ref:%d, fmt:%s\n", pMode->Width,
2885 pMode->Height, pMode->RefreshRate, debug_d3dformat(pMode->Format));
2889 /* NOTE: due to structure differences between dx8 and dx9 D3DADAPTER_IDENTIFIER,
2890 and fields being inserted in the middle, a new structure is used in place */
2891 static HRESULT WINAPI IWineD3DImpl_GetAdapterIdentifier(IWineD3D *iface, UINT Adapter, DWORD Flags,
2892 WINED3DADAPTER_IDENTIFIER* pIdentifier) {
2893 IWineD3DImpl *This = (IWineD3DImpl *)iface;
2894 struct wined3d_adapter *adapter;
2897 TRACE_(d3d_caps)("(%p}->(Adapter: %d, Flags: %x, pId=%p)\n", This, Adapter, Flags, pIdentifier);
2899 if (Adapter >= IWineD3D_GetAdapterCount(iface)) {
2900 return WINED3DERR_INVALIDCALL;
2903 adapter = &This->adapters[Adapter];
2905 /* Return the information requested */
2906 TRACE_(d3d_caps)("device/Vendor Name and Version detection using FillGLCaps\n");
2908 if (pIdentifier->driver_size)
2910 const char *name = adapter->driver_info.name;
2911 len = min(strlen(name), pIdentifier->driver_size - 1);
2912 memcpy(pIdentifier->driver, name, len);
2913 pIdentifier->driver[len] = '\0';
2916 if (pIdentifier->description_size)
2918 const char *description = adapter->driver_info.description;
2919 len = min(strlen(description), pIdentifier->description_size - 1);
2920 memcpy(pIdentifier->description, description, len);
2921 pIdentifier->description[len] = '\0';
2924 /* Note that d3d8 doesn't supply a device name. */
2925 if (pIdentifier->device_name_size)
2927 static const char *device_name = "\\\\.\\DISPLAY1"; /* FIXME: May depend on desktop? */
2929 len = strlen(device_name);
2930 if (len >= pIdentifier->device_name_size)
2932 ERR("Device name size too small.\n");
2933 return WINED3DERR_INVALIDCALL;
2936 memcpy(pIdentifier->device_name, device_name, len);
2937 pIdentifier->device_name[len] = '\0';
2940 pIdentifier->driver_version.u.HighPart = adapter->driver_info.version_high;
2941 pIdentifier->driver_version.u.LowPart = adapter->driver_info.version_low;
2942 pIdentifier->vendor_id = adapter->driver_info.vendor;
2943 pIdentifier->device_id = adapter->driver_info.device;
2944 pIdentifier->subsystem_id = 0;
2945 pIdentifier->revision = 0;
2946 memcpy(&pIdentifier->device_identifier, &IID_D3DDEVICE_D3DUID, sizeof(pIdentifier->device_identifier));
2947 pIdentifier->whql_level = (Flags & WINED3DENUM_NO_WHQL_LEVEL) ? 0 : 1;
2948 memcpy(&pIdentifier->adapter_luid, &adapter->luid, sizeof(pIdentifier->adapter_luid));
2949 pIdentifier->video_memory = adapter->TextureRam;
2954 static BOOL IWineD3DImpl_IsPixelFormatCompatibleWithRenderFmt(const struct wined3d_gl_info *gl_info,
2955 const WineD3D_PixelFormat *cfg, const struct wined3d_format_desc *format_desc)
2957 short redSize, greenSize, blueSize, alphaSize, colorBits;
2962 /* Float formats need FBOs. If FBOs are used this function isn't called */
2963 if (format_desc->Flags & WINED3DFMT_FLAG_FLOAT) return FALSE;
2965 if(cfg->iPixelType == WGL_TYPE_RGBA_ARB) { /* Integer RGBA formats */
2966 if (!getColorBits(format_desc, &redSize, &greenSize, &blueSize, &alphaSize, &colorBits))
2968 ERR("Unable to check compatibility for Format=%s\n", debug_d3dformat(format_desc->format));
2972 if(cfg->redSize < redSize)
2975 if(cfg->greenSize < greenSize)
2978 if(cfg->blueSize < blueSize)
2981 if(cfg->alphaSize < alphaSize)
2987 /* Probably a RGBA_float or color index mode */
2991 static BOOL IWineD3DImpl_IsPixelFormatCompatibleWithDepthFmt(const struct wined3d_gl_info *gl_info,
2992 const WineD3D_PixelFormat *cfg, const struct wined3d_format_desc *format_desc)
2994 short depthSize, stencilSize;
2995 BOOL lockable = FALSE;
3000 if (!getDepthStencilBits(format_desc, &depthSize, &stencilSize))
3002 ERR("Unable to check compatibility for Format=%s\n", debug_d3dformat(format_desc->format));
3006 /* Float formats need FBOs. If FBOs are used this function isn't called */
3007 if (format_desc->Flags & WINED3DFMT_FLAG_FLOAT) return FALSE;
3009 if ((format_desc->format == WINED3DFMT_D16_LOCKABLE) || (format_desc->format == WINED3DFMT_D32_FLOAT))
3012 /* On some modern cards like the Geforce8/9 GLX doesn't offer some dephthstencil formats which D3D9 reports.
3013 * We can safely report 'compatible' formats (e.g. D24 can be used for D16) as long as we aren't dealing with
3014 * a lockable format. This also helps D3D <= 7 as they expect D16 which isn't offered without this on Geforce8 cards. */
3015 if(!(cfg->depthSize == depthSize || (!lockable && cfg->depthSize > depthSize)))
3018 /* Some cards like Intel i915 ones only offer D24S8 but lots of games also need a format without stencil, so
3019 * allow more stencil bits than requested. */
3020 if(cfg->stencilSize < stencilSize)
3026 static HRESULT WINAPI IWineD3DImpl_CheckDepthStencilMatch(IWineD3D *iface, UINT Adapter, WINED3DDEVTYPE DeviceType,
3027 WINED3DFORMAT AdapterFormat,
3028 WINED3DFORMAT RenderTargetFormat,
3029 WINED3DFORMAT DepthStencilFormat) {
3030 IWineD3DImpl *This = (IWineD3DImpl *)iface;
3032 const WineD3D_PixelFormat *cfgs;
3033 const struct wined3d_adapter *adapter;
3034 const struct wined3d_format_desc *rt_format_desc;
3035 const struct wined3d_format_desc *ds_format_desc;
3038 WARN_(d3d_caps)("(%p)-> (STUB) (Adptr:%d, DevType:(%x,%s), AdptFmt:(%x,%s), RendrTgtFmt:(%x,%s), DepthStencilFmt:(%x,%s))\n",
3040 DeviceType, debug_d3ddevicetype(DeviceType),
3041 AdapterFormat, debug_d3dformat(AdapterFormat),
3042 RenderTargetFormat, debug_d3dformat(RenderTargetFormat),
3043 DepthStencilFormat, debug_d3dformat(DepthStencilFormat));
3045 if (Adapter >= IWineD3D_GetAdapterCount(iface)) {
3046 TRACE("(%p) Failed: Atapter (%u) higher than supported adapters (%u) returning WINED3DERR_INVALIDCALL\n", This, Adapter, IWineD3D_GetAdapterCount(iface));
3047 return WINED3DERR_INVALIDCALL;
3050 adapter = &This->adapters[Adapter];
3051 rt_format_desc = getFormatDescEntry(RenderTargetFormat, &adapter->gl_info);
3052 ds_format_desc = getFormatDescEntry(DepthStencilFormat, &adapter->gl_info);
3053 if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
3055 if ((rt_format_desc->Flags & WINED3DFMT_FLAG_RENDERTARGET) &&
3056 (ds_format_desc->Flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL))) {
3057 TRACE_(d3d_caps)("(%p) : Formats matched\n", This);
3063 cfgs = adapter->cfgs;
3064 nCfgs = adapter->nCfgs;
3065 for (it = 0; it < nCfgs; ++it) {
3066 if (IWineD3DImpl_IsPixelFormatCompatibleWithRenderFmt(&adapter->gl_info, &cfgs[it], rt_format_desc))
3068 if (IWineD3DImpl_IsPixelFormatCompatibleWithDepthFmt(&adapter->gl_info, &cfgs[it], ds_format_desc))
3070 TRACE_(d3d_caps)("(%p) : Formats matched\n", This);
3076 WARN_(d3d_caps)("unsupported format pair: %s and %s\n", debug_d3dformat(RenderTargetFormat), debug_d3dformat(DepthStencilFormat));
3078 return WINED3DERR_NOTAVAILABLE;
3081 static HRESULT WINAPI IWineD3DImpl_CheckDeviceMultiSampleType(IWineD3D *iface, UINT Adapter, WINED3DDEVTYPE DeviceType,
3082 WINED3DFORMAT SurfaceFormat, BOOL Windowed, WINED3DMULTISAMPLE_TYPE MultiSampleType, DWORD *pQualityLevels)
3084 IWineD3DImpl *This = (IWineD3DImpl *)iface;
3085 const struct wined3d_format_desc *glDesc;
3086 const struct wined3d_adapter *adapter;
3088 TRACE_(d3d_caps)("(%p)-> (Adptr:%d, DevType:(%x,%s), SurfFmt:(%x,%s), Win?%d, MultiSamp:%x, pQual:%p)\n",
3091 DeviceType, debug_d3ddevicetype(DeviceType),
3092 SurfaceFormat, debug_d3dformat(SurfaceFormat),
3097 if (Adapter >= IWineD3D_GetAdapterCount(iface)) {
3098 return WINED3DERR_INVALIDCALL;
3101 /* TODO: handle Windowed, add more quality levels */
3103 if (WINED3DMULTISAMPLE_NONE == MultiSampleType) {
3104 if(pQualityLevels) *pQualityLevels = 1;
3108 /* By default multisampling is disabled right now as it causes issues
3109 * on some Nvidia driver versions and it doesn't work well in combination
3111 if(!wined3d_settings.allow_multisampling)
3112 return WINED3DERR_NOTAVAILABLE;
3114 adapter = &This->adapters[Adapter];
3115 glDesc = getFormatDescEntry(SurfaceFormat, &adapter->gl_info);
3116 if (!glDesc) return WINED3DERR_INVALIDCALL;
3118 if(glDesc->Flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL)) {
3120 const WineD3D_PixelFormat *cfgs;
3122 cfgs = adapter->cfgs;
3123 nCfgs = adapter->nCfgs;
3124 for(i=0; i<nCfgs; i++) {
3125 if(cfgs[i].numSamples != MultiSampleType)
3128 if (!IWineD3DImpl_IsPixelFormatCompatibleWithDepthFmt(&adapter->gl_info, &cfgs[i], glDesc))
3131 TRACE("Found iPixelFormat=%d to support MultiSampleType=%d for format %s\n", cfgs[i].iPixelFormat, MultiSampleType, debug_d3dformat(SurfaceFormat));
3134 *pQualityLevels = 1; /* Guess at a value! */
3138 else if(glDesc->Flags & WINED3DFMT_FLAG_RENDERTARGET) {
3139 short redSize, greenSize, blueSize, alphaSize, colorBits;
3141 const WineD3D_PixelFormat *cfgs;
3143 if (!getColorBits(glDesc, &redSize, &greenSize, &blueSize, &alphaSize, &colorBits))
3145 ERR("Unable to color bits for format %#x, can't check multisampling capability!\n", SurfaceFormat);
3146 return WINED3DERR_NOTAVAILABLE;
3149 cfgs = adapter->cfgs;
3150 nCfgs = adapter->nCfgs;
3151 for(i=0; i<nCfgs; i++) {
3152 if(cfgs[i].numSamples != MultiSampleType)
3154 if(cfgs[i].redSize != redSize)
3156 if(cfgs[i].greenSize != greenSize)
3158 if(cfgs[i].blueSize != blueSize)
3160 /* Not all drivers report alpha-less formats since they use 32-bit anyway, so accept alpha even if we didn't ask for it. */
3161 if(alphaSize && cfgs[i].alphaSize != alphaSize)
3163 if(cfgs[i].colorSize != (glDesc->byte_count << 3))
3166 TRACE("Found iPixelFormat=%d to support MultiSampleType=%d for format %s\n", cfgs[i].iPixelFormat, MultiSampleType, debug_d3dformat(SurfaceFormat));
3169 *pQualityLevels = 1; /* Guess at a value! */
3173 return WINED3DERR_NOTAVAILABLE;
3176 static HRESULT WINAPI IWineD3DImpl_CheckDeviceType(IWineD3D *iface, UINT Adapter, WINED3DDEVTYPE DeviceType,
3177 WINED3DFORMAT DisplayFormat, WINED3DFORMAT BackBufferFormat, BOOL Windowed)
3179 HRESULT hr = WINED3DERR_NOTAVAILABLE;
3182 TRACE("iface %p, adapter_idx %u, device_type %s, display_format %s, backbuffer_format %s, windowed %#x.\n",
3183 iface, Adapter, debug_d3ddevicetype(DeviceType), debug_d3dformat(DisplayFormat),
3184 debug_d3dformat(BackBufferFormat), Windowed);
3186 if (Adapter >= IWineD3D_GetAdapterCount(iface)) {
3187 WARN_(d3d_caps)("Adapter >= IWineD3D_GetAdapterCount(iface), returning WINED3DERR_INVALIDCALL\n");
3188 return WINED3DERR_INVALIDCALL;
3191 /* The task of this function is to check whether a certain display / backbuffer format
3192 * combination is available on the given adapter. In fullscreen mode microsoft specified
3193 * that the display format shouldn't provide alpha and that ignoring alpha the backbuffer
3194 * and display format should match exactly.
3195 * In windowed mode format conversion can occur and this depends on the driver. When format
3196 * conversion is done, this function should nevertheless fail and applications need to use
3197 * CheckDeviceFormatConversion.
3198 * At the moment we assume that fullscreen and windowed have the same capabilities */
3200 /* There are only 4 display formats */
3201 if (!(DisplayFormat == WINED3DFMT_B5G6R5_UNORM
3202 || DisplayFormat == WINED3DFMT_B5G5R5X1_UNORM
3203 || DisplayFormat == WINED3DFMT_B8G8R8X8_UNORM
3204 || DisplayFormat == WINED3DFMT_B10G10R10A2_UNORM))
3206 TRACE_(d3d_caps)("Format %s unsupported as display format\n", debug_d3dformat(DisplayFormat));
3207 return WINED3DERR_NOTAVAILABLE;
3210 /* If the requested DisplayFormat is not available, don't continue */
3211 nmodes = IWineD3DImpl_GetAdapterModeCount(iface, Adapter, DisplayFormat);
3213 TRACE_(d3d_caps)("No available modes for display format %s\n", debug_d3dformat(DisplayFormat));
3214 return WINED3DERR_NOTAVAILABLE;
3217 /* Windowed mode allows you to specify WINED3DFMT_UNKNOWN for the backbufferformat, it means 'reuse' the display format for the backbuffer */
3218 if(!Windowed && BackBufferFormat == WINED3DFMT_UNKNOWN) {
3219 TRACE_(d3d_caps)("BackBufferFormat WINED3FMT_UNKNOWN not available in Windowed mode\n");
3220 return WINED3DERR_NOTAVAILABLE;
3223 /* In FULLSCREEN mode R5G6B5 can only be mixed with backbuffer format R5G6B5 */
3224 if (DisplayFormat == WINED3DFMT_B5G6R5_UNORM && BackBufferFormat != WINED3DFMT_B5G6R5_UNORM)
3226 TRACE_(d3d_caps)("Unsupported display/backbuffer format combination %s/%s\n", debug_d3dformat(DisplayFormat), debug_d3dformat(BackBufferFormat));
3227 return WINED3DERR_NOTAVAILABLE;
3230 /* In FULLSCREEN mode X1R5G5B5 can only be mixed with backbuffer format *1R5G5B5 */
3231 if (DisplayFormat == WINED3DFMT_B5G5R5X1_UNORM
3232 && !(BackBufferFormat == WINED3DFMT_B5G5R5X1_UNORM || BackBufferFormat == WINED3DFMT_B5G5R5A1_UNORM))
3234 TRACE_(d3d_caps)("Unsupported display/backbuffer format combination %s/%s\n", debug_d3dformat(DisplayFormat), debug_d3dformat(BackBufferFormat));
3235 return WINED3DERR_NOTAVAILABLE;
3238 /* In FULLSCREEN mode X8R8G8B8 can only be mixed with backbuffer format *8R8G8B8 */
3239 if (DisplayFormat == WINED3DFMT_B8G8R8X8_UNORM
3240 && !(BackBufferFormat == WINED3DFMT_B8G8R8X8_UNORM || BackBufferFormat == WINED3DFMT_B8G8R8A8_UNORM))
3242 TRACE_(d3d_caps)("Unsupported display/backbuffer format combination %s/%s\n", debug_d3dformat(DisplayFormat), debug_d3dformat(BackBufferFormat));
3243 return WINED3DERR_NOTAVAILABLE;
3246 /* A2R10G10B10 is only allowed in fullscreen mode and it can only be mixed with backbuffer format A2R10G10B10 */
3247 if (DisplayFormat == WINED3DFMT_B10G10R10A2_UNORM
3248 && (BackBufferFormat != WINED3DFMT_B10G10R10A2_UNORM || Windowed))
3250 TRACE_(d3d_caps)("Unsupported display/backbuffer format combination %s/%s\n", debug_d3dformat(DisplayFormat), debug_d3dformat(BackBufferFormat));
3251 return WINED3DERR_NOTAVAILABLE;
3254 /* Use CheckDeviceFormat to see if the BackBufferFormat is usable with the given DisplayFormat */
3255 hr = IWineD3DImpl_CheckDeviceFormat(iface, Adapter, DeviceType, DisplayFormat, WINED3DUSAGE_RENDERTARGET, WINED3DRTYPE_SURFACE, BackBufferFormat, SURFACE_OPENGL);
3257 TRACE_(d3d_caps)("Unsupported display/backbuffer format combination %s/%s\n", debug_d3dformat(DisplayFormat), debug_d3dformat(BackBufferFormat));
3263 /* Check if we support bumpmapping for a format */
3264 static BOOL CheckBumpMapCapability(struct wined3d_adapter *adapter, const struct wined3d_format_desc *format_desc)
3266 /* Ask the fixed function pipeline implementation if it can deal
3267 * with the conversion. If we've got a GL extension giving native
3268 * support this will be an identity conversion. */
3269 return (format_desc->Flags & WINED3DFMT_FLAG_BUMPMAP)
3270 && adapter->fragment_pipe->color_fixup_supported(format_desc->color_fixup);
3273 /* Check if the given DisplayFormat + DepthStencilFormat combination is valid for the Adapter */
3274 static BOOL CheckDepthStencilCapability(struct wined3d_adapter *adapter,
3275 const struct wined3d_format_desc *display_format_desc, const struct wined3d_format_desc *ds_format_desc)
3279 /* Only allow depth/stencil formats */
3280 if (!(ds_format_desc->depth_size || ds_format_desc->stencil_size)) return FALSE;
3282 if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
3284 /* With FBOs WGL limitations do not apply, but the format needs to be FBO attachable */
3285 if (ds_format_desc->Flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL)) return TRUE;
3289 /* Walk through all WGL pixel formats to find a match */
3290 for (it = 0; it < adapter->nCfgs; ++it)
3292 WineD3D_PixelFormat *cfg = &adapter->cfgs[it];
3293 if (IWineD3DImpl_IsPixelFormatCompatibleWithRenderFmt(&adapter->gl_info, cfg, display_format_desc))
3295 if (IWineD3DImpl_IsPixelFormatCompatibleWithDepthFmt(&adapter->gl_info, cfg, ds_format_desc))
3306 static BOOL CheckFilterCapability(struct wined3d_adapter *adapter, const struct wined3d_format_desc *format_desc)
3308 /* The flags entry of a format contains the filtering capability */
3309 if (format_desc->Flags & WINED3DFMT_FLAG_FILTERING) return TRUE;
3314 /* Check the render target capabilities of a format */
3315 static BOOL CheckRenderTargetCapability(struct wined3d_adapter *adapter,
3316 const struct wined3d_format_desc *adapter_format_desc, const struct wined3d_format_desc *check_format_desc)
3318 /* Filter out non-RT formats */
3319 if (!(check_format_desc->Flags & WINED3DFMT_FLAG_RENDERTARGET)) return FALSE;
3320 if(wined3d_settings.offscreen_rendering_mode == ORM_BACKBUFFER) {
3321 WineD3D_PixelFormat *cfgs = adapter->cfgs;
3323 short AdapterRed, AdapterGreen, AdapterBlue, AdapterAlpha, AdapterTotalSize;
3324 short CheckRed, CheckGreen, CheckBlue, CheckAlpha, CheckTotalSize;
3326 getColorBits(adapter_format_desc, &AdapterRed, &AdapterGreen, &AdapterBlue, &AdapterAlpha, &AdapterTotalSize);
3327 getColorBits(check_format_desc, &CheckRed, &CheckGreen, &CheckBlue, &CheckAlpha, &CheckTotalSize);
3329 /* In backbuffer mode the front and backbuffer share the same WGL pixelformat.
3330 * The format must match in RGB, alpha is allowed to be different. (Only the backbuffer can have alpha) */
3331 if(!((AdapterRed == CheckRed) && (AdapterGreen == CheckGreen) && (AdapterBlue == CheckBlue))) {
3332 TRACE_(d3d_caps)("[FAILED]\n");
3336 /* Check if there is a WGL pixel format matching the requirements, the format should also be window
3337 * drawable (not offscreen; e.g. Nvidia offers R5G6B5 for pbuffers even when X is running at 24bit) */
3338 for (it = 0; it < adapter->nCfgs; ++it)
3340 if (cfgs[it].windowDrawable && IWineD3DImpl_IsPixelFormatCompatibleWithRenderFmt(&adapter->gl_info,
3341 &cfgs[it], check_format_desc))
3343 TRACE_(d3d_caps)("iPixelFormat=%d is compatible with CheckFormat=%s\n",
3344 cfgs[it].iPixelFormat, debug_d3dformat(check_format_desc->format));
3349 else if(wined3d_settings.offscreen_rendering_mode == ORM_FBO)
3351 /* For now return TRUE for FBOs until we have some proper checks.
3352 * Note that this function will only be called when the format is around for texturing. */
3358 static BOOL CheckSrgbReadCapability(struct wined3d_adapter *adapter, const struct wined3d_format_desc *format_desc)
3360 return adapter->gl_info.supported[EXT_TEXTURE_SRGB]
3361 && (format_desc->Flags & WINED3DFMT_FLAG_SRGB_READ);
3364 static BOOL CheckSrgbWriteCapability(struct wined3d_adapter *adapter, const struct wined3d_format_desc *format_desc)
3366 /* Only offer SRGB writing on X8R8G8B8/A8R8G8B8 when we use ARB or GLSL shaders as we are
3367 * doing the color fixup in shaders.
3368 * Note Windows drivers (at least on the Geforce 8800) also offer this on R5G6B5. */
3369 if (format_desc->Flags & WINED3DFMT_FLAG_SRGB_WRITE)
3371 int vs_selected_mode;
3372 int ps_selected_mode;
3373 select_shader_mode(&adapter->gl_info, &ps_selected_mode, &vs_selected_mode);
3375 if((ps_selected_mode == SHADER_ARB) || (ps_selected_mode == SHADER_GLSL)) {
3376 TRACE_(d3d_caps)("[OK]\n");
3381 TRACE_(d3d_caps)("[FAILED] - no SRGB writing support on format=%s\n", debug_d3dformat(format_desc->format));
3385 /* Check if a format support blending in combination with pixel shaders */
3386 static BOOL CheckPostPixelShaderBlendingCapability(struct wined3d_adapter *adapter,
3387 const struct wined3d_format_desc *format_desc)
3389 /* The flags entry of a format contains the post pixel shader blending capability */
3390 if (format_desc->Flags & WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING) return TRUE;
3395 static BOOL CheckWrapAndMipCapability(struct wined3d_adapter *adapter, const struct wined3d_format_desc *format_desc)
3397 /* OpenGL supports mipmapping on all formats basically. Wrapping is unsupported,
3398 * but we have to report mipmapping so we cannot reject this flag. Tests show that
3399 * windows reports WRAPANDMIP on unfilterable surfaces as well, apparently to show
3400 * that wrapping is supported. The lack of filtering will sort out the mipmapping
3401 * capability anyway.
3403 * For now lets report this on all formats, but in the future we may want to
3404 * restrict it to some should games need that
3409 /* Check if a texture format is supported on the given adapter */
3410 static BOOL CheckTextureCapability(struct wined3d_adapter *adapter, const struct wined3d_format_desc *format_desc)
3412 const struct wined3d_gl_info *gl_info = &adapter->gl_info;
3414 switch (format_desc->format)
3417 * supported: RGB(A) formats
3419 case WINED3DFMT_B8G8R8_UNORM: /* Enable for dx7, blacklisted for 8 and 9 above */
3420 case WINED3DFMT_B8G8R8A8_UNORM:
3421 case WINED3DFMT_B8G8R8X8_UNORM:
3422 case WINED3DFMT_B5G6R5_UNORM:
3423 case WINED3DFMT_B5G5R5X1_UNORM:
3424 case WINED3DFMT_B5G5R5A1_UNORM:
3425 case WINED3DFMT_B4G4R4A4_UNORM:
3426 case WINED3DFMT_A8_UNORM:
3427 case WINED3DFMT_B4G4R4X4_UNORM:
3428 case WINED3DFMT_R8G8B8A8_UNORM:
3429 case WINED3DFMT_R8G8B8X8_UNORM:
3430 case WINED3DFMT_B10G10R10A2_UNORM:
3431 case WINED3DFMT_R10G10B10A2_UNORM:
3432 case WINED3DFMT_R16G16_UNORM:
3433 TRACE_(d3d_caps)("[OK]\n");
3436 case WINED3DFMT_B2G3R3_UNORM:
3437 TRACE_(d3d_caps)("[FAILED] - Not supported on Windows\n");
3441 * Not supported: Palettized
3442 * Only some Geforce/Voodoo3/G400 cards offer 8-bit textures in case of <=Direct3D7.
3443 * Since it is not widely available, don't offer it. Further no Windows driver offers
3444 * WINED3DFMT_P8_UINT_A8_NORM, so don't offer it either.
3446 case WINED3DFMT_P8_UINT:
3447 case WINED3DFMT_P8_UINT_A8_UNORM:
3451 * Supported: (Alpha)-Luminance
3453 case WINED3DFMT_L8_UNORM:
3454 case WINED3DFMT_L8A8_UNORM:
3455 case WINED3DFMT_L16_UNORM:
3456 TRACE_(d3d_caps)("[OK]\n");
3459 /* Not supported on Windows, thus disabled */
3460 case WINED3DFMT_L4A4_UNORM:
3461 TRACE_(d3d_caps)("[FAILED] - not supported on windows\n");
3465 * Supported: Depth/Stencil formats
3467 case WINED3DFMT_D16_LOCKABLE:
3468 case WINED3DFMT_D16_UNORM:
3469 case WINED3DFMT_S1_UINT_D15_UNORM:
3470 case WINED3DFMT_X8D24_UNORM:
3471 case WINED3DFMT_S4X4_UINT_D24_UNORM:
3472 case WINED3DFMT_D24_UNORM_S8_UINT:
3473 case WINED3DFMT_S8_UINT_D24_FLOAT:
3474 case WINED3DFMT_D32_UNORM:
3475 case WINED3DFMT_D32_FLOAT:
3479 * Not supported everywhere(depends on GL_ATI_envmap_bumpmap or
3480 * GL_NV_texture_shader). Emulated by shaders
3482 case WINED3DFMT_R8G8_SNORM:
3483 case WINED3DFMT_R8G8_SNORM_L8X8_UNORM:
3484 case WINED3DFMT_R5G5_SNORM_L6_UNORM:
3485 case WINED3DFMT_R8G8B8A8_SNORM:
3486 case WINED3DFMT_R16G16_SNORM:
3487 /* Ask the shader backend if it can deal with the conversion. If
3488 * we've got a GL extension giving native support this will be an
3489 * identity conversion. */
3490 if (adapter->shader_backend->shader_color_fixup_supported(format_desc->color_fixup))
3492 TRACE_(d3d_caps)("[OK]\n");
3495 TRACE_(d3d_caps)("[FAILED]\n");
3498 case WINED3DFMT_DXT1:
3499 case WINED3DFMT_DXT2:
3500 case WINED3DFMT_DXT3:
3501 case WINED3DFMT_DXT4:
3502 case WINED3DFMT_DXT5:
3503 if (gl_info->supported[EXT_TEXTURE_COMPRESSION_S3TC])
3505 TRACE_(d3d_caps)("[OK]\n");
3508 TRACE_(d3d_caps)("[FAILED]\n");
3513 * Odd formats - not supported
3515 case WINED3DFMT_VERTEXDATA:
3516 case WINED3DFMT_R16_UINT:
3517 case WINED3DFMT_R32_UINT:
3518 case WINED3DFMT_R16G16B16A16_SNORM:
3519 case WINED3DFMT_R10G10B10_SNORM_A2_UNORM:
3520 case WINED3DFMT_R10G11B11_SNORM:
3521 TRACE_(d3d_caps)("[FAILED]\n"); /* Enable when implemented */
3525 * WINED3DFMT_R8G8_SNORM_Cx: Not supported right now
3527 case WINED3DFMT_R8G8_SNORM_Cx:
3528 TRACE_(d3d_caps)("[FAILED]\n"); /* Enable when implemented */
3532 case WINED3DFMT_UYVY:
3533 case WINED3DFMT_YUY2:
3534 if (gl_info->supported[APPLE_YCBCR_422])
3536 TRACE_(d3d_caps)("[OK]\n");
3539 TRACE_(d3d_caps)("[FAILED]\n");
3541 case WINED3DFMT_YV12:
3542 TRACE_(d3d_caps)("[FAILED]\n");
3546 case WINED3DFMT_R16G16B16A16_UNORM:
3547 case WINED3DFMT_B2G3R3A8_UNORM:
3548 TRACE_(d3d_caps)("[FAILED]\n"); /* Enable when implemented */
3551 /* Floating point formats */
3552 case WINED3DFMT_R16_FLOAT:
3553 case WINED3DFMT_R16G16_FLOAT:
3554 case WINED3DFMT_R16G16B16A16_FLOAT:
3555 if (gl_info->supported[ARB_TEXTURE_FLOAT] && gl_info->supported[ARB_HALF_FLOAT_PIXEL])
3557 TRACE_(d3d_caps)("[OK]\n");
3560 TRACE_(d3d_caps)("[FAILED]\n");
3563 case WINED3DFMT_R32_FLOAT:
3564 case WINED3DFMT_R32G32_FLOAT:
3565 case WINED3DFMT_R32G32B32A32_FLOAT:
3566 if (gl_info->supported[ARB_TEXTURE_FLOAT])
3568 TRACE_(d3d_caps)("[OK]\n");
3571 TRACE_(d3d_caps)("[FAILED]\n");
3574 /* ATI instancing hack: Although ATI cards do not support Shader Model 3.0, they support
3575 * instancing. To query if the card supports instancing CheckDeviceFormat with the special format
3576 * MAKEFOURCC('I','N','S','T') is used. Should a (broken) app check for this provide a proper return value.
3577 * We can do instancing with all shader versions, but we need vertex shaders.
3579 * Additionally applications have to set the D3DRS_POINTSIZE render state to MAKEFOURCC('I','N','S','T') once
3580 * to enable instancing. WineD3D doesn't need that and just ignores it.
3582 * With Shader Model 3.0 capable cards Instancing 'just works' in Windows.
3584 case WINED3DFMT_INST:
3585 TRACE("ATI Instancing check hack\n");
3586 if (gl_info->supported[ARB_VERTEX_PROGRAM] || gl_info->supported[ARB_VERTEX_SHADER])
3588 TRACE_(d3d_caps)("[OK]\n");
3591 TRACE_(d3d_caps)("[FAILED]\n");
3594 /* Some weird FOURCC formats */
3595 case WINED3DFMT_R8G8_B8G8:
3596 case WINED3DFMT_G8R8_G8B8:
3597 case WINED3DFMT_MULTI2_ARGB8:
3598 TRACE_(d3d_caps)("[FAILED]\n");
3601 /* Vendor specific formats */
3602 case WINED3DFMT_ATI2N:
3603 if (gl_info->supported[ATI_TEXTURE_COMPRESSION_3DC]
3604 || gl_info->supported[EXT_TEXTURE_COMPRESSION_RGTC])
3606 if (adapter->shader_backend->shader_color_fixup_supported(format_desc->color_fixup)
3607 && adapter->fragment_pipe->color_fixup_supported(format_desc->color_fixup))
3609 TRACE_(d3d_caps)("[OK]\n");
3613 TRACE_(d3d_caps)("[OK]\n");
3616 TRACE_(d3d_caps)("[FAILED]\n");
3619 case WINED3DFMT_NVHU:
3620 case WINED3DFMT_NVHS:
3621 /* These formats seem to be similar to the HILO formats in GL_NV_texture_shader. NVHU
3622 * is said to be GL_UNSIGNED_HILO16, NVHS GL_SIGNED_HILO16. Rumours say that d3d computes
3623 * a 3rd channel similarly to D3DFMT_CxV8U8(So NVHS could be called D3DFMT_CxV16U16).
3624 * ATI refused to support formats which can easilly be emulated with pixel shaders, so
3625 * Applications have to deal with not having NVHS and NVHU.
3627 TRACE_(d3d_caps)("[FAILED]\n");
3630 case WINED3DFMT_UNKNOWN:
3634 ERR("Unhandled format=%s\n", debug_d3dformat(format_desc->format));
3640 static BOOL CheckSurfaceCapability(struct wined3d_adapter *adapter,
3641 const struct wined3d_format_desc *adapter_format_desc,
3642 const struct wined3d_format_desc *check_format_desc,
3643 WINED3DSURFTYPE SurfaceType)
3645 if(SurfaceType == SURFACE_GDI) {
3646 switch(check_format_desc->format)
3648 case WINED3DFMT_B8G8R8_UNORM:
3649 case WINED3DFMT_B8G8R8A8_UNORM:
3650 case WINED3DFMT_B8G8R8X8_UNORM:
3651 case WINED3DFMT_B5G6R5_UNORM:
3652 case WINED3DFMT_B5G5R5X1_UNORM:
3653 case WINED3DFMT_B5G5R5A1_UNORM:
3654 case WINED3DFMT_B4G4R4A4_UNORM:
3655 case WINED3DFMT_B2G3R3_UNORM:
3656 case WINED3DFMT_A8_UNORM:
3657 case WINED3DFMT_B2G3R3A8_UNORM:
3658 case WINED3DFMT_B4G4R4X4_UNORM:
3659 case WINED3DFMT_R10G10B10A2_UNORM:
3660 case WINED3DFMT_R8G8B8A8_UNORM:
3661 case WINED3DFMT_R8G8B8X8_UNORM:
3662 case WINED3DFMT_R16G16_UNORM:
3663 case WINED3DFMT_B10G10R10A2_UNORM:
3664 case WINED3DFMT_R16G16B16A16_UNORM:
3665 case WINED3DFMT_P8_UINT:
3666 TRACE_(d3d_caps)("[OK]\n");
3669 TRACE_(d3d_caps)("[FAILED] - not available on GDI surfaces\n");
3674 /* All format that are supported for textures are supported for surfaces as well */
3675 if (CheckTextureCapability(adapter, check_format_desc)) return TRUE;
3676 /* All depth stencil formats are supported on surfaces */
3677 if (CheckDepthStencilCapability(adapter, adapter_format_desc, check_format_desc)) return TRUE;
3679 /* If opengl can't process the format natively, the blitter may be able to convert it */
3680 if (adapter->blitter->blit_supported(&adapter->gl_info, BLIT_OP_BLIT,
3681 NULL, WINED3DPOOL_DEFAULT, 0, check_format_desc,
3682 NULL, WINED3DPOOL_DEFAULT, 0, adapter_format_desc))
3684 TRACE_(d3d_caps)("[OK]\n");
3688 /* Reject other formats */
3689 TRACE_(d3d_caps)("[FAILED]\n");
3693 static BOOL CheckVertexTextureCapability(struct wined3d_adapter *adapter,
3694 const struct wined3d_format_desc *format_desc)
3696 return adapter->gl_info.limits.vertex_samplers
3697 && (format_desc->Flags & WINED3DFMT_FLAG_VTF);
3700 static HRESULT WINAPI IWineD3DImpl_CheckDeviceFormat(IWineD3D *iface, UINT Adapter, WINED3DDEVTYPE DeviceType,
3701 WINED3DFORMAT AdapterFormat, DWORD Usage, WINED3DRESOURCETYPE RType, WINED3DFORMAT CheckFormat,
3702 WINED3DSURFTYPE SurfaceType)
3704 IWineD3DImpl *This = (IWineD3DImpl *)iface;
3705 struct wined3d_adapter *adapter = &This->adapters[Adapter];
3706 const struct wined3d_gl_info *gl_info = &adapter->gl_info;
3707 const struct wined3d_format_desc *format_desc = getFormatDescEntry(CheckFormat, gl_info);
3708 const struct wined3d_format_desc *adapter_format_desc = getFormatDescEntry(AdapterFormat, gl_info);
3709 DWORD UsageCaps = 0;
3711 TRACE_(d3d_caps)("(%p)-> (STUB) (Adptr:%d, DevType:(%u,%s), AdptFmt:(%u,%s), Use:(%u,%s,%s), ResTyp:(%x,%s), CheckFmt:(%u,%s))\n",
3714 DeviceType, debug_d3ddevicetype(DeviceType),
3715 AdapterFormat, debug_d3dformat(AdapterFormat),
3716 Usage, debug_d3dusage(Usage), debug_d3dusagequery(Usage),
3717 RType, debug_d3dresourcetype(RType),
3718 CheckFormat, debug_d3dformat(CheckFormat));
3720 if (Adapter >= IWineD3D_GetAdapterCount(iface)) {
3721 return WINED3DERR_INVALIDCALL;
3726 case WINED3DRTYPE_CUBETEXTURE:
3727 /* Cubetexture allows:
3728 * - WINED3DUSAGE_AUTOGENMIPMAP
3729 * - WINED3DUSAGE_DEPTHSTENCIL
3730 * - WINED3DUSAGE_DYNAMIC
3731 * - WINED3DUSAGE_NONSECURE (d3d9ex)
3732 * - WINED3DUSAGE_RENDERTARGET
3733 * - WINED3DUSAGE_SOFTWAREPROCESSING
3734 * - WINED3DUSAGE_QUERY_WRAPANDMIP
3736 if (SurfaceType != SURFACE_OPENGL)
3738 TRACE_(d3d_caps)("[FAILED]\n");
3739 return WINED3DERR_NOTAVAILABLE;
3742 if (!gl_info->supported[ARB_TEXTURE_CUBE_MAP])
3744 TRACE_(d3d_caps)("[FAILED] - No cube texture support\n");
3745 return WINED3DERR_NOTAVAILABLE;
3748 if (!CheckTextureCapability(adapter, format_desc))
3750 TRACE_(d3d_caps)("[FAILED] - Cube texture format not supported\n");
3751 return WINED3DERR_NOTAVAILABLE;
3754 if (Usage & WINED3DUSAGE_AUTOGENMIPMAP)
3756 if (!gl_info->supported[SGIS_GENERATE_MIPMAP])
3757 /* When autogenmipmap isn't around continue and return
3758 * WINED3DOK_NOAUTOGEN instead of D3D_OK. */
3759 TRACE_(d3d_caps)("[FAILED] - No autogenmipmap support, but continuing\n");
3761 UsageCaps |= WINED3DUSAGE_AUTOGENMIPMAP;
3764 /* Always report dynamic locking. */
3765 if (Usage & WINED3DUSAGE_DYNAMIC)
3766 UsageCaps |= WINED3DUSAGE_DYNAMIC;
3768 if (Usage & WINED3DUSAGE_RENDERTARGET)
3770 if (!CheckRenderTargetCapability(adapter, adapter_format_desc, format_desc))
3772 TRACE_(d3d_caps)("[FAILED] - No rendertarget support\n");
3773 return WINED3DERR_NOTAVAILABLE;
3775 UsageCaps |= WINED3DUSAGE_RENDERTARGET;
3778 /* Always report software processing. */
3779 if (Usage & WINED3DUSAGE_SOFTWAREPROCESSING)
3780 UsageCaps |= WINED3DUSAGE_SOFTWAREPROCESSING;
3782 if (Usage & WINED3DUSAGE_QUERY_FILTER)
3784 if (!CheckFilterCapability(adapter, format_desc))
3786 TRACE_(d3d_caps)("[FAILED] - No query filter support\n");
3787 return WINED3DERR_NOTAVAILABLE;
3789 UsageCaps |= WINED3DUSAGE_QUERY_FILTER;
3792 if (Usage & WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING)
3794 if (!CheckPostPixelShaderBlendingCapability(adapter, format_desc))
3796 TRACE_(d3d_caps)("[FAILED] - No query post pixelshader blending support\n");
3797 return WINED3DERR_NOTAVAILABLE;
3799 UsageCaps |= WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING;
3802 if (Usage & WINED3DUSAGE_QUERY_SRGBREAD)
3804 if (!CheckSrgbReadCapability(adapter, format_desc))
3806 TRACE_(d3d_caps)("[FAILED] - No query srgbread support\n");
3807 return WINED3DERR_NOTAVAILABLE;
3809 UsageCaps |= WINED3DUSAGE_QUERY_SRGBREAD;
3812 if (Usage & WINED3DUSAGE_QUERY_SRGBWRITE)
3814 if (!CheckSrgbWriteCapability(adapter, format_desc))
3816 TRACE_(d3d_caps)("[FAILED] - No query srgbwrite support\n");
3817 return WINED3DERR_NOTAVAILABLE;
3819 UsageCaps |= WINED3DUSAGE_QUERY_SRGBWRITE;
3822 if (Usage & WINED3DUSAGE_QUERY_VERTEXTEXTURE)
3824 if (!CheckVertexTextureCapability(adapter, format_desc))
3826 TRACE_(d3d_caps)("[FAILED] - No query vertextexture support\n");
3827 return WINED3DERR_NOTAVAILABLE;
3829 UsageCaps |= WINED3DUSAGE_QUERY_VERTEXTEXTURE;
3832 if (Usage & WINED3DUSAGE_QUERY_WRAPANDMIP)
3834 if (!CheckWrapAndMipCapability(adapter, format_desc))
3836 TRACE_(d3d_caps)("[FAILED] - No wrapping and mipmapping support\n");
3837 return WINED3DERR_NOTAVAILABLE;
3839 UsageCaps |= WINED3DUSAGE_QUERY_WRAPANDMIP;
3843 case WINED3DRTYPE_SURFACE:
3845 * - WINED3DUSAGE_DEPTHSTENCIL
3846 * - WINED3DUSAGE_NONSECURE (d3d9ex)
3847 * - WINED3DUSAGE_RENDERTARGET
3849 if (!CheckSurfaceCapability(adapter, adapter_format_desc, format_desc, SurfaceType))
3851 TRACE_(d3d_caps)("[FAILED] - Not supported for plain surfaces\n");
3852 return WINED3DERR_NOTAVAILABLE;
3855 if (Usage & WINED3DUSAGE_DEPTHSTENCIL)
3857 if (!CheckDepthStencilCapability(adapter, adapter_format_desc, format_desc))
3859 TRACE_(d3d_caps)("[FAILED] - No depthstencil support\n");
3860 return WINED3DERR_NOTAVAILABLE;
3862 UsageCaps |= WINED3DUSAGE_DEPTHSTENCIL;
3865 if (Usage & WINED3DUSAGE_RENDERTARGET)
3867 if (!CheckRenderTargetCapability(adapter, adapter_format_desc, format_desc))
3869 TRACE_(d3d_caps)("[FAILED] - No rendertarget support\n");
3870 return WINED3DERR_NOTAVAILABLE;
3872 UsageCaps |= WINED3DUSAGE_RENDERTARGET;
3875 if (Usage & WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING)
3877 if (!CheckPostPixelShaderBlendingCapability(adapter, format_desc))
3879 TRACE_(d3d_caps)("[FAILED] - No query post pixelshader blending support\n");
3880 return WINED3DERR_NOTAVAILABLE;
3882 UsageCaps |= WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING;
3886 case WINED3DRTYPE_TEXTURE:
3888 * - WINED3DUSAGE_AUTOGENMIPMAP
3889 * - WINED3DUSAGE_DEPTHSTENCIL
3890 * - WINED3DUSAGE_DMAP
3891 * - WINED3DUSAGE_DYNAMIC
3892 * - WINED3DUSAGE_NONSECURE (d3d9ex)
3893 * - WINED3DUSAGE_RENDERTARGET
3894 * - WINED3DUSAGE_SOFTWAREPROCESSING
3895 * - WINED3DUSAGE_TEXTAPI (d3d9ex)
3896 * - WINED3DUSAGE_QUERY_WRAPANDMIP
3898 if (SurfaceType != SURFACE_OPENGL)
3900 TRACE_(d3d_caps)("[FAILED]\n");
3901 return WINED3DERR_NOTAVAILABLE;
3904 if (!CheckTextureCapability(adapter, format_desc))
3906 TRACE_(d3d_caps)("[FAILED] - Texture format not supported\n");
3907 return WINED3DERR_NOTAVAILABLE;
3910 if (Usage & WINED3DUSAGE_AUTOGENMIPMAP)
3912 if (!gl_info->supported[SGIS_GENERATE_MIPMAP])
3913 /* When autogenmipmap isn't around continue and return
3914 * WINED3DOK_NOAUTOGEN instead of D3D_OK. */
3915 TRACE_(d3d_caps)("[FAILED] - No autogenmipmap support, but continuing\n");
3917 UsageCaps |= WINED3DUSAGE_AUTOGENMIPMAP;
3920 /* Always report dynamic locking. */
3921 if (Usage & WINED3DUSAGE_DYNAMIC)
3922 UsageCaps |= WINED3DUSAGE_DYNAMIC;
3924 if (Usage & WINED3DUSAGE_RENDERTARGET)
3926 if (!CheckRenderTargetCapability(adapter, adapter_format_desc, format_desc))
3928 TRACE_(d3d_caps)("[FAILED] - No rendertarget support\n");
3929 return WINED3DERR_NOTAVAILABLE;
3931 UsageCaps |= WINED3DUSAGE_RENDERTARGET;
3934 /* Always report software processing. */
3935 if (Usage & WINED3DUSAGE_SOFTWAREPROCESSING)
3936 UsageCaps |= WINED3DUSAGE_SOFTWAREPROCESSING;
3938 if (Usage & WINED3DUSAGE_QUERY_FILTER)
3940 if (!CheckFilterCapability(adapter, format_desc))
3942 TRACE_(d3d_caps)("[FAILED] - No query filter support\n");
3943 return WINED3DERR_NOTAVAILABLE;
3945 UsageCaps |= WINED3DUSAGE_QUERY_FILTER;
3948 if (Usage & WINED3DUSAGE_QUERY_LEGACYBUMPMAP)
3950 if (!CheckBumpMapCapability(adapter, format_desc))
3952 TRACE_(d3d_caps)("[FAILED] - No legacy bumpmap support\n");
3953 return WINED3DERR_NOTAVAILABLE;
3955 UsageCaps |= WINED3DUSAGE_QUERY_LEGACYBUMPMAP;
3958 if (Usage & WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING)
3960 if (!CheckPostPixelShaderBlendingCapability(adapter, format_desc))
3962 TRACE_(d3d_caps)("[FAILED] - No query post pixelshader blending support\n");
3963 return WINED3DERR_NOTAVAILABLE;
3965 UsageCaps |= WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING;
3968 if (Usage & WINED3DUSAGE_QUERY_SRGBREAD)
3970 if (!CheckSrgbReadCapability(adapter, format_desc))
3972 TRACE_(d3d_caps)("[FAILED] - No query srgbread support\n");
3973 return WINED3DERR_NOTAVAILABLE;
3975 UsageCaps |= WINED3DUSAGE_QUERY_SRGBREAD;
3978 if (Usage & WINED3DUSAGE_QUERY_SRGBWRITE)
3980 if (!CheckSrgbWriteCapability(adapter, format_desc))
3982 TRACE_(d3d_caps)("[FAILED] - No query srgbwrite support\n");
3983 return WINED3DERR_NOTAVAILABLE;
3985 UsageCaps |= WINED3DUSAGE_QUERY_SRGBWRITE;
3988 if (Usage & WINED3DUSAGE_QUERY_VERTEXTEXTURE)
3990 if (!CheckVertexTextureCapability(adapter, format_desc))
3992 TRACE_(d3d_caps)("[FAILED] - No query vertextexture support\n");
3993 return WINED3DERR_NOTAVAILABLE;
3995 UsageCaps |= WINED3DUSAGE_QUERY_VERTEXTEXTURE;
3998 if (Usage & WINED3DUSAGE_QUERY_WRAPANDMIP)
4000 if (!CheckWrapAndMipCapability(adapter, format_desc))
4002 TRACE_(d3d_caps)("[FAILED] - No wrapping and mipmapping support\n");
4003 return WINED3DERR_NOTAVAILABLE;
4005 UsageCaps |= WINED3DUSAGE_QUERY_WRAPANDMIP;
4008 if (Usage & WINED3DUSAGE_DEPTHSTENCIL)
4010 if (!CheckDepthStencilCapability(adapter, adapter_format_desc, format_desc))
4012 TRACE_(d3d_caps)("[FAILED] - No depth stencil support\n");
4013 return WINED3DERR_NOTAVAILABLE;
4015 if ((format_desc->Flags & WINED3DFMT_FLAG_SHADOW) && !gl_info->supported[ARB_SHADOW])
4017 TRACE_(d3d_caps)("[FAILED] - No shadow sampler support.\n");
4018 return WINED3DERR_NOTAVAILABLE;
4020 UsageCaps |= WINED3DUSAGE_DEPTHSTENCIL;
4024 case WINED3DRTYPE_VOLUMETEXTURE:
4025 case WINED3DRTYPE_VOLUME:
4026 /* Volume is to VolumeTexture what Surface is to Texture, but its
4027 * usage caps are not documented. Most driver seem to offer
4028 * (nearly) the same on Volume and VolumeTexture, so do that too.
4030 * Volumetexture allows:
4031 * - D3DUSAGE_DYNAMIC
4032 * - D3DUSAGE_NONSECURE (d3d9ex)
4033 * - D3DUSAGE_SOFTWAREPROCESSING
4034 * - D3DUSAGE_QUERY_WRAPANDMIP
4036 if (SurfaceType != SURFACE_OPENGL)
4038 TRACE_(d3d_caps)("[FAILED]\n");
4039 return WINED3DERR_NOTAVAILABLE;
4042 if (!gl_info->supported[EXT_TEXTURE3D])
4044 TRACE_(d3d_caps)("[FAILED] - No volume texture support\n");
4045 return WINED3DERR_NOTAVAILABLE;
4048 if (!CheckTextureCapability(adapter, format_desc))
4050 TRACE_(d3d_caps)("[FAILED] - Format not supported\n");
4051 return WINED3DERR_NOTAVAILABLE;
4054 /* Filter formats that need conversion; For one part, this
4055 * conversion is unimplemented, and volume textures are huge, so
4056 * it would be a big performance hit. Unless we hit an application
4057 * needing one of those formats, don't advertize them to avoid
4058 * leading applications into temptation. The windows drivers don't
4059 * support most of those formats on volumes anyway, except for
4060 * WINED3DFMT_R32_FLOAT. */
4061 switch (CheckFormat)
4063 case WINED3DFMT_P8_UINT:
4064 case WINED3DFMT_L4A4_UNORM:
4065 case WINED3DFMT_R32_FLOAT:
4066 case WINED3DFMT_R16_FLOAT:
4067 case WINED3DFMT_R8G8_SNORM_L8X8_UNORM:
4068 case WINED3DFMT_R5G5_SNORM_L6_UNORM:
4069 case WINED3DFMT_R16G16_UNORM:
4070 TRACE_(d3d_caps)("[FAILED] - No converted formats on volumes\n");
4071 return WINED3DERR_NOTAVAILABLE;
4073 case WINED3DFMT_R8G8B8A8_SNORM:
4074 case WINED3DFMT_R16G16_SNORM:
4075 if (!gl_info->supported[NV_TEXTURE_SHADER])
4077 TRACE_(d3d_caps)("[FAILED] - No converted formats on volumes\n");
4078 return WINED3DERR_NOTAVAILABLE;
4082 case WINED3DFMT_R8G8_SNORM:
4083 if (!gl_info->supported[NV_TEXTURE_SHADER])
4085 TRACE_(d3d_caps)("[FAILED] - No converted formats on volumes\n");
4086 return WINED3DERR_NOTAVAILABLE;
4090 case WINED3DFMT_DXT1:
4091 case WINED3DFMT_DXT2:
4092 case WINED3DFMT_DXT3:
4093 case WINED3DFMT_DXT4:
4094 case WINED3DFMT_DXT5:
4095 /* The GL_EXT_texture_compression_s3tc spec requires that
4096 * loading an s3tc compressed texture results in an error.
4097 * While the D3D refrast does support s3tc volumes, at
4098 * least the nvidia windows driver does not, so we're free
4099 * not to support this format. */
4100 TRACE_(d3d_caps)("[FAILED] - DXTn does not support 3D textures\n");
4101 return WINED3DERR_NOTAVAILABLE;
4104 /* Do nothing, continue with checking the format below */
4108 /* Always report dynamic locking. */
4109 if (Usage & WINED3DUSAGE_DYNAMIC)
4110 UsageCaps |= WINED3DUSAGE_DYNAMIC;
4112 /* Always report software processing. */
4113 if (Usage & WINED3DUSAGE_SOFTWAREPROCESSING)
4114 UsageCaps |= WINED3DUSAGE_SOFTWAREPROCESSING;
4116 if (Usage & WINED3DUSAGE_QUERY_FILTER)
4118 if (!CheckFilterCapability(adapter, format_desc))
4120 TRACE_(d3d_caps)("[FAILED] - No query filter support\n");
4121 return WINED3DERR_NOTAVAILABLE;
4123 UsageCaps |= WINED3DUSAGE_QUERY_FILTER;
4126 if (Usage & WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING)
4128 if (!CheckPostPixelShaderBlendingCapability(adapter, format_desc))
4130 TRACE_(d3d_caps)("[FAILED] - No query post pixelshader blending support\n");
4131 return WINED3DERR_NOTAVAILABLE;
4133 UsageCaps |= WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING;
4136 if (Usage & WINED3DUSAGE_QUERY_SRGBREAD)
4138 if (!CheckSrgbReadCapability(adapter, format_desc))
4140 TRACE_(d3d_caps)("[FAILED] - No query srgbread support\n");
4141 return WINED3DERR_NOTAVAILABLE;
4143 UsageCaps |= WINED3DUSAGE_QUERY_SRGBREAD;
4146 if (Usage & WINED3DUSAGE_QUERY_SRGBWRITE)
4148 if (!CheckSrgbWriteCapability(adapter, format_desc))
4150 TRACE_(d3d_caps)("[FAILED] - No query srgbwrite support\n");
4151 return WINED3DERR_NOTAVAILABLE;
4153 UsageCaps |= WINED3DUSAGE_QUERY_SRGBWRITE;
4156 if (Usage & WINED3DUSAGE_QUERY_VERTEXTEXTURE)
4158 if (!CheckVertexTextureCapability(adapter, format_desc))
4160 TRACE_(d3d_caps)("[FAILED] - No query vertextexture support\n");
4161 return WINED3DERR_NOTAVAILABLE;
4163 UsageCaps |= WINED3DUSAGE_QUERY_VERTEXTEXTURE;
4166 if (Usage & WINED3DUSAGE_QUERY_WRAPANDMIP)
4168 if (!CheckWrapAndMipCapability(adapter, format_desc))
4170 TRACE_(d3d_caps)("[FAILED] - No wrapping and mipmapping support\n");
4171 return WINED3DERR_NOTAVAILABLE;
4173 UsageCaps |= WINED3DUSAGE_QUERY_WRAPANDMIP;
4178 FIXME_(d3d_caps)("Unhandled resource type %s.\n", debug_d3dresourcetype(RType));
4179 return WINED3DERR_NOTAVAILABLE;
4182 /* When the UsageCaps exactly matches Usage return WINED3D_OK except for
4183 * the situation in which WINED3DUSAGE_AUTOGENMIPMAP isn't around, then
4184 * WINED3DOK_NOAUTOGEN is returned if all the other usage flags match. */
4185 if (UsageCaps == Usage)
4187 if (UsageCaps == (Usage & ~WINED3DUSAGE_AUTOGENMIPMAP))
4188 return WINED3DOK_NOAUTOGEN;
4190 TRACE_(d3d_caps)("[FAILED] - Usage %#x requested for CheckFormat %s and RType %s but only %#x is available\n",
4191 Usage, debug_d3dformat(CheckFormat), debug_d3dresourcetype(RType), UsageCaps);
4193 return WINED3DERR_NOTAVAILABLE;
4196 static HRESULT WINAPI IWineD3DImpl_CheckDeviceFormatConversion(IWineD3D *iface, UINT adapter_idx,
4197 WINED3DDEVTYPE device_type, WINED3DFORMAT src_format, WINED3DFORMAT dst_format)
4199 FIXME("iface %p, adapter_idx %u, device_type %s, src_format %s, dst_format %s stub!\n",
4200 iface, adapter_idx, debug_d3ddevicetype(device_type), debug_d3dformat(src_format),
4201 debug_d3dformat(dst_format));
4206 /* Note: d3d8 passes in a pointer to a D3DCAPS8 structure, which is a true
4207 subset of a D3DCAPS9 structure. However, it has to come via a void *
4208 as the d3d8 interface cannot import the d3d9 header */
4209 static HRESULT WINAPI IWineD3DImpl_GetDeviceCaps(IWineD3D *iface, UINT Adapter, WINED3DDEVTYPE DeviceType, WINED3DCAPS* pCaps) {
4211 IWineD3DImpl *This = (IWineD3DImpl *)iface;
4212 struct wined3d_adapter *adapter = &This->adapters[Adapter];
4213 const struct wined3d_gl_info *gl_info = &adapter->gl_info;
4214 int vs_selected_mode;
4215 int ps_selected_mode;
4216 struct shader_caps shader_caps;
4217 struct fragment_caps fragment_caps;
4218 DWORD ckey_caps, blit_caps, fx_caps;
4220 TRACE_(d3d_caps)("(%p)->(Adptr:%d, DevType: %x, pCaps: %p)\n", This, Adapter, DeviceType, pCaps);
4222 if (Adapter >= IWineD3D_GetAdapterCount(iface)) {
4223 return WINED3DERR_INVALIDCALL;
4226 select_shader_mode(&adapter->gl_info, &ps_selected_mode, &vs_selected_mode);
4228 /* ------------------------------------------------
4229 The following fields apply to both d3d8 and d3d9
4230 ------------------------------------------------ */
4231 pCaps->DeviceType = (DeviceType == WINED3DDEVTYPE_HAL) ? WINED3DDEVTYPE_HAL : WINED3DDEVTYPE_REF; /* Not quite true, but use h/w supported by opengl I suppose */
4232 pCaps->AdapterOrdinal = Adapter;
4235 pCaps->Caps2 = WINED3DCAPS2_CANRENDERWINDOWED |
4236 WINED3DCAPS2_FULLSCREENGAMMA |
4237 WINED3DCAPS2_DYNAMICTEXTURES;
4238 if (gl_info->supported[SGIS_GENERATE_MIPMAP])
4240 pCaps->Caps2 |= WINED3DCAPS2_CANAUTOGENMIPMAP;
4243 pCaps->Caps3 = WINED3DCAPS3_ALPHA_FULLSCREEN_FLIP_OR_DISCARD |
4244 WINED3DCAPS3_COPY_TO_VIDMEM |
4245 WINED3DCAPS3_COPY_TO_SYSTEMMEM;
4247 pCaps->PresentationIntervals = WINED3DPRESENT_INTERVAL_IMMEDIATE |
4248 WINED3DPRESENT_INTERVAL_ONE;
4250 pCaps->CursorCaps = WINED3DCURSORCAPS_COLOR |
4251 WINED3DCURSORCAPS_LOWRES;
4253 pCaps->DevCaps = WINED3DDEVCAPS_FLOATTLVERTEX |
4254 WINED3DDEVCAPS_EXECUTESYSTEMMEMORY |
4255 WINED3DDEVCAPS_TLVERTEXSYSTEMMEMORY|
4256 WINED3DDEVCAPS_TLVERTEXVIDEOMEMORY |
4257 WINED3DDEVCAPS_DRAWPRIMTLVERTEX |
4258 WINED3DDEVCAPS_HWTRANSFORMANDLIGHT |
4259 WINED3DDEVCAPS_EXECUTEVIDEOMEMORY |
4260 WINED3DDEVCAPS_PUREDEVICE |
4261 WINED3DDEVCAPS_HWRASTERIZATION |
4262 WINED3DDEVCAPS_TEXTUREVIDEOMEMORY |
4263 WINED3DDEVCAPS_TEXTURESYSTEMMEMORY |
4264 WINED3DDEVCAPS_CANRENDERAFTERFLIP |
4265 WINED3DDEVCAPS_DRAWPRIMITIVES2 |
4266 WINED3DDEVCAPS_DRAWPRIMITIVES2EX |
4267 WINED3DDEVCAPS_RTPATCHES;
4269 pCaps->PrimitiveMiscCaps = WINED3DPMISCCAPS_CULLNONE |
4270 WINED3DPMISCCAPS_CULLCCW |
4271 WINED3DPMISCCAPS_CULLCW |
4272 WINED3DPMISCCAPS_COLORWRITEENABLE |
4273 WINED3DPMISCCAPS_CLIPTLVERTS |
4274 WINED3DPMISCCAPS_CLIPPLANESCALEDPOINTS |
4275 WINED3DPMISCCAPS_MASKZ |
4276 WINED3DPMISCCAPS_BLENDOP |
4277 WINED3DPMISCCAPS_MRTPOSTPIXELSHADERBLENDING;
4279 WINED3DPMISCCAPS_NULLREFERENCE
4280 WINED3DPMISCCAPS_FOGANDSPECULARALPHA
4281 WINED3DPMISCCAPS_MRTINDEPENDENTBITDEPTHS
4282 WINED3DPMISCCAPS_FOGVERTEXCLAMPED */
4284 if (gl_info->supported[EXT_BLEND_EQUATION_SEPARATE] && gl_info->supported[EXT_BLEND_FUNC_SEPARATE])
4285 pCaps->PrimitiveMiscCaps |= WINED3DPMISCCAPS_SEPARATEALPHABLEND;
4286 if (gl_info->supported[EXT_DRAW_BUFFERS2])
4287 pCaps->PrimitiveMiscCaps |= WINED3DPMISCCAPS_INDEPENDENTWRITEMASKS;
4289 pCaps->RasterCaps = WINED3DPRASTERCAPS_DITHER |
4290 WINED3DPRASTERCAPS_PAT |
4291 WINED3DPRASTERCAPS_WFOG |
4292 WINED3DPRASTERCAPS_ZFOG |
4293 WINED3DPRASTERCAPS_FOGVERTEX |
4294 WINED3DPRASTERCAPS_FOGTABLE |
4295 WINED3DPRASTERCAPS_STIPPLE |
4296 WINED3DPRASTERCAPS_SUBPIXEL |
4297 WINED3DPRASTERCAPS_ZTEST |
4298 WINED3DPRASTERCAPS_SCISSORTEST |
4299 WINED3DPRASTERCAPS_SLOPESCALEDEPTHBIAS |
4300 WINED3DPRASTERCAPS_DEPTHBIAS;
4302 if (gl_info->supported[EXT_TEXTURE_FILTER_ANISOTROPIC])
4304 pCaps->RasterCaps |= WINED3DPRASTERCAPS_ANISOTROPY |
4305 WINED3DPRASTERCAPS_ZBIAS |
4306 WINED3DPRASTERCAPS_MIPMAPLODBIAS;
4308 if (gl_info->supported[NV_FOG_DISTANCE])
4310 pCaps->RasterCaps |= WINED3DPRASTERCAPS_FOGRANGE;
4313 WINED3DPRASTERCAPS_COLORPERSPECTIVE
4314 WINED3DPRASTERCAPS_STRETCHBLTMULTISAMPLE
4315 WINED3DPRASTERCAPS_ANTIALIASEDGES
4316 WINED3DPRASTERCAPS_ZBUFFERLESSHSR
4317 WINED3DPRASTERCAPS_WBUFFER */
4319 pCaps->ZCmpCaps = WINED3DPCMPCAPS_ALWAYS |
4320 WINED3DPCMPCAPS_EQUAL |
4321 WINED3DPCMPCAPS_GREATER |
4322 WINED3DPCMPCAPS_GREATEREQUAL |
4323 WINED3DPCMPCAPS_LESS |
4324 WINED3DPCMPCAPS_LESSEQUAL |
4325 WINED3DPCMPCAPS_NEVER |
4326 WINED3DPCMPCAPS_NOTEQUAL;
4328 pCaps->SrcBlendCaps = WINED3DPBLENDCAPS_BOTHINVSRCALPHA |
4329 WINED3DPBLENDCAPS_BOTHSRCALPHA |
4330 WINED3DPBLENDCAPS_DESTALPHA |
4331 WINED3DPBLENDCAPS_DESTCOLOR |
4332 WINED3DPBLENDCAPS_INVDESTALPHA |
4333 WINED3DPBLENDCAPS_INVDESTCOLOR |
4334 WINED3DPBLENDCAPS_INVSRCALPHA |
4335 WINED3DPBLENDCAPS_INVSRCCOLOR |
4336 WINED3DPBLENDCAPS_ONE |
4337 WINED3DPBLENDCAPS_SRCALPHA |
4338 WINED3DPBLENDCAPS_SRCALPHASAT |
4339 WINED3DPBLENDCAPS_SRCCOLOR |
4340 WINED3DPBLENDCAPS_ZERO;
4342 pCaps->DestBlendCaps = WINED3DPBLENDCAPS_DESTALPHA |
4343 WINED3DPBLENDCAPS_DESTCOLOR |
4344 WINED3DPBLENDCAPS_INVDESTALPHA |
4345 WINED3DPBLENDCAPS_INVDESTCOLOR |
4346 WINED3DPBLENDCAPS_INVSRCALPHA |
4347 WINED3DPBLENDCAPS_INVSRCCOLOR |
4348 WINED3DPBLENDCAPS_ONE |
4349 WINED3DPBLENDCAPS_SRCALPHA |
4350 WINED3DPBLENDCAPS_SRCCOLOR |
4351 WINED3DPBLENDCAPS_ZERO;
4352 /* NOTE: WINED3DPBLENDCAPS_SRCALPHASAT is not supported as dest blend factor,
4353 * according to the glBlendFunc manpage
4355 * WINED3DPBLENDCAPS_BOTHINVSRCALPHA and WINED3DPBLENDCAPS_BOTHSRCALPHA are
4356 * legacy settings for srcblend only
4359 if (gl_info->supported[EXT_BLEND_COLOR])
4361 pCaps->SrcBlendCaps |= WINED3DPBLENDCAPS_BLENDFACTOR;
4362 pCaps->DestBlendCaps |= WINED3DPBLENDCAPS_BLENDFACTOR;
4366 pCaps->AlphaCmpCaps = WINED3DPCMPCAPS_ALWAYS |
4367 WINED3DPCMPCAPS_EQUAL |
4368 WINED3DPCMPCAPS_GREATER |
4369 WINED3DPCMPCAPS_GREATEREQUAL |
4370 WINED3DPCMPCAPS_LESS |
4371 WINED3DPCMPCAPS_LESSEQUAL |
4372 WINED3DPCMPCAPS_NEVER |
4373 WINED3DPCMPCAPS_NOTEQUAL;
4375 pCaps->ShadeCaps = WINED3DPSHADECAPS_SPECULARGOURAUDRGB |
4376 WINED3DPSHADECAPS_COLORGOURAUDRGB |
4377 WINED3DPSHADECAPS_ALPHAFLATBLEND |
4378 WINED3DPSHADECAPS_ALPHAGOURAUDBLEND |
4379 WINED3DPSHADECAPS_COLORFLATRGB |
4380 WINED3DPSHADECAPS_FOGFLAT |
4381 WINED3DPSHADECAPS_FOGGOURAUD |
4382 WINED3DPSHADECAPS_SPECULARFLATRGB;
4384 pCaps->TextureCaps = WINED3DPTEXTURECAPS_ALPHA |
4385 WINED3DPTEXTURECAPS_ALPHAPALETTE |
4386 WINED3DPTEXTURECAPS_TRANSPARENCY |
4387 WINED3DPTEXTURECAPS_BORDER |
4388 WINED3DPTEXTURECAPS_MIPMAP |
4389 WINED3DPTEXTURECAPS_PROJECTED |
4390 WINED3DPTEXTURECAPS_PERSPECTIVE;
4392 if (!gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO])
4394 pCaps->TextureCaps |= WINED3DPTEXTURECAPS_POW2 |
4395 WINED3DPTEXTURECAPS_NONPOW2CONDITIONAL;
4398 if (gl_info->supported[EXT_TEXTURE3D])
4400 pCaps->TextureCaps |= WINED3DPTEXTURECAPS_VOLUMEMAP |
4401 WINED3DPTEXTURECAPS_MIPVOLUMEMAP |
4402 WINED3DPTEXTURECAPS_VOLUMEMAP_POW2;
4405 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
4407 pCaps->TextureCaps |= WINED3DPTEXTURECAPS_CUBEMAP |
4408 WINED3DPTEXTURECAPS_MIPCUBEMAP |
4409 WINED3DPTEXTURECAPS_CUBEMAP_POW2;
4413 pCaps->TextureFilterCaps = WINED3DPTFILTERCAPS_MAGFLINEAR |
4414 WINED3DPTFILTERCAPS_MAGFPOINT |
4415 WINED3DPTFILTERCAPS_MINFLINEAR |
4416 WINED3DPTFILTERCAPS_MINFPOINT |
4417 WINED3DPTFILTERCAPS_MIPFLINEAR |
4418 WINED3DPTFILTERCAPS_MIPFPOINT |
4419 WINED3DPTFILTERCAPS_LINEAR |
4420 WINED3DPTFILTERCAPS_LINEARMIPLINEAR |
4421 WINED3DPTFILTERCAPS_LINEARMIPNEAREST |
4422 WINED3DPTFILTERCAPS_MIPLINEAR |
4423 WINED3DPTFILTERCAPS_MIPNEAREST |
4424 WINED3DPTFILTERCAPS_NEAREST;
4426 if (gl_info->supported[EXT_TEXTURE_FILTER_ANISOTROPIC])
4428 pCaps->TextureFilterCaps |= WINED3DPTFILTERCAPS_MAGFANISOTROPIC |
4429 WINED3DPTFILTERCAPS_MINFANISOTROPIC;
4432 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
4434 pCaps->CubeTextureFilterCaps = WINED3DPTFILTERCAPS_MAGFLINEAR |
4435 WINED3DPTFILTERCAPS_MAGFPOINT |
4436 WINED3DPTFILTERCAPS_MINFLINEAR |
4437 WINED3DPTFILTERCAPS_MINFPOINT |
4438 WINED3DPTFILTERCAPS_MIPFLINEAR |
4439 WINED3DPTFILTERCAPS_MIPFPOINT |
4440 WINED3DPTFILTERCAPS_LINEAR |
4441 WINED3DPTFILTERCAPS_LINEARMIPLINEAR |
4442 WINED3DPTFILTERCAPS_LINEARMIPNEAREST |
4443 WINED3DPTFILTERCAPS_MIPLINEAR |
4444 WINED3DPTFILTERCAPS_MIPNEAREST |
4445 WINED3DPTFILTERCAPS_NEAREST;
4447 if (gl_info->supported[EXT_TEXTURE_FILTER_ANISOTROPIC])
4449 pCaps->CubeTextureFilterCaps |= WINED3DPTFILTERCAPS_MAGFANISOTROPIC |
4450 WINED3DPTFILTERCAPS_MINFANISOTROPIC;
4453 pCaps->CubeTextureFilterCaps = 0;
4455 if (gl_info->supported[EXT_TEXTURE3D])
4457 pCaps->VolumeTextureFilterCaps = WINED3DPTFILTERCAPS_MAGFLINEAR |
4458 WINED3DPTFILTERCAPS_MAGFPOINT |
4459 WINED3DPTFILTERCAPS_MINFLINEAR |
4460 WINED3DPTFILTERCAPS_MINFPOINT |
4461 WINED3DPTFILTERCAPS_MIPFLINEAR |
4462 WINED3DPTFILTERCAPS_MIPFPOINT |
4463 WINED3DPTFILTERCAPS_LINEAR |
4464 WINED3DPTFILTERCAPS_LINEARMIPLINEAR |
4465 WINED3DPTFILTERCAPS_LINEARMIPNEAREST |
4466 WINED3DPTFILTERCAPS_MIPLINEAR |
4467 WINED3DPTFILTERCAPS_MIPNEAREST |
4468 WINED3DPTFILTERCAPS_NEAREST;
4470 pCaps->VolumeTextureFilterCaps = 0;
4472 pCaps->TextureAddressCaps = WINED3DPTADDRESSCAPS_INDEPENDENTUV |
4473 WINED3DPTADDRESSCAPS_CLAMP |
4474 WINED3DPTADDRESSCAPS_WRAP;
4476 if (gl_info->supported[ARB_TEXTURE_BORDER_CLAMP])
4478 pCaps->TextureAddressCaps |= WINED3DPTADDRESSCAPS_BORDER;
4480 if (gl_info->supported[ARB_TEXTURE_MIRRORED_REPEAT])
4482 pCaps->TextureAddressCaps |= WINED3DPTADDRESSCAPS_MIRROR;
4484 if (gl_info->supported[ATI_TEXTURE_MIRROR_ONCE])
4486 pCaps->TextureAddressCaps |= WINED3DPTADDRESSCAPS_MIRRORONCE;
4489 if (gl_info->supported[EXT_TEXTURE3D])
4491 pCaps->VolumeTextureAddressCaps = WINED3DPTADDRESSCAPS_INDEPENDENTUV |
4492 WINED3DPTADDRESSCAPS_CLAMP |
4493 WINED3DPTADDRESSCAPS_WRAP;
4494 if (gl_info->supported[ARB_TEXTURE_BORDER_CLAMP])
4496 pCaps->VolumeTextureAddressCaps |= WINED3DPTADDRESSCAPS_BORDER;
4498 if (gl_info->supported[ARB_TEXTURE_MIRRORED_REPEAT])
4500 pCaps->VolumeTextureAddressCaps |= WINED3DPTADDRESSCAPS_MIRROR;
4502 if (gl_info->supported[ATI_TEXTURE_MIRROR_ONCE])
4504 pCaps->VolumeTextureAddressCaps |= WINED3DPTADDRESSCAPS_MIRRORONCE;
4507 pCaps->VolumeTextureAddressCaps = 0;
4509 pCaps->LineCaps = WINED3DLINECAPS_TEXTURE |
4510 WINED3DLINECAPS_ZTEST |
4511 WINED3DLINECAPS_BLEND |
4512 WINED3DLINECAPS_ALPHACMP |
4513 WINED3DLINECAPS_FOG;
4514 /* WINED3DLINECAPS_ANTIALIAS is not supported on Windows, and dx and gl seem to have a different
4515 * idea how generating the smoothing alpha values works; the result is different
4518 pCaps->MaxTextureWidth = gl_info->limits.texture_size;
4519 pCaps->MaxTextureHeight = gl_info->limits.texture_size;
4521 if (gl_info->supported[EXT_TEXTURE3D])
4522 pCaps->MaxVolumeExtent = gl_info->limits.texture3d_size;
4524 pCaps->MaxVolumeExtent = 0;
4526 pCaps->MaxTextureRepeat = 32768;
4527 pCaps->MaxTextureAspectRatio = gl_info->limits.texture_size;
4528 pCaps->MaxVertexW = 1.0f;
4530 pCaps->GuardBandLeft = 0.0f;
4531 pCaps->GuardBandTop = 0.0f;
4532 pCaps->GuardBandRight = 0.0f;
4533 pCaps->GuardBandBottom = 0.0f;
4535 pCaps->ExtentsAdjust = 0.0f;
4537 pCaps->StencilCaps = WINED3DSTENCILCAPS_DECRSAT |
4538 WINED3DSTENCILCAPS_INCRSAT |
4539 WINED3DSTENCILCAPS_INVERT |
4540 WINED3DSTENCILCAPS_KEEP |
4541 WINED3DSTENCILCAPS_REPLACE |
4542 WINED3DSTENCILCAPS_ZERO;
4543 if (gl_info->supported[EXT_STENCIL_WRAP])
4545 pCaps->StencilCaps |= WINED3DSTENCILCAPS_DECR |
4546 WINED3DSTENCILCAPS_INCR;
4548 if (gl_info->supported[EXT_STENCIL_TWO_SIDE] || gl_info->supported[ATI_SEPARATE_STENCIL])
4550 pCaps->StencilCaps |= WINED3DSTENCILCAPS_TWOSIDED;
4553 pCaps->FVFCaps = WINED3DFVFCAPS_PSIZE | 0x0008; /* 8 texture coords */
4555 pCaps->MaxUserClipPlanes = gl_info->limits.clipplanes;
4556 pCaps->MaxActiveLights = gl_info->limits.lights;
4558 pCaps->MaxVertexBlendMatrices = gl_info->limits.blends;
4559 pCaps->MaxVertexBlendMatrixIndex = 0;
4561 pCaps->MaxAnisotropy = gl_info->limits.anisotropy;
4562 pCaps->MaxPointSize = gl_info->limits.pointsize_max;
4565 /* FIXME: Add D3DVTXPCAPS_TWEENING, D3DVTXPCAPS_TEXGEN_SPHEREMAP */
4566 pCaps->VertexProcessingCaps = WINED3DVTXPCAPS_DIRECTIONALLIGHTS |
4567 WINED3DVTXPCAPS_MATERIALSOURCE7 |
4568 WINED3DVTXPCAPS_POSITIONALLIGHTS |
4569 WINED3DVTXPCAPS_LOCALVIEWER |
4570 WINED3DVTXPCAPS_VERTEXFOG |
4571 WINED3DVTXPCAPS_TEXGEN;
4573 pCaps->MaxPrimitiveCount = 0xFFFFF; /* For now set 2^20-1 which is used by most >=Geforce3/Radeon8500 cards */
4574 pCaps->MaxVertexIndex = 0xFFFFF;
4575 pCaps->MaxStreams = MAX_STREAMS;
4576 pCaps->MaxStreamStride = 1024;
4578 /* d3d9.dll sets D3DDEVCAPS2_CAN_STRETCHRECT_FROM_TEXTURES here because StretchRects is implemented in d3d9 */
4579 pCaps->DevCaps2 = WINED3DDEVCAPS2_STREAMOFFSET |
4580 WINED3DDEVCAPS2_VERTEXELEMENTSCANSHARESTREAMOFFSET;
4581 pCaps->MaxNpatchTessellationLevel = 0;
4582 pCaps->MasterAdapterOrdinal = 0;
4583 pCaps->AdapterOrdinalInGroup = 0;
4584 pCaps->NumberOfAdaptersInGroup = 1;
4586 pCaps->NumSimultaneousRTs = gl_info->limits.buffers;
4588 pCaps->StretchRectFilterCaps = WINED3DPTFILTERCAPS_MINFPOINT |
4589 WINED3DPTFILTERCAPS_MAGFPOINT |
4590 WINED3DPTFILTERCAPS_MINFLINEAR |
4591 WINED3DPTFILTERCAPS_MAGFLINEAR;
4592 pCaps->VertexTextureFilterCaps = 0;
4594 adapter->shader_backend->shader_get_caps(&adapter->gl_info, &shader_caps);
4595 adapter->fragment_pipe->get_caps(&adapter->gl_info, &fragment_caps);
4597 /* Add shader misc caps. Only some of them belong to the shader parts of the pipeline */
4598 pCaps->PrimitiveMiscCaps |= fragment_caps.PrimitiveMiscCaps;
4600 /* This takes care for disabling vertex shader or pixel shader caps while leaving the other one enabled.
4601 * Ignore shader model capabilities if disabled in config
4603 if(vs_selected_mode == SHADER_NONE) {
4604 TRACE_(d3d_caps)("Vertex shader disabled in config, reporting version 0.0\n");
4605 pCaps->VertexShaderVersion = WINED3DVS_VERSION(0,0);
4606 pCaps->MaxVertexShaderConst = 0;
4608 pCaps->VertexShaderVersion = shader_caps.VertexShaderVersion;
4609 pCaps->MaxVertexShaderConst = shader_caps.MaxVertexShaderConst;
4612 if(ps_selected_mode == SHADER_NONE) {
4613 TRACE_(d3d_caps)("Pixel shader disabled in config, reporting version 0.0\n");
4614 pCaps->PixelShaderVersion = WINED3DPS_VERSION(0,0);
4615 pCaps->PixelShader1xMaxValue = 0.0f;
4617 pCaps->PixelShaderVersion = shader_caps.PixelShaderVersion;
4618 pCaps->PixelShader1xMaxValue = shader_caps.PixelShader1xMaxValue;
4621 pCaps->TextureOpCaps = fragment_caps.TextureOpCaps;
4622 pCaps->MaxTextureBlendStages = fragment_caps.MaxTextureBlendStages;
4623 pCaps->MaxSimultaneousTextures = fragment_caps.MaxSimultaneousTextures;
4625 /* The following caps are shader specific, but they are things we cannot detect, or which
4626 * are the same among all shader models. So to avoid code duplication set the shader version
4627 * specific, but otherwise constant caps here
4629 if(pCaps->VertexShaderVersion == WINED3DVS_VERSION(3,0)) {
4630 /* Where possible set the caps based on OpenGL extensions and if they aren't set (in case of software rendering)
4631 use the VS 3.0 from MSDN or else if there's OpenGL spec use a hardcoded value minimum VS3.0 value. */
4632 pCaps->VS20Caps.Caps = WINED3DVS20CAPS_PREDICATION;
4633 pCaps->VS20Caps.DynamicFlowControlDepth = WINED3DVS20_MAX_DYNAMICFLOWCONTROLDEPTH; /* VS 3.0 requires MAX_DYNAMICFLOWCONTROLDEPTH (24) */
4634 pCaps->VS20Caps.NumTemps = max(32, adapter->gl_info.limits.arb_vs_temps);
4635 pCaps->VS20Caps.StaticFlowControlDepth = WINED3DVS20_MAX_STATICFLOWCONTROLDEPTH ; /* level of nesting in loops / if-statements; VS 3.0 requires MAX (4) */
4637 pCaps->MaxVShaderInstructionsExecuted = 65535; /* VS 3.0 needs at least 65535, some cards even use 2^32-1 */
4638 pCaps->MaxVertexShader30InstructionSlots = max(512, adapter->gl_info.limits.arb_vs_instructions);
4640 else if (pCaps->VertexShaderVersion == WINED3DVS_VERSION(2,0))
4642 pCaps->VS20Caps.Caps = 0;
4643 pCaps->VS20Caps.DynamicFlowControlDepth = WINED3DVS20_MIN_DYNAMICFLOWCONTROLDEPTH;
4644 pCaps->VS20Caps.NumTemps = max(12, adapter->gl_info.limits.arb_vs_temps);
4645 pCaps->VS20Caps.StaticFlowControlDepth = 1;
4647 pCaps->MaxVShaderInstructionsExecuted = 65535;
4648 pCaps->MaxVertexShader30InstructionSlots = 0;
4649 } else { /* VS 1.x */
4650 pCaps->VS20Caps.Caps = 0;
4651 pCaps->VS20Caps.DynamicFlowControlDepth = 0;
4652 pCaps->VS20Caps.NumTemps = 0;
4653 pCaps->VS20Caps.StaticFlowControlDepth = 0;
4655 pCaps->MaxVShaderInstructionsExecuted = 0;
4656 pCaps->MaxVertexShader30InstructionSlots = 0;
4659 if(pCaps->PixelShaderVersion == WINED3DPS_VERSION(3,0)) {
4660 /* Where possible set the caps based on OpenGL extensions and if they aren't set (in case of software rendering)
4661 use the PS 3.0 from MSDN or else if there's OpenGL spec use a hardcoded value minimum PS 3.0 value. */
4663 /* 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 */
4664 pCaps->PS20Caps.Caps = WINED3DPS20CAPS_ARBITRARYSWIZZLE |
4665 WINED3DPS20CAPS_GRADIENTINSTRUCTIONS |
4666 WINED3DPS20CAPS_PREDICATION |
4667 WINED3DPS20CAPS_NODEPENDENTREADLIMIT |
4668 WINED3DPS20CAPS_NOTEXINSTRUCTIONLIMIT;
4669 pCaps->PS20Caps.DynamicFlowControlDepth = WINED3DPS20_MAX_DYNAMICFLOWCONTROLDEPTH; /* PS 3.0 requires MAX_DYNAMICFLOWCONTROLDEPTH (24) */
4670 pCaps->PS20Caps.NumTemps = max(32, adapter->gl_info.limits.arb_ps_temps);
4671 pCaps->PS20Caps.StaticFlowControlDepth = WINED3DPS20_MAX_STATICFLOWCONTROLDEPTH; /* PS 3.0 requires MAX_STATICFLOWCONTROLDEPTH (4) */
4672 pCaps->PS20Caps.NumInstructionSlots = WINED3DPS20_MAX_NUMINSTRUCTIONSLOTS; /* PS 3.0 requires MAX_NUMINSTRUCTIONSLOTS (512) */
4674 pCaps->MaxPShaderInstructionsExecuted = 65535;
4675 pCaps->MaxPixelShader30InstructionSlots = max(WINED3DMIN30SHADERINSTRUCTIONS,
4676 adapter->gl_info.limits.arb_ps_instructions);
4678 else if(pCaps->PixelShaderVersion == WINED3DPS_VERSION(2,0))
4680 /* Below we assume PS2.0 specs, not extended 2.0a(GeforceFX)/2.0b(Radeon R3xx) ones */
4681 pCaps->PS20Caps.Caps = 0;
4682 pCaps->PS20Caps.DynamicFlowControlDepth = 0; /* WINED3DVS20_MIN_DYNAMICFLOWCONTROLDEPTH = 0 */
4683 pCaps->PS20Caps.NumTemps = max(12, adapter->gl_info.limits.arb_ps_temps);
4684 pCaps->PS20Caps.StaticFlowControlDepth = WINED3DPS20_MIN_STATICFLOWCONTROLDEPTH; /* Minimum: 1 */
4685 pCaps->PS20Caps.NumInstructionSlots = WINED3DPS20_MIN_NUMINSTRUCTIONSLOTS; /* Minimum number (64 ALU + 32 Texture), a GeforceFX uses 512 */
4687 pCaps->MaxPShaderInstructionsExecuted = 512; /* Minimum value, a GeforceFX uses 1024 */
4688 pCaps->MaxPixelShader30InstructionSlots = 0;
4689 } else { /* PS 1.x */
4690 pCaps->PS20Caps.Caps = 0;
4691 pCaps->PS20Caps.DynamicFlowControlDepth = 0;
4692 pCaps->PS20Caps.NumTemps = 0;
4693 pCaps->PS20Caps.StaticFlowControlDepth = 0;
4694 pCaps->PS20Caps.NumInstructionSlots = 0;
4696 pCaps->MaxPShaderInstructionsExecuted = 0;
4697 pCaps->MaxPixelShader30InstructionSlots = 0;
4700 if(pCaps->VertexShaderVersion >= WINED3DVS_VERSION(2,0)) {
4701 /* OpenGL supports all the formats below, perhaps not always
4702 * without conversion, but it supports them.
4703 * Further GLSL doesn't seem to have an official unsigned type so
4704 * don't advertise it yet as I'm not sure how we handle it.
4705 * We might need to add some clamping in the shader engine to
4707 * TODO: WINED3DDTCAPS_USHORT2N, WINED3DDTCAPS_USHORT4N, WINED3DDTCAPS_UDEC3, WINED3DDTCAPS_DEC3N */
4708 pCaps->DeclTypes = WINED3DDTCAPS_UBYTE4 |
4709 WINED3DDTCAPS_UBYTE4N |
4710 WINED3DDTCAPS_SHORT2N |
4711 WINED3DDTCAPS_SHORT4N;
4712 if (gl_info->supported[ARB_HALF_FLOAT_VERTEX])
4714 pCaps->DeclTypes |= WINED3DDTCAPS_FLOAT16_2 |
4715 WINED3DDTCAPS_FLOAT16_4;
4718 pCaps->DeclTypes = 0;
4720 /* Set DirectDraw helper Caps */
4721 ckey_caps = WINEDDCKEYCAPS_DESTBLT |
4722 WINEDDCKEYCAPS_SRCBLT;
4723 fx_caps = WINEDDFXCAPS_BLTALPHA |
4724 WINEDDFXCAPS_BLTMIRRORLEFTRIGHT |
4725 WINEDDFXCAPS_BLTMIRRORUPDOWN |
4726 WINEDDFXCAPS_BLTROTATION90 |
4727 WINEDDFXCAPS_BLTSHRINKX |
4728 WINEDDFXCAPS_BLTSHRINKXN |
4729 WINEDDFXCAPS_BLTSHRINKY |
4730 WINEDDFXCAPS_BLTSHRINKXN |
4731 WINEDDFXCAPS_BLTSTRETCHX |
4732 WINEDDFXCAPS_BLTSTRETCHXN |
4733 WINEDDFXCAPS_BLTSTRETCHY |
4734 WINEDDFXCAPS_BLTSTRETCHYN;
4735 blit_caps = WINEDDCAPS_BLT |
4736 WINEDDCAPS_BLTCOLORFILL |
4737 WINEDDCAPS_BLTDEPTHFILL |
4738 WINEDDCAPS_BLTSTRETCH |
4739 WINEDDCAPS_CANBLTSYSMEM |
4740 WINEDDCAPS_CANCLIP |
4741 WINEDDCAPS_CANCLIPSTRETCHED |
4742 WINEDDCAPS_COLORKEY |
4743 WINEDDCAPS_COLORKEYHWASSIST |
4744 WINEDDCAPS_ALIGNBOUNDARYSRC;
4746 /* Fill the ddraw caps structure */
4747 pCaps->DirectDrawCaps.Caps = WINEDDCAPS_GDI |
4748 WINEDDCAPS_PALETTE |
4750 pCaps->DirectDrawCaps.Caps2 = WINEDDCAPS2_CERTIFIED |
4751 WINEDDCAPS2_NOPAGELOCKREQUIRED |
4752 WINEDDCAPS2_PRIMARYGAMMA |
4753 WINEDDCAPS2_WIDESURFACES |
4754 WINEDDCAPS2_CANRENDERWINDOWED;
4755 pCaps->DirectDrawCaps.SVBCaps = blit_caps;
4756 pCaps->DirectDrawCaps.SVBCKeyCaps = ckey_caps;
4757 pCaps->DirectDrawCaps.SVBFXCaps = fx_caps;
4758 pCaps->DirectDrawCaps.VSBCaps = blit_caps;
4759 pCaps->DirectDrawCaps.VSBCKeyCaps = ckey_caps;
4760 pCaps->DirectDrawCaps.VSBFXCaps = fx_caps;
4761 pCaps->DirectDrawCaps.SSBCaps = blit_caps;
4762 pCaps->DirectDrawCaps.SSBCKeyCaps = ckey_caps;
4763 pCaps->DirectDrawCaps.SSBFXCaps = fx_caps;
4765 pCaps->DirectDrawCaps.ddsCaps = WINEDDSCAPS_ALPHA |
4766 WINEDDSCAPS_BACKBUFFER |
4768 WINEDDSCAPS_FRONTBUFFER |
4769 WINEDDSCAPS_OFFSCREENPLAIN |
4770 WINEDDSCAPS_PALETTE |
4771 WINEDDSCAPS_PRIMARYSURFACE |
4772 WINEDDSCAPS_SYSTEMMEMORY |
4773 WINEDDSCAPS_VIDEOMEMORY |
4774 WINEDDSCAPS_VISIBLE;
4775 pCaps->DirectDrawCaps.StrideAlign = DDRAW_PITCH_ALIGNMENT;
4777 /* Set D3D caps if OpenGL is available. */
4778 if (adapter->opengl)
4780 pCaps->DirectDrawCaps.ddsCaps |=WINEDDSCAPS_3DDEVICE |
4781 WINEDDSCAPS_MIPMAP |
4782 WINEDDSCAPS_TEXTURE |
4783 WINEDDSCAPS_ZBUFFER;
4784 pCaps->DirectDrawCaps.Caps |= WINEDDCAPS_3D;
4790 static HRESULT WINAPI IWineD3DImpl_CreateDevice(IWineD3D *iface, UINT adapter_idx,
4791 WINED3DDEVTYPE device_type, HWND focus_window, DWORD flags, IUnknown *parent,
4792 IWineD3DDeviceParent *device_parent, IWineD3DDevice **device)
4794 IWineD3DImpl *This = (IWineD3DImpl *)iface;
4795 IWineD3DDeviceImpl *object;
4798 TRACE("iface %p, adapter_idx %u, device_type %#x, focus_window %p, flags %#x.\n"
4799 "parent %p, device_parent %p, device %p.\n",
4800 iface, adapter_idx, device_type, focus_window, flags,
4801 parent, device_parent, device);
4803 /* Validate the adapter number. If no adapters are available(no GL), ignore the adapter
4804 * number and create a device without a 3D adapter for 2D only operation. */
4805 if (IWineD3D_GetAdapterCount(iface) && adapter_idx >= IWineD3D_GetAdapterCount(iface))
4807 return WINED3DERR_INVALIDCALL;
4810 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
4813 ERR("Failed to allocate device memory.\n");
4814 return E_OUTOFMEMORY;
4817 hr = device_init(object, This, adapter_idx, device_type, focus_window, flags, parent, device_parent);
4820 WARN("Failed to initialize device, hr %#x.\n", hr);
4821 HeapFree(GetProcessHeap(), 0, object);
4825 TRACE("Created device %p.\n", object);
4826 *device = (IWineD3DDevice *)object;
4828 IWineD3DDeviceParent_WineD3DDeviceCreated(device_parent, *device);
4833 static HRESULT WINAPI IWineD3DImpl_GetParent(IWineD3D *iface, IUnknown **pParent) {
4834 IWineD3DImpl *This = (IWineD3DImpl *)iface;
4835 IUnknown_AddRef(This->parent);
4836 *pParent = This->parent;
4840 static void WINE_GLAPI invalid_func(const void *data)
4842 ERR("Invalid vertex attribute function called\n");
4846 static void WINE_GLAPI invalid_texcoord_func(GLenum unit, const void *data)
4848 ERR("Invalid texcoord function called\n");
4852 /* Helper functions for providing vertex data to opengl. The arrays are initialized based on
4853 * the extension detection and are used in drawStridedSlow
4855 static void WINE_GLAPI position_d3dcolor(const void *data)
4857 DWORD pos = *((const DWORD *)data);
4859 FIXME("Add a test for fixed function position from d3dcolor type\n");
4860 glVertex4s(D3DCOLOR_B_R(pos),
4866 static void WINE_GLAPI position_float4(const void *data)
4868 const GLfloat *pos = data;
4870 if (pos[3] != 0.0f && pos[3] != 1.0f)
4872 float w = 1.0f / pos[3];
4874 glVertex4f(pos[0] * w, pos[1] * w, pos[2] * w, w);
4882 static void WINE_GLAPI diffuse_d3dcolor(const void *data)
4884 DWORD diffuseColor = *((const DWORD *)data);
4886 glColor4ub(D3DCOLOR_B_R(diffuseColor),
4887 D3DCOLOR_B_G(diffuseColor),
4888 D3DCOLOR_B_B(diffuseColor),
4889 D3DCOLOR_B_A(diffuseColor));
4892 static void WINE_GLAPI specular_d3dcolor(const void *data)
4894 DWORD specularColor = *((const DWORD *)data);
4895 GLbyte d[] = {D3DCOLOR_B_R(specularColor),
4896 D3DCOLOR_B_G(specularColor),
4897 D3DCOLOR_B_B(specularColor)};
4899 specular_func_3ubv(d);
4902 static void WINE_GLAPI warn_no_specular_func(const void *data)
4904 WARN("GL_EXT_secondary_color not supported\n");
4907 static void fillGLAttribFuncs(const struct wined3d_gl_info *gl_info)
4909 position_funcs[WINED3D_FFP_EMIT_FLOAT1] = invalid_func;
4910 position_funcs[WINED3D_FFP_EMIT_FLOAT2] = invalid_func;
4911 position_funcs[WINED3D_FFP_EMIT_FLOAT3] = (glAttribFunc)glVertex3fv;
4912 position_funcs[WINED3D_FFP_EMIT_FLOAT4] = position_float4;
4913 position_funcs[WINED3D_FFP_EMIT_D3DCOLOR] = position_d3dcolor;
4914 position_funcs[WINED3D_FFP_EMIT_UBYTE4] = invalid_func;
4915 position_funcs[WINED3D_FFP_EMIT_SHORT2] = invalid_func;
4916 position_funcs[WINED3D_FFP_EMIT_SHORT4] = (glAttribFunc)glVertex2sv;
4917 position_funcs[WINED3D_FFP_EMIT_UBYTE4N] = invalid_func;
4918 position_funcs[WINED3D_FFP_EMIT_SHORT2N] = invalid_func;
4919 position_funcs[WINED3D_FFP_EMIT_SHORT4N] = invalid_func;
4920 position_funcs[WINED3D_FFP_EMIT_USHORT2N] = invalid_func;
4921 position_funcs[WINED3D_FFP_EMIT_USHORT4N] = invalid_func;
4922 position_funcs[WINED3D_FFP_EMIT_UDEC3] = invalid_func;
4923 position_funcs[WINED3D_FFP_EMIT_DEC3N] = invalid_func;
4924 position_funcs[WINED3D_FFP_EMIT_FLOAT16_2] = invalid_func;
4925 position_funcs[WINED3D_FFP_EMIT_FLOAT16_4] = invalid_func;
4927 diffuse_funcs[WINED3D_FFP_EMIT_FLOAT1] = invalid_func;
4928 diffuse_funcs[WINED3D_FFP_EMIT_FLOAT2] = invalid_func;
4929 diffuse_funcs[WINED3D_FFP_EMIT_FLOAT3] = (glAttribFunc)glColor3fv;
4930 diffuse_funcs[WINED3D_FFP_EMIT_FLOAT4] = (glAttribFunc)glColor4fv;
4931 diffuse_funcs[WINED3D_FFP_EMIT_D3DCOLOR] = diffuse_d3dcolor;
4932 diffuse_funcs[WINED3D_FFP_EMIT_UBYTE4] = invalid_func;
4933 diffuse_funcs[WINED3D_FFP_EMIT_SHORT2] = invalid_func;
4934 diffuse_funcs[WINED3D_FFP_EMIT_SHORT4] = invalid_func;
4935 diffuse_funcs[WINED3D_FFP_EMIT_UBYTE4N] = (glAttribFunc)glColor4ubv;
4936 diffuse_funcs[WINED3D_FFP_EMIT_SHORT2N] = invalid_func;
4937 diffuse_funcs[WINED3D_FFP_EMIT_SHORT4N] = (glAttribFunc)glColor4sv;
4938 diffuse_funcs[WINED3D_FFP_EMIT_USHORT2N] = invalid_func;
4939 diffuse_funcs[WINED3D_FFP_EMIT_USHORT4N] = (glAttribFunc)glColor4usv;
4940 diffuse_funcs[WINED3D_FFP_EMIT_UDEC3] = invalid_func;
4941 diffuse_funcs[WINED3D_FFP_EMIT_DEC3N] = invalid_func;
4942 diffuse_funcs[WINED3D_FFP_EMIT_FLOAT16_2] = invalid_func;
4943 diffuse_funcs[WINED3D_FFP_EMIT_FLOAT16_4] = invalid_func;
4945 /* No 4 component entry points here */
4946 specular_funcs[WINED3D_FFP_EMIT_FLOAT1] = invalid_func;
4947 specular_funcs[WINED3D_FFP_EMIT_FLOAT2] = invalid_func;
4948 if (gl_info->supported[EXT_SECONDARY_COLOR])
4950 specular_funcs[WINED3D_FFP_EMIT_FLOAT3] = (glAttribFunc)GL_EXTCALL(glSecondaryColor3fvEXT);
4954 specular_funcs[WINED3D_FFP_EMIT_FLOAT3] = warn_no_specular_func;
4956 specular_funcs[WINED3D_FFP_EMIT_FLOAT4] = invalid_func;
4957 if (gl_info->supported[EXT_SECONDARY_COLOR])
4959 specular_func_3ubv = (glAttribFunc)GL_EXTCALL(glSecondaryColor3ubvEXT);
4960 specular_funcs[WINED3D_FFP_EMIT_D3DCOLOR] = specular_d3dcolor;
4964 specular_funcs[WINED3D_FFP_EMIT_D3DCOLOR] = warn_no_specular_func;
4966 specular_funcs[WINED3D_FFP_EMIT_UBYTE4] = invalid_func;
4967 specular_funcs[WINED3D_FFP_EMIT_SHORT2] = invalid_func;
4968 specular_funcs[WINED3D_FFP_EMIT_SHORT4] = invalid_func;
4969 specular_funcs[WINED3D_FFP_EMIT_UBYTE4N] = invalid_func;
4970 specular_funcs[WINED3D_FFP_EMIT_SHORT2N] = invalid_func;
4971 specular_funcs[WINED3D_FFP_EMIT_SHORT4N] = invalid_func;
4972 specular_funcs[WINED3D_FFP_EMIT_USHORT2N] = invalid_func;
4973 specular_funcs[WINED3D_FFP_EMIT_USHORT4N] = invalid_func;
4974 specular_funcs[WINED3D_FFP_EMIT_UDEC3] = invalid_func;
4975 specular_funcs[WINED3D_FFP_EMIT_DEC3N] = invalid_func;
4976 specular_funcs[WINED3D_FFP_EMIT_FLOAT16_2] = invalid_func;
4977 specular_funcs[WINED3D_FFP_EMIT_FLOAT16_4] = invalid_func;
4979 /* Only 3 component entry points here. Test how others behave. Float4 normals are used
4980 * by one of our tests, trying to pass it to the pixel shader, which fails on Windows.
4982 normal_funcs[WINED3D_FFP_EMIT_FLOAT1] = invalid_func;
4983 normal_funcs[WINED3D_FFP_EMIT_FLOAT2] = invalid_func;
4984 normal_funcs[WINED3D_FFP_EMIT_FLOAT3] = (glAttribFunc)glNormal3fv;
4985 normal_funcs[WINED3D_FFP_EMIT_FLOAT4] = (glAttribFunc)glNormal3fv; /* Just ignore the 4th value */
4986 normal_funcs[WINED3D_FFP_EMIT_D3DCOLOR] = invalid_func;
4987 normal_funcs[WINED3D_FFP_EMIT_UBYTE4] = invalid_func;
4988 normal_funcs[WINED3D_FFP_EMIT_SHORT2] = invalid_func;
4989 normal_funcs[WINED3D_FFP_EMIT_SHORT4] = invalid_func;
4990 normal_funcs[WINED3D_FFP_EMIT_UBYTE4N] = invalid_func;
4991 normal_funcs[WINED3D_FFP_EMIT_SHORT2N] = invalid_func;
4992 normal_funcs[WINED3D_FFP_EMIT_SHORT4N] = invalid_func;
4993 normal_funcs[WINED3D_FFP_EMIT_USHORT2N] = invalid_func;
4994 normal_funcs[WINED3D_FFP_EMIT_USHORT4N] = invalid_func;
4995 normal_funcs[WINED3D_FFP_EMIT_UDEC3] = invalid_func;
4996 normal_funcs[WINED3D_FFP_EMIT_DEC3N] = invalid_func;
4997 normal_funcs[WINED3D_FFP_EMIT_FLOAT16_2] = invalid_func;
4998 normal_funcs[WINED3D_FFP_EMIT_FLOAT16_4] = invalid_func;
5000 multi_texcoord_funcs[WINED3D_FFP_EMIT_FLOAT1] = (glMultiTexCoordFunc)GL_EXTCALL(glMultiTexCoord1fvARB);
5001 multi_texcoord_funcs[WINED3D_FFP_EMIT_FLOAT2] = (glMultiTexCoordFunc)GL_EXTCALL(glMultiTexCoord2fvARB);
5002 multi_texcoord_funcs[WINED3D_FFP_EMIT_FLOAT3] = (glMultiTexCoordFunc)GL_EXTCALL(glMultiTexCoord3fvARB);
5003 multi_texcoord_funcs[WINED3D_FFP_EMIT_FLOAT4] = (glMultiTexCoordFunc)GL_EXTCALL(glMultiTexCoord4fvARB);
5004 multi_texcoord_funcs[WINED3D_FFP_EMIT_D3DCOLOR] = invalid_texcoord_func;
5005 multi_texcoord_funcs[WINED3D_FFP_EMIT_UBYTE4] = invalid_texcoord_func;
5006 multi_texcoord_funcs[WINED3D_FFP_EMIT_SHORT2] = (glMultiTexCoordFunc)GL_EXTCALL(glMultiTexCoord2svARB);
5007 multi_texcoord_funcs[WINED3D_FFP_EMIT_SHORT4] = (glMultiTexCoordFunc)GL_EXTCALL(glMultiTexCoord4svARB);
5008 multi_texcoord_funcs[WINED3D_FFP_EMIT_UBYTE4N] = invalid_texcoord_func;
5009 multi_texcoord_funcs[WINED3D_FFP_EMIT_SHORT2N] = invalid_texcoord_func;
5010 multi_texcoord_funcs[WINED3D_FFP_EMIT_SHORT4N] = invalid_texcoord_func;
5011 multi_texcoord_funcs[WINED3D_FFP_EMIT_USHORT2N] = invalid_texcoord_func;
5012 multi_texcoord_funcs[WINED3D_FFP_EMIT_USHORT4N] = invalid_texcoord_func;
5013 multi_texcoord_funcs[WINED3D_FFP_EMIT_UDEC3] = invalid_texcoord_func;
5014 multi_texcoord_funcs[WINED3D_FFP_EMIT_DEC3N] = invalid_texcoord_func;
5015 if (gl_info->supported[NV_HALF_FLOAT])
5017 /* Not supported by ARB_HALF_FLOAT_VERTEX, so check for NV_HALF_FLOAT */
5018 multi_texcoord_funcs[WINED3D_FFP_EMIT_FLOAT16_2] = (glMultiTexCoordFunc)GL_EXTCALL(glMultiTexCoord2hvNV);
5019 multi_texcoord_funcs[WINED3D_FFP_EMIT_FLOAT16_4] = (glMultiTexCoordFunc)GL_EXTCALL(glMultiTexCoord4hvNV);
5021 multi_texcoord_funcs[WINED3D_FFP_EMIT_FLOAT16_2] = invalid_texcoord_func;
5022 multi_texcoord_funcs[WINED3D_FFP_EMIT_FLOAT16_4] = invalid_texcoord_func;
5026 static BOOL InitAdapters(IWineD3DImpl *This)
5028 static HMODULE mod_gl;
5030 int ps_selected_mode, vs_selected_mode;
5032 /* No need to hold any lock. The calling library makes sure only one thread calls
5033 * wined3d simultaneously
5036 TRACE("Initializing adapters\n");
5039 #ifdef USE_WIN32_OPENGL
5040 #define USE_GL_FUNC(pfn) pfn = (void*)GetProcAddress(mod_gl, #pfn);
5041 mod_gl = LoadLibraryA("opengl32.dll");
5043 ERR("Can't load opengl32.dll!\n");
5047 #define USE_GL_FUNC(pfn) pfn = (void*)pwglGetProcAddress(#pfn);
5048 /* To bypass the opengl32 thunks load wglGetProcAddress from gdi32 (glXGetProcAddress wrapper) instead of opengl32's */
5049 mod_gl = GetModuleHandleA("gdi32.dll");
5053 /* Load WGL core functions from opengl32.dll */
5054 #define USE_WGL_FUNC(pfn) p##pfn = (void*)GetProcAddress(mod_gl, #pfn);
5058 if(!pwglGetProcAddress) {
5059 ERR("Unable to load wglGetProcAddress!\n");
5063 /* Dynamically load all GL core functions */
5067 /* Load glFinish and glFlush from opengl32.dll even if we're not using WIN32 opengl
5068 * otherwise because we have to use winex11.drv's override
5070 #ifdef USE_WIN32_OPENGL
5071 wglFinish = (void*)GetProcAddress(mod_gl, "glFinish");
5072 wglFlush = (void*)GetProcAddress(mod_gl, "glFlush");
5074 wglFinish = (void*)pwglGetProcAddress("wglFinish");
5075 wglFlush = (void*)pwglGetProcAddress("wglFlush");
5078 glEnableWINE = glEnable;
5079 glDisableWINE = glDisable;
5081 /* For now only one default adapter */
5083 struct wined3d_adapter *adapter = &This->adapters[0];
5084 const struct wined3d_gl_info *gl_info = &adapter->gl_info;
5085 struct wined3d_fake_gl_ctx fake_gl_ctx = {0};
5089 WineD3D_PixelFormat *cfgs;
5090 DISPLAY_DEVICEW DisplayDevice;
5093 TRACE("Initializing default adapter\n");
5094 adapter->ordinal = 0;
5095 adapter->monitorPoint.x = -1;
5096 adapter->monitorPoint.y = -1;
5098 if (!AllocateLocallyUniqueId(&adapter->luid))
5100 DWORD err = GetLastError();
5101 ERR("Failed to set adapter LUID (%#x).\n", err);
5104 TRACE("Allocated LUID %08x:%08x for adapter.\n",
5105 adapter->luid.HighPart, adapter->luid.LowPart);
5107 if (!WineD3D_CreateFakeGLContext(&fake_gl_ctx))
5109 ERR("Failed to get a gl context for default adapter\n");
5113 ret = IWineD3DImpl_FillGLCaps(adapter);
5115 ERR("Failed to initialize gl caps for default adapter\n");
5116 WineD3D_ReleaseFakeGLContext(&fake_gl_ctx);
5119 ret = initPixelFormats(&adapter->gl_info, adapter->driver_info.vendor);
5121 ERR("Failed to init gl formats\n");
5122 WineD3D_ReleaseFakeGLContext(&fake_gl_ctx);
5126 hdc = fake_gl_ctx.dc;
5128 /* Use the VideoRamSize registry setting when set */
5129 if(wined3d_settings.emulated_textureram)
5130 adapter->TextureRam = wined3d_settings.emulated_textureram;
5132 adapter->TextureRam = adapter->gl_info.vidmem;
5133 adapter->UsedTextureRam = 0;
5134 TRACE("Emulating %dMB of texture ram\n", adapter->TextureRam/(1024*1024));
5136 /* Initialize the Adapter's DeviceName which is required for ChangeDisplaySettings and friends */
5137 DisplayDevice.cb = sizeof(DisplayDevice);
5138 EnumDisplayDevicesW(NULL, 0 /* Adapter 0 = iDevNum 0 */, &DisplayDevice, 0);
5139 TRACE("DeviceName: %s\n", debugstr_w(DisplayDevice.DeviceName));
5140 strcpyW(adapter->DeviceName, DisplayDevice.DeviceName);
5142 if (gl_info->supported[WGL_ARB_PIXEL_FORMAT])
5149 attribute = WGL_NUMBER_PIXEL_FORMATS_ARB;
5150 GL_EXTCALL(wglGetPixelFormatAttribivARB(hdc, 0, 0, 1, &attribute, &adapter->nCfgs));
5152 adapter->cfgs = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, adapter->nCfgs *sizeof(WineD3D_PixelFormat));
5153 cfgs = adapter->cfgs;
5154 attribs[nAttribs++] = WGL_RED_BITS_ARB;
5155 attribs[nAttribs++] = WGL_GREEN_BITS_ARB;
5156 attribs[nAttribs++] = WGL_BLUE_BITS_ARB;
5157 attribs[nAttribs++] = WGL_ALPHA_BITS_ARB;
5158 attribs[nAttribs++] = WGL_COLOR_BITS_ARB;
5159 attribs[nAttribs++] = WGL_DEPTH_BITS_ARB;
5160 attribs[nAttribs++] = WGL_STENCIL_BITS_ARB;
5161 attribs[nAttribs++] = WGL_DRAW_TO_WINDOW_ARB;
5162 attribs[nAttribs++] = WGL_PIXEL_TYPE_ARB;
5163 attribs[nAttribs++] = WGL_DOUBLE_BUFFER_ARB;
5164 attribs[nAttribs++] = WGL_AUX_BUFFERS_ARB;
5166 for (iPixelFormat=1; iPixelFormat <= adapter->nCfgs; ++iPixelFormat)
5168 res = GL_EXTCALL(wglGetPixelFormatAttribivARB(hdc, iPixelFormat, 0, nAttribs, attribs, values));
5173 /* Cache the pixel format */
5174 cfgs->iPixelFormat = iPixelFormat;
5175 cfgs->redSize = values[0];
5176 cfgs->greenSize = values[1];
5177 cfgs->blueSize = values[2];
5178 cfgs->alphaSize = values[3];
5179 cfgs->colorSize = values[4];
5180 cfgs->depthSize = values[5];
5181 cfgs->stencilSize = values[6];
5182 cfgs->windowDrawable = values[7];
5183 cfgs->iPixelType = values[8];
5184 cfgs->doubleBuffer = values[9];
5185 cfgs->auxBuffers = values[10];
5187 cfgs->numSamples = 0;
5188 /* Check multisample support */
5189 if (gl_info->supported[ARB_MULTISAMPLE])
5191 int attrib[2] = {WGL_SAMPLE_BUFFERS_ARB, WGL_SAMPLES_ARB};
5193 if(GL_EXTCALL(wglGetPixelFormatAttribivARB(hdc, iPixelFormat, 0, 2, attrib, value))) {
5194 /* value[0] = WGL_SAMPLE_BUFFERS_ARB which tells whether multisampling is supported.
5195 * value[1] = number of multi sample buffers*/
5197 cfgs->numSamples = value[1];
5201 TRACE("iPixelFormat=%d, iPixelType=%#x, doubleBuffer=%d, RGBA=%d/%d/%d/%d, "
5202 "depth=%d, stencil=%d, samples=%d, windowDrawable=%d\n",
5203 cfgs->iPixelFormat, cfgs->iPixelType, cfgs->doubleBuffer,
5204 cfgs->redSize, cfgs->greenSize, cfgs->blueSize, cfgs->alphaSize,
5205 cfgs->depthSize, cfgs->stencilSize, cfgs->numSamples, cfgs->windowDrawable);
5211 int nCfgs = DescribePixelFormat(hdc, 0, 0, 0);
5212 adapter->cfgs = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, nCfgs*sizeof(WineD3D_PixelFormat));
5213 adapter->nCfgs = 0; /* We won't accept all formats e.g. software accelerated ones will be skipped */
5215 cfgs = adapter->cfgs;
5216 for(iPixelFormat=1; iPixelFormat<=nCfgs; iPixelFormat++)
5218 PIXELFORMATDESCRIPTOR ppfd;
5220 res = DescribePixelFormat(hdc, iPixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &ppfd);
5224 /* We only want HW acceleration using an OpenGL ICD driver.
5225 * PFD_GENERIC_FORMAT = slow opengl 1.1 gdi software rendering
5226 * PFD_GENERIC_ACCELERATED = partial hw acceleration using a MCD driver (e.g. 3dfx minigl)
5228 if(ppfd.dwFlags & (PFD_GENERIC_FORMAT | PFD_GENERIC_ACCELERATED))
5230 TRACE("Skipping iPixelFormat=%d because it isn't ICD accelerated\n", iPixelFormat);
5234 cfgs->iPixelFormat = iPixelFormat;
5235 cfgs->redSize = ppfd.cRedBits;
5236 cfgs->greenSize = ppfd.cGreenBits;
5237 cfgs->blueSize = ppfd.cBlueBits;
5238 cfgs->alphaSize = ppfd.cAlphaBits;
5239 cfgs->colorSize = ppfd.cColorBits;
5240 cfgs->depthSize = ppfd.cDepthBits;
5241 cfgs->stencilSize = ppfd.cStencilBits;
5242 cfgs->windowDrawable = (ppfd.dwFlags & PFD_DRAW_TO_WINDOW) ? 1 : 0;
5243 cfgs->iPixelType = (ppfd.iPixelType == PFD_TYPE_RGBA) ? WGL_TYPE_RGBA_ARB : WGL_TYPE_COLORINDEX_ARB;
5244 cfgs->doubleBuffer = (ppfd.dwFlags & PFD_DOUBLEBUFFER) ? 1 : 0;
5245 cfgs->auxBuffers = ppfd.cAuxBuffers;
5246 cfgs->numSamples = 0;
5248 TRACE("iPixelFormat=%d, iPixelType=%#x, doubleBuffer=%d, RGBA=%d/%d/%d/%d, "
5249 "depth=%d, stencil=%d, windowDrawable=%d\n",
5250 cfgs->iPixelFormat, cfgs->iPixelType, cfgs->doubleBuffer,
5251 cfgs->redSize, cfgs->greenSize, cfgs->blueSize, cfgs->alphaSize,
5252 cfgs->depthSize, cfgs->stencilSize, cfgs->windowDrawable);
5257 /* 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 */
5260 ERR("Disabling Direct3D because no hardware accelerated pixel formats have been found!\n");
5262 WineD3D_ReleaseFakeGLContext(&fake_gl_ctx);
5263 HeapFree(GetProcessHeap(), 0, adapter->cfgs);
5268 /* D16, D24X8 and D24S8 are common depth / depth+stencil formats. All drivers support them though this doesn't
5269 * mean that the format is offered in hardware. For instance Geforce8 cards don't have offer D16 in hardware
5270 * but just fake it using D24(X8?) which is fine. D3D also allows that.
5271 * Some display drivers (i915 on Linux) only report mixed depth+stencil formats like D24S8. MSDN clearly mentions
5272 * that only on lockable formats (e.g. D16_locked) the bit order is guaranteed and that on other formats the
5273 * driver is allowed to consume more bits EXCEPT for stencil bits.
5275 * Mark an adapter with this broken stencil behavior.
5277 adapter->brokenStencil = TRUE;
5278 for (i = 0, cfgs = adapter->cfgs; i < adapter->nCfgs; ++i)
5280 /* Nearly all drivers offer depth formats without stencil, only on i915 this if-statement won't be entered. */
5281 if(cfgs[i].depthSize && !cfgs[i].stencilSize) {
5282 adapter->brokenStencil = FALSE;
5287 WineD3D_ReleaseFakeGLContext(&fake_gl_ctx);
5289 select_shader_mode(&adapter->gl_info, &ps_selected_mode, &vs_selected_mode);
5290 fillGLAttribFuncs(&adapter->gl_info);
5291 adapter->opengl = TRUE;
5293 This->adapter_count = 1;
5294 TRACE("%u adapters successfully initialized\n", This->adapter_count);
5299 /* Initialize an adapter for ddraw-only memory counting */
5300 memset(This->adapters, 0, sizeof(This->adapters));
5301 This->adapters[0].ordinal = 0;
5302 This->adapters[0].opengl = FALSE;
5303 This->adapters[0].monitorPoint.x = -1;
5304 This->adapters[0].monitorPoint.y = -1;
5306 This->adapters[0].driver_info.name = "Display";
5307 This->adapters[0].driver_info.description = "WineD3D DirectDraw Emulation";
5308 if(wined3d_settings.emulated_textureram) {
5309 This->adapters[0].TextureRam = wined3d_settings.emulated_textureram;
5311 This->adapters[0].TextureRam = 8 * 1024 * 1024; /* This is plenty for a DDraw-only card */
5314 initPixelFormatsNoGL(&This->adapters[0].gl_info);
5316 This->adapter_count = 1;
5320 /**********************************************************
5321 * IWineD3D VTbl follows
5322 **********************************************************/
5324 static const struct IWineD3DVtbl IWineD3D_Vtbl =
5327 IWineD3DImpl_QueryInterface,
5328 IWineD3DImpl_AddRef,
5329 IWineD3DImpl_Release,
5331 IWineD3DImpl_GetParent,
5332 IWineD3DImpl_GetAdapterCount,
5333 IWineD3DImpl_RegisterSoftwareDevice,
5334 IWineD3DImpl_GetAdapterMonitor,
5335 IWineD3DImpl_GetAdapterModeCount,
5336 IWineD3DImpl_EnumAdapterModes,
5337 IWineD3DImpl_GetAdapterDisplayMode,
5338 IWineD3DImpl_GetAdapterIdentifier,
5339 IWineD3DImpl_CheckDeviceMultiSampleType,
5340 IWineD3DImpl_CheckDepthStencilMatch,
5341 IWineD3DImpl_CheckDeviceType,
5342 IWineD3DImpl_CheckDeviceFormat,
5343 IWineD3DImpl_CheckDeviceFormatConversion,
5344 IWineD3DImpl_GetDeviceCaps,
5345 IWineD3DImpl_CreateDevice
5348 static void STDMETHODCALLTYPE wined3d_null_wined3d_object_destroyed(void *parent) {}
5350 const struct wined3d_parent_ops wined3d_null_parent_ops =
5352 wined3d_null_wined3d_object_destroyed,
5355 HRESULT wined3d_init(IWineD3DImpl *wined3d, UINT version, IUnknown *parent)
5357 wined3d->lpVtbl = &IWineD3D_Vtbl;
5358 wined3d->dxVersion = version;
5360 wined3d->parent = parent;
5362 if (!InitAdapters(wined3d))
5364 WARN("Failed to initialize adapters.\n");
5367 MESSAGE("Direct3D%u is not available without OpenGL.\n", version);