VirtualBox

source: vbox/trunk/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/directx.c@ 39819

Last change on this file since 39819 was 39819, checked in by vboxsync, 13 years ago

wddm/3d: fix ie rendering with mesa nvidia drivers

  • Property svn:eol-style set to native
File size: 238.5 KB
Line 
1/*
2 * IWineD3D implementation
3 *
4 * Copyright 2002-2004 Jason Edmeades
5 * Copyright 2003-2004 Raphael Junqueira
6 * Copyright 2004 Christian Costa
7 * Copyright 2005 Oliver Stieber
8 * Copyright 2007-2008 Stefan Dösinger for CodeWeavers
9 * Copyright 2009 Henri Verbeet for CodeWeavers
10 *
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.
15 *
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.
20 *
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
24 */
25
26/*
27 * Oracle LGPL Disclaimer: For the avoidance of doubt, except that if any license choice
28 * other than GPL or LGPL is available it will apply instead, Oracle elects to use only
29 * the Lesser General Public License version 2.1 (LGPLv2) at this time for any software where
30 * a choice of LGPL license versions is made available with the language indicating
31 * that LGPLv2 or any later version may be used, or where a choice of which version
32 * of the LGPL is applied is otherwise unspecified.
33 */
34
35#include "config.h"
36#include <stdio.h>
37#include "wined3d_private.h"
38
39WINE_DEFAULT_DEBUG_CHANNEL(d3d);
40WINE_DECLARE_DEBUG_CHANNEL(d3d_caps);
41
42#define GLINFO_LOCATION (*gl_info)
43#define WINE_DEFAULT_VIDMEM (64 * 1024 * 1024)
44
45/* The d3d device ID */
46static const GUID IID_D3DDEVICE_D3DUID = { 0xaeb2cdd4, 0x6e41, 0x43ea, { 0x94,0x1c,0x83,0x61,0xcc,0x76,0x07,0x81 } };
47
48/* Extension detection */
49static const struct {
50 const char *extension_string;
51 GL_SupportedExt extension;
52 DWORD version;
53} EXTENSION_MAP[] = {
54 /* APPLE */
55 {"GL_APPLE_client_storage", APPLE_CLIENT_STORAGE, 0 },
56 {"GL_APPLE_fence", APPLE_FENCE, 0 },
57 {"GL_APPLE_float_pixels", APPLE_FLOAT_PIXELS, 0 },
58 {"GL_APPLE_flush_buffer_range", APPLE_FLUSH_BUFFER_RANGE, 0 },
59 {"GL_APPLE_flush_render", APPLE_FLUSH_RENDER, 0 },
60 {"GL_APPLE_ycbcr_422", APPLE_YCBCR_422, 0 },
61
62 /* ARB */
63 {"GL_ARB_color_buffer_float", ARB_COLOR_BUFFER_FLOAT, 0 },
64 {"GL_ARB_depth_buffer_float", ARB_DEPTH_BUFFER_FLOAT, 0 },
65 {"GL_ARB_depth_clamp", ARB_DEPTH_CLAMP, 0 },
66 {"GL_ARB_depth_texture", ARB_DEPTH_TEXTURE, 0 },
67 {"GL_ARB_draw_buffers", ARB_DRAW_BUFFERS, 0 },
68 {"GL_ARB_fragment_program", ARB_FRAGMENT_PROGRAM, 0 },
69 {"GL_ARB_fragment_shader", ARB_FRAGMENT_SHADER, 0 },
70 {"GL_ARB_framebuffer_object", ARB_FRAMEBUFFER_OBJECT, 0 },
71 {"GL_ARB_geometry_shader4", ARB_GEOMETRY_SHADER4, 0 },
72 {"GL_ARB_half_float_pixel", ARB_HALF_FLOAT_PIXEL, 0 },
73 {"GL_ARB_half_float_vertex", ARB_HALF_FLOAT_VERTEX, 0 },
74 {"GL_ARB_imaging", ARB_IMAGING, 0 },
75 {"GL_ARB_map_buffer_range", ARB_MAP_BUFFER_RANGE, 0 },
76 {"GL_ARB_multisample", ARB_MULTISAMPLE, 0 }, /* needs GLX_ARB_MULTISAMPLE as well */
77 {"GL_ARB_multitexture", ARB_MULTITEXTURE, 0 },
78 {"GL_ARB_occlusion_query", ARB_OCCLUSION_QUERY, 0 },
79 {"GL_ARB_pixel_buffer_object", ARB_PIXEL_BUFFER_OBJECT, 0 },
80 {"GL_ARB_point_parameters", ARB_POINT_PARAMETERS, 0 },
81 {"GL_ARB_point_sprite", ARB_POINT_SPRITE, 0 },
82 {"GL_ARB_provoking_vertex", ARB_PROVOKING_VERTEX, 0 },
83 {"GL_ARB_shader_objects", ARB_SHADER_OBJECTS, 0 },
84 {"GL_ARB_shader_texture_lod", ARB_SHADER_TEXTURE_LOD, 0 },
85 {"GL_ARB_shading_language_100", ARB_SHADING_LANGUAGE_100, 0 },
86 {"GL_ARB_sync", ARB_SYNC, 0 },
87 {"GL_ARB_texture_border_clamp", ARB_TEXTURE_BORDER_CLAMP, 0 },
88 {"GL_ARB_texture_compression", ARB_TEXTURE_COMPRESSION, 0 },
89 {"GL_ARB_texture_cube_map", ARB_TEXTURE_CUBE_MAP, 0 },
90 {"GL_ARB_texture_env_add", ARB_TEXTURE_ENV_ADD, 0 },
91 {"GL_ARB_texture_env_combine", ARB_TEXTURE_ENV_COMBINE, 0 },
92 {"GL_ARB_texture_env_dot3", ARB_TEXTURE_ENV_DOT3, 0 },
93 {"GL_ARB_texture_float", ARB_TEXTURE_FLOAT, 0 },
94 {"GL_ARB_texture_mirrored_repeat", ARB_TEXTURE_MIRRORED_REPEAT, 0 },
95 {"GL_ARB_texture_non_power_of_two", ARB_TEXTURE_NON_POWER_OF_TWO, MAKEDWORD_VERSION(2, 0) },
96 {"GL_ARB_texture_rectangle", ARB_TEXTURE_RECTANGLE, 0 },
97 {"GL_ARB_texture_rg", ARB_TEXTURE_RG, 0 },
98 {"GL_ARB_vertex_array_bgra", ARB_VERTEX_ARRAY_BGRA, 0 },
99 {"GL_ARB_vertex_blend", ARB_VERTEX_BLEND, 0 },
100 {"GL_ARB_vertex_buffer_object", ARB_VERTEX_BUFFER_OBJECT, 0 },
101 {"GL_ARB_vertex_program", ARB_VERTEX_PROGRAM, 0 },
102 {"GL_ARB_vertex_shader", ARB_VERTEX_SHADER, 0 },
103
104 /* ATI */
105 {"GL_ATI_fragment_shader", ATI_FRAGMENT_SHADER, 0 },
106 {"GL_ATI_separate_stencil", ATI_SEPARATE_STENCIL, 0 },
107 {"GL_ATI_texture_compression_3dc", ATI_TEXTURE_COMPRESSION_3DC, 0 },
108 {"GL_ATI_texture_env_combine3", ATI_TEXTURE_ENV_COMBINE3, 0 },
109 {"GL_ATI_texture_mirror_once", ATI_TEXTURE_MIRROR_ONCE, 0 },
110
111 /* EXT */
112 {"GL_EXT_blend_color", EXT_BLEND_COLOR, 0 },
113 {"GL_EXT_blend_equation_separate", EXT_BLEND_EQUATION_SEPARATE, 0 },
114 {"GL_EXT_blend_func_separate", EXT_BLEND_FUNC_SEPARATE, 0 },
115 {"GL_EXT_blend_minmax", EXT_BLEND_MINMAX, 0 },
116 {"GL_EXT_draw_buffers2", EXT_DRAW_BUFFERS2, 0 },
117 {"GL_EXT_fog_coord", EXT_FOG_COORD, 0 },
118 {"GL_EXT_framebuffer_blit", EXT_FRAMEBUFFER_BLIT, 0 },
119 {"GL_EXT_framebuffer_multisample", EXT_FRAMEBUFFER_MULTISAMPLE, 0 },
120 {"GL_EXT_framebuffer_object", EXT_FRAMEBUFFER_OBJECT, 0 },
121 {"GL_EXT_gpu_program_parameters", EXT_GPU_PROGRAM_PARAMETERS, 0 },
122 {"GL_EXT_gpu_shader4", EXT_GPU_SHADER4, 0 },
123 {"GL_EXT_packed_depth_stencil", EXT_PACKED_DEPTH_STENCIL, 0 },
124 {"GL_EXT_paletted_texture", EXT_PALETTED_TEXTURE, 0 },
125 {"GL_EXT_point_parameters", EXT_POINT_PARAMETERS, 0 },
126 {"GL_EXT_provoking_vertex", EXT_PROVOKING_VERTEX, 0 },
127 {"GL_EXT_secondary_color", EXT_SECONDARY_COLOR, 0 },
128 {"GL_EXT_stencil_two_side", EXT_STENCIL_TWO_SIDE, 0 },
129 {"GL_EXT_stencil_wrap", EXT_STENCIL_WRAP, 0 },
130 {"GL_EXT_texture3D", EXT_TEXTURE3D, MAKEDWORD_VERSION(1, 2) },
131 {"GL_EXT_texture_compression_rgtc", EXT_TEXTURE_COMPRESSION_RGTC, 0 },
132 {"GL_EXT_texture_compression_s3tc", EXT_TEXTURE_COMPRESSION_S3TC, 0 },
133 {"GL_EXT_texture_env_add", EXT_TEXTURE_ENV_ADD, 0 },
134 {"GL_EXT_texture_env_combine", EXT_TEXTURE_ENV_COMBINE, 0 },
135 {"GL_EXT_texture_env_dot3", EXT_TEXTURE_ENV_DOT3, 0 },
136 {"GL_EXT_texture_filter_anisotropic", EXT_TEXTURE_FILTER_ANISOTROPIC, 0 },
137 {"GL_EXT_texture_lod_bias", EXT_TEXTURE_LOD_BIAS, 0 },
138 {"GL_EXT_texture_sRGB", EXT_TEXTURE_SRGB, 0 },
139 {"GL_EXT_vertex_array_bgra", EXT_VERTEX_ARRAY_BGRA, 0 },
140
141 /* NV */
142 {"GL_NV_depth_clamp", NV_DEPTH_CLAMP, 0 },
143 {"GL_NV_fence", NV_FENCE, 0 },
144 {"GL_NV_fog_distance", NV_FOG_DISTANCE, 0 },
145 {"GL_NV_fragment_program", NV_FRAGMENT_PROGRAM, 0 },
146 {"GL_NV_fragment_program2", NV_FRAGMENT_PROGRAM2, 0 },
147 {"GL_NV_fragment_program_option", NV_FRAGMENT_PROGRAM_OPTION, 0 },
148 {"GL_NV_half_float", NV_HALF_FLOAT, 0 },
149 {"GL_NV_light_max_exponent", NV_LIGHT_MAX_EXPONENT, 0 },
150 {"GL_NV_register_combiners", NV_REGISTER_COMBINERS, 0 },
151 {"GL_NV_register_combiners2", NV_REGISTER_COMBINERS2, 0 },
152 {"GL_NV_texgen_reflection", NV_TEXGEN_REFLECTION, 0 },
153 {"GL_NV_texture_env_combine4", NV_TEXTURE_ENV_COMBINE4, 0 },
154 {"GL_NV_texture_shader", NV_TEXTURE_SHADER, 0 },
155 {"GL_NV_texture_shader2", NV_TEXTURE_SHADER2, 0 },
156 {"GL_NV_vertex_program", NV_VERTEX_PROGRAM, 0 },
157 {"GL_NV_vertex_program1_1", NV_VERTEX_PROGRAM1_1, 0 },
158 {"GL_NV_vertex_program2", NV_VERTEX_PROGRAM2, 0 },
159 {"GL_NV_vertex_program2_option", NV_VERTEX_PROGRAM2_OPTION, 0 },
160 {"GL_NV_vertex_program3", NV_VERTEX_PROGRAM3, 0 },
161
162 /* SGI */
163 {"GL_SGIS_generate_mipmap", SGIS_GENERATE_MIPMAP, 0 },
164};
165
166/**********************************************************
167 * Utility functions follow
168 **********************************************************/
169
170static HRESULT WINAPI IWineD3DImpl_CheckDeviceFormat(IWineD3D *iface, UINT Adapter, WINED3DDEVTYPE DeviceType, WINED3DFORMAT AdapterFormat, DWORD Usage, WINED3DRESOURCETYPE RType, WINED3DFORMAT CheckFormat, WINED3DSURFTYPE SurfaceType);
171
172const struct min_lookup minMipLookup[] =
173{
174 /* NONE POINT LINEAR */
175 {{GL_NEAREST, GL_NEAREST, GL_NEAREST}}, /* NONE */
176 {{GL_NEAREST, GL_NEAREST_MIPMAP_NEAREST, GL_NEAREST_MIPMAP_LINEAR}}, /* POINT*/
177 {{GL_LINEAR, GL_LINEAR_MIPMAP_NEAREST, GL_LINEAR_MIPMAP_LINEAR}}, /* LINEAR */
178};
179
180const struct min_lookup minMipLookup_noFilter[] =
181{
182 /* NONE POINT LINEAR */
183 {{GL_NEAREST, GL_NEAREST, GL_NEAREST}}, /* NONE */
184 {{GL_NEAREST, GL_NEAREST, GL_NEAREST}}, /* POINT */
185 {{GL_NEAREST, GL_NEAREST, GL_NEAREST}}, /* LINEAR */
186};
187
188const struct min_lookup minMipLookup_noMip[] =
189{
190 /* NONE POINT LINEAR */
191 {{GL_NEAREST, GL_NEAREST, GL_NEAREST}}, /* NONE */
192 {{GL_NEAREST, GL_NEAREST, GL_NEAREST}}, /* POINT */
193 {{GL_LINEAR, GL_LINEAR, GL_LINEAR }}, /* LINEAR */
194};
195
196const GLenum magLookup[] =
197{
198 /* NONE POINT LINEAR */
199 GL_NEAREST, GL_NEAREST, GL_LINEAR,
200};
201
202const GLenum magLookup_noFilter[] =
203{
204 /* NONE POINT LINEAR */
205 GL_NEAREST, GL_NEAREST, GL_NEAREST,
206};
207
208/* drawStridedSlow attributes */
209glAttribFunc position_funcs[WINED3D_FFP_EMIT_COUNT];
210glAttribFunc diffuse_funcs[WINED3D_FFP_EMIT_COUNT];
211glAttribFunc specular_func_3ubv;
212glAttribFunc specular_funcs[WINED3D_FFP_EMIT_COUNT];
213glAttribFunc normal_funcs[WINED3D_FFP_EMIT_COUNT];
214glMultiTexCoordFunc multi_texcoord_funcs[WINED3D_FFP_EMIT_COUNT];
215
216/**
217 * Note: GL seems to trap if GetDeviceCaps is called before any HWND's created,
218 * i.e., there is no GL Context - Get a default rendering context to enable the
219 * function query some info from GL.
220 */
221
222struct wined3d_fake_gl_ctx
223{
224 HDC dc;
225 HWND wnd;
226 HGLRC gl_ctx;
227 HDC restore_dc;
228 HGLRC restore_gl_ctx;
229};
230
231static void WineD3D_ReleaseFakeGLContext(struct wined3d_fake_gl_ctx *ctx)
232{
233 TRACE_(d3d_caps)("Destroying fake GL context.\n");
234
235 if (!pwglMakeCurrent(NULL, NULL))
236 {
237 ERR_(d3d_caps)("Failed to disable fake GL context.\n");
238 }
239
240 if (!pwglDeleteContext(ctx->gl_ctx))
241 {
242 DWORD err = GetLastError();
243 ERR("wglDeleteContext(%p) failed, last error %#x.\n", ctx->gl_ctx, err);
244 }
245
246 ReleaseDC(ctx->wnd, ctx->dc);
247 DestroyWindow(ctx->wnd);
248
249 if (ctx->restore_gl_ctx && !pwglMakeCurrent(ctx->restore_dc, ctx->restore_gl_ctx))
250 {
251 ERR_(d3d_caps)("Failed to restore previous GL context.\n");
252 }
253}
254
255static BOOL WineD3D_CreateFakeGLContext(struct wined3d_fake_gl_ctx *ctx)
256{
257 PIXELFORMATDESCRIPTOR pfd;
258 int iPixelFormat;
259
260 TRACE("getting context...\n");
261
262 ctx->restore_dc = pwglGetCurrentDC();
263 ctx->restore_gl_ctx = pwglGetCurrentContext();
264
265 /* We need a fake window as a hdc retrieved using GetDC(0) can't be used for much GL purposes. */
266 ctx->wnd = CreateWindowA(WINED3D_OPENGL_WINDOW_CLASS_NAME, "WineD3D fake window",
267 WS_OVERLAPPEDWINDOW, 10, 10, 10, 10, NULL, NULL, NULL, NULL);
268 if (!ctx->wnd)
269 {
270 ERR_(d3d_caps)("Failed to create a window.\n");
271 goto fail;
272 }
273
274 ctx->dc = GetDC(ctx->wnd);
275 if (!ctx->dc)
276 {
277 ERR_(d3d_caps)("Failed to get a DC.\n");
278 goto fail;
279 }
280
281 /* PixelFormat selection */
282 ZeroMemory(&pfd, sizeof(pfd));
283 pfd.nSize = sizeof(pfd);
284 pfd.nVersion = 1;
285 pfd.dwFlags = PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER | PFD_DRAW_TO_WINDOW; /* PFD_GENERIC_ACCELERATED */
286 pfd.iPixelType = PFD_TYPE_RGBA;
287 pfd.cColorBits = 32;
288 pfd.iLayerType = PFD_MAIN_PLANE;
289
290 iPixelFormat = ChoosePixelFormat(ctx->dc, &pfd);
291 if (!iPixelFormat)
292 {
293 /* If this happens something is very wrong as ChoosePixelFormat barely fails. */
294 ERR_(d3d_caps)("Can't find a suitable iPixelFormat.\n");
295 goto fail;
296 }
297 DescribePixelFormat(ctx->dc, iPixelFormat, sizeof(pfd), &pfd);
298 SetPixelFormat(ctx->dc, iPixelFormat, &pfd);
299
300 /* Create a GL context. */
301 ctx->gl_ctx = pwglCreateContext(ctx->dc);
302 if (!ctx->gl_ctx)
303 {
304 WARN_(d3d_caps)("Error creating default context for capabilities initialization.\n");
305 goto fail;
306 }
307
308 /* Make it the current GL context. */
309 if (!context_set_current(NULL))
310 {
311 ERR_(d3d_caps)("Failed to clear current D3D context.\n");
312 }
313
314 if (!pwglMakeCurrent(ctx->dc, ctx->gl_ctx))
315 {
316 ERR_(d3d_caps)("Failed to make fake GL context current.\n");
317 goto fail;
318 }
319
320 return TRUE;
321
322fail:
323 if (ctx->gl_ctx) pwglDeleteContext(ctx->gl_ctx);
324 ctx->gl_ctx = NULL;
325 if (ctx->dc) ReleaseDC(ctx->wnd, ctx->dc);
326 ctx->dc = NULL;
327 if (ctx->wnd) DestroyWindow(ctx->wnd);
328 ctx->wnd = NULL;
329 if (ctx->restore_gl_ctx && !pwglMakeCurrent(ctx->restore_dc, ctx->restore_gl_ctx))
330 {
331 ERR_(d3d_caps)("Failed to restore previous GL context.\n");
332 }
333
334 return FALSE;
335}
336
337/* Adjust the amount of used texture memory */
338long WineD3DAdapterChangeGLRam(IWineD3DDeviceImpl *D3DDevice, long glram)
339{
340 struct wined3d_adapter *adapter = D3DDevice->adapter;
341
342 adapter->UsedTextureRam += glram;
343 TRACE("Adjusted gl ram by %ld to %d\n", glram, adapter->UsedTextureRam);
344 return adapter->UsedTextureRam;
345}
346
347static void wined3d_adapter_cleanup(struct wined3d_adapter *adapter)
348{
349 HeapFree(GetProcessHeap(), 0, adapter->gl_info.gl_formats);
350 HeapFree(GetProcessHeap(), 0, adapter->cfgs);
351}
352
353/**********************************************************
354 * IUnknown parts follows
355 **********************************************************/
356
357static HRESULT WINAPI IWineD3DImpl_QueryInterface(IWineD3D *iface,REFIID riid,LPVOID *ppobj)
358{
359 IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
360
361 TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(riid),ppobj);
362 if (IsEqualGUID(riid, &IID_IUnknown)
363 || IsEqualGUID(riid, &IID_IWineD3DBase)
364 || IsEqualGUID(riid, &IID_IWineD3DDevice)) {
365 IUnknown_AddRef(iface);
366 *ppobj = This;
367 return S_OK;
368 }
369 *ppobj = NULL;
370 return E_NOINTERFACE;
371}
372
373static ULONG WINAPI IWineD3DImpl_AddRef(IWineD3D *iface) {
374 IWineD3DImpl *This = (IWineD3DImpl *)iface;
375 ULONG refCount = InterlockedIncrement(&This->ref);
376
377 TRACE("(%p) : AddRef increasing from %d\n", This, refCount - 1);
378 return refCount;
379}
380
381static ULONG WINAPI IWineD3DImpl_Release(IWineD3D *iface) {
382 IWineD3DImpl *This = (IWineD3DImpl *)iface;
383 ULONG ref;
384 TRACE("(%p) : Releasing from %d\n", This, This->ref);
385 ref = InterlockedDecrement(&This->ref);
386 if (ref == 0) {
387 unsigned int i;
388
389 for (i = 0; i < This->adapter_count; ++i)
390 {
391 wined3d_adapter_cleanup(&This->adapters[i]);
392 }
393 HeapFree(GetProcessHeap(), 0, This);
394
395#ifdef VBOX_WITH_WDDM
396 VBoxExtCheckTerm();
397#endif
398 }
399
400 return ref;
401}
402
403/**********************************************************
404 * IWineD3D parts follows
405 **********************************************************/
406
407/* GL locking is done by the caller */
408static inline BOOL test_arb_vs_offset_limit(const struct wined3d_gl_info *gl_info)
409{
410 GLuint prog;
411 BOOL ret = FALSE;
412 const char *testcode =
413 "!!ARBvp1.0\n"
414 "PARAM C[66] = { program.env[0..65] };\n"
415 "ADDRESS A0;"
416 "PARAM zero = {0.0, 0.0, 0.0, 0.0};\n"
417 "ARL A0.x, zero.x;\n"
418 "MOV result.position, C[A0.x + 65];\n"
419 "END\n";
420
421 while(glGetError());
422 GL_EXTCALL(glGenProgramsARB(1, &prog));
423 if(!prog) {
424 ERR("Failed to create an ARB offset limit test program\n");
425 }
426 GL_EXTCALL(glBindProgramARB(GL_VERTEX_PROGRAM_ARB, prog));
427 GL_EXTCALL(glProgramStringARB(GL_VERTEX_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB,
428 strlen(testcode), testcode));
429 if(glGetError() != 0) {
430 TRACE("OpenGL implementation does not allow indirect addressing offsets > 63\n");
431 TRACE("error: %s\n", debugstr_a((const char *)glGetString(GL_PROGRAM_ERROR_STRING_ARB)));
432 ret = TRUE;
433 } else TRACE("OpenGL implementation allows offsets > 63\n");
434
435 GL_EXTCALL(glBindProgramARB(GL_VERTEX_PROGRAM_ARB, 0));
436 GL_EXTCALL(glDeleteProgramsARB(1, &prog));
437 checkGLcall("ARB vp offset limit test cleanup");
438
439 return ret;
440}
441
442static DWORD ver_for_ext(GL_SupportedExt ext)
443{
444 unsigned int i;
445 for (i = 0; i < (sizeof(EXTENSION_MAP) / sizeof(*EXTENSION_MAP)); ++i) {
446 if(EXTENSION_MAP[i].extension == ext) {
447 return EXTENSION_MAP[i].version;
448 }
449 }
450 return 0;
451}
452
453static BOOL match_ati_r300_to_500(const struct wined3d_gl_info *gl_info, const char *gl_renderer,
454 enum wined3d_gl_vendor gl_vendor, enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device)
455{
456 if (card_vendor != HW_VENDOR_ATI) return FALSE;
457 if (device == CARD_ATI_RADEON_9500) return TRUE;
458 if (device == CARD_ATI_RADEON_X700) return TRUE;
459 if (device == CARD_ATI_RADEON_X1600) return TRUE;
460 return FALSE;
461}
462
463static BOOL match_geforce5(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)
465{
466 if (card_vendor == HW_VENDOR_NVIDIA)
467 {
468 if (device == CARD_NVIDIA_GEFORCEFX_5800 || device == CARD_NVIDIA_GEFORCEFX_5600)
469 {
470 return TRUE;
471 }
472 }
473 return FALSE;
474}
475
476static BOOL match_apple(const struct wined3d_gl_info *gl_info, const char *gl_renderer,
477 enum wined3d_gl_vendor gl_vendor, enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device)
478{
479 /* MacOS has various specialities in the extensions it advertises. Some have to be loaded from
480 * the opengl 1.2+ core, while other extensions are advertised, but software emulated. So try to
481 * detect the Apple OpenGL implementation to apply some extension fixups afterwards.
482 *
483 * Detecting this isn't really easy. The vendor string doesn't mention Apple. Compile-time checks
484 * aren't sufficient either because a Linux binary may display on a macos X server via remote X11.
485 * So try to detect the GL implementation by looking at certain Apple extensions. Some extensions
486 * like client storage might be supported on other implementations too, but GL_APPLE_flush_render
487 * is specific to the Mac OS X window management, and GL_APPLE_ycbcr_422 is QuickTime specific. So
488 * the chance that other implementations support them is rather small since Win32 QuickTime uses
489 * DirectDraw, not OpenGL.
490 *
491 * This test has been moved into wined3d_guess_gl_vendor()
492 */
493 if (gl_vendor == GL_VENDOR_APPLE)
494 {
495 return TRUE;
496 }
497 return FALSE;
498}
499
500/* Context activation is done by the caller. */
501static void test_pbo_functionality(struct wined3d_gl_info *gl_info)
502{
503 /* Some OpenGL implementations, namely Apple's Geforce 8 driver, advertises PBOs,
504 * but glTexSubImage from a PBO fails miserably, with the first line repeated over
505 * all the texture. This function detects this bug by its symptom and disables PBOs
506 * if the test fails.
507 *
508 * The test uploads a 4x4 texture via the PBO in the "native" format GL_BGRA,
509 * GL_UNSIGNED_INT_8_8_8_8_REV. This format triggers the bug, and it is what we use
510 * for D3DFMT_A8R8G8B8. Then the texture is read back without any PBO and the data
511 * read back is compared to the original. If they are equal PBOs are assumed to work,
512 * otherwise the PBO extension is disabled. */
513 GLuint texture, pbo;
514 static const unsigned int pattern[] =
515 {
516 0x00000000, 0x000000ff, 0x0000ff00, 0x40ff0000,
517 0x80ffffff, 0x40ffff00, 0x00ff00ff, 0x0000ffff,
518 0x00ffff00, 0x00ff00ff, 0x0000ffff, 0x000000ff,
519 0x80ff00ff, 0x0000ffff, 0x00ff00ff, 0x40ff00ff
520 };
521 unsigned int check[sizeof(pattern) / sizeof(pattern[0])];
522
523 /* No PBO -> No point in testing them. */
524 if (!gl_info->supported[ARB_PIXEL_BUFFER_OBJECT]) return;
525
526 ENTER_GL();
527
528 while (glGetError());
529 glGenTextures(1, &texture);
530 glBindTexture(GL_TEXTURE_2D, texture);
531
532 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
533 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 4, 4, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, 0);
534 checkGLcall("Specifying the PBO test texture");
535
536 GL_EXTCALL(glGenBuffersARB(1, &pbo));
537 GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, pbo));
538 GL_EXTCALL(glBufferDataARB(GL_PIXEL_UNPACK_BUFFER_ARB, sizeof(pattern), pattern, GL_STREAM_DRAW_ARB));
539 checkGLcall("Specifying the PBO test pbo");
540
541 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 4, 4, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL);
542 checkGLcall("Loading the PBO test texture");
543
544 GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0));
545 wglFinish(); /* just to be sure */
546
547 memset(check, 0, sizeof(check));
548 glGetTexImage(GL_TEXTURE_2D, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, check);
549 checkGLcall("Reading back the PBO test texture");
550
551 glDeleteTextures(1, &texture);
552 GL_EXTCALL(glDeleteBuffersARB(1, &pbo));
553 checkGLcall("PBO test cleanup");
554
555 LEAVE_GL();
556
557 if (memcmp(check, pattern, sizeof(check)))
558 {
559 WARN_(d3d_caps)("PBO test failed, read back data doesn't match original.\n");
560 WARN_(d3d_caps)("Disabling PBOs. This may result in slower performance.\n");
561 gl_info->supported[ARB_PIXEL_BUFFER_OBJECT] = FALSE;
562 }
563 else
564 {
565 TRACE_(d3d_caps)("PBO test successful.\n");
566 }
567}
568
569static BOOL match_apple_intel(const struct wined3d_gl_info *gl_info, const char *gl_renderer,
570 enum wined3d_gl_vendor gl_vendor, enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device)
571{
572 return (card_vendor == HW_VENDOR_INTEL) && (gl_vendor == GL_VENDOR_APPLE);
573}
574
575static BOOL match_apple_nonr500ati(const struct wined3d_gl_info *gl_info, const char *gl_renderer,
576 enum wined3d_gl_vendor gl_vendor, enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device)
577{
578 if (gl_vendor != GL_VENDOR_APPLE) return FALSE;
579 if (card_vendor != HW_VENDOR_ATI) return FALSE;
580 if (device == CARD_ATI_RADEON_X1600) return FALSE;
581 return TRUE;
582}
583
584static BOOL match_fglrx(const struct wined3d_gl_info *gl_info, const char *gl_renderer,
585 enum wined3d_gl_vendor gl_vendor, enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device)
586{
587 return gl_vendor == GL_VENDOR_FGLRX;
588
589}
590
591static BOOL match_dx10_capable(const struct wined3d_gl_info *gl_info, const char *gl_renderer,
592 enum wined3d_gl_vendor gl_vendor, enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device)
593{
594 /* DX9 cards support 40 single float varyings in hardware, most drivers report 32. ATI misreports
595 * 44 varyings. So assume that if we have more than 44 varyings we have a dx10 card.
596 * This detection is for the gl_ClipPos varying quirk. If a d3d9 card really supports more than 44
597 * varyings and we subtract one in dx9 shaders its not going to hurt us because the dx9 limit is
598 * hardcoded
599 *
600 * dx10 cards usually have 64 varyings */
601 return gl_info->limits.glsl_varyings > 44;
602}
603
604/* A GL context is provided by the caller */
605static BOOL match_allows_spec_alpha(const struct wined3d_gl_info *gl_info, const char *gl_renderer,
606 enum wined3d_gl_vendor gl_vendor, enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device)
607{
608 GLenum error;
609 DWORD data[16];
610
611 if (!gl_info->supported[EXT_SECONDARY_COLOR]) return FALSE;
612
613 ENTER_GL();
614 while(glGetError());
615 GL_EXTCALL(glSecondaryColorPointerEXT)(4, GL_UNSIGNED_BYTE, 4, data);
616 error = glGetError();
617 LEAVE_GL();
618
619 if(error == GL_NO_ERROR)
620 {
621 TRACE("GL Implementation accepts 4 component specular color pointers\n");
622 return TRUE;
623 }
624 else
625 {
626 TRACE("GL implementation does not accept 4 component specular colors, error %s\n",
627 debug_glerror(error));
628 return FALSE;
629 }
630}
631
632static BOOL match_apple_nvts(const struct wined3d_gl_info *gl_info, const char *gl_renderer,
633 enum wined3d_gl_vendor gl_vendor, enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device)
634{
635 if (!match_apple(gl_info, gl_renderer, gl_vendor, card_vendor, device)) return FALSE;
636 return gl_info->supported[NV_TEXTURE_SHADER];
637}
638
639/* A GL context is provided by the caller */
640static BOOL match_broken_nv_clip(const struct wined3d_gl_info *gl_info, const char *gl_renderer,
641 enum wined3d_gl_vendor gl_vendor, enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device)
642{
643 GLuint prog;
644 BOOL ret = FALSE;
645 GLint pos;
646 const char *testcode =
647 "!!ARBvp1.0\n"
648 "OPTION NV_vertex_program2;\n"
649 "MOV result.clip[0], 0.0;\n"
650 "MOV result.position, 0.0;\n"
651 "END\n";
652
653 if (!gl_info->supported[NV_VERTEX_PROGRAM2_OPTION]) return FALSE;
654
655 ENTER_GL();
656 while(glGetError());
657
658 GL_EXTCALL(glGenProgramsARB(1, &prog));
659 if(!prog)
660 {
661 ERR("Failed to create the NVvp clip test program\n");
662 LEAVE_GL();
663 return FALSE;
664 }
665 GL_EXTCALL(glBindProgramARB(GL_VERTEX_PROGRAM_ARB, prog));
666 GL_EXTCALL(glProgramStringARB(GL_VERTEX_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB,
667 strlen(testcode), testcode));
668 glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB, &pos);
669 if(pos != -1)
670 {
671 WARN("GL_NV_vertex_program2_option result.clip[] test failed\n");
672 TRACE("error: %s\n", debugstr_a((const char *)glGetString(GL_PROGRAM_ERROR_STRING_ARB)));
673 ret = TRUE;
674 while(glGetError());
675 }
676 else TRACE("GL_NV_vertex_program2_option result.clip[] test passed\n");
677
678 GL_EXTCALL(glBindProgramARB(GL_VERTEX_PROGRAM_ARB, 0));
679 GL_EXTCALL(glDeleteProgramsARB(1, &prog));
680 checkGLcall("GL_NV_vertex_program2_option result.clip[] test cleanup");
681
682 LEAVE_GL();
683 return ret;
684}
685
686/* Context activation is done by the caller. */
687static BOOL match_fbo_tex_update(const struct wined3d_gl_info *gl_info, const char *gl_renderer,
688 enum wined3d_gl_vendor gl_vendor, enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device)
689{
690 char data[4 * 4 * 4];
691 GLuint tex, fbo;
692 GLenum status;
693
694 if (wined3d_settings.offscreen_rendering_mode != ORM_FBO) return FALSE;
695
696 memset(data, 0xcc, sizeof(data));
697
698 ENTER_GL();
699
700 glGenTextures(1, &tex);
701 glBindTexture(GL_TEXTURE_2D, tex);
702 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
703 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
704 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 4, 4, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL);
705 checkGLcall("glTexImage2D");
706
707 gl_info->fbo_ops.glGenFramebuffers(1, &fbo);
708 gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, fbo);
709 gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
710 checkGLcall("glFramebufferTexture2D");
711
712 status = gl_info->fbo_ops.glCheckFramebufferStatus(GL_FRAMEBUFFER);
713 if (status != GL_FRAMEBUFFER_COMPLETE) ERR("FBO status %#x\n", status);
714 checkGLcall("glCheckFramebufferStatus");
715
716 memset(data, 0x11, sizeof(data));
717 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 4, 4, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, data);
718 checkGLcall("glTexSubImage2D");
719
720 glClearColor(0.996, 0.729, 0.745, 0.792);
721 glClear(GL_COLOR_BUFFER_BIT);
722 checkGLcall("glClear");
723
724 glGetTexImage(GL_TEXTURE_2D, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, data);
725 checkGLcall("glGetTexImage");
726
727 gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
728 gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, 0);
729 glBindTexture(GL_TEXTURE_2D, 0);
730 checkGLcall("glBindTexture");
731
732 gl_info->fbo_ops.glDeleteFramebuffers(1, &fbo);
733 glDeleteTextures(1, &tex);
734 checkGLcall("glDeleteTextures");
735
736 LEAVE_GL();
737
738 return *(DWORD *)data == 0x11111111;
739}
740
741static void quirk_arb_constants(struct wined3d_gl_info *gl_info)
742{
743 TRACE_(d3d_caps)("Using ARB vs constant limit(=%u) for GLSL.\n", gl_info->limits.arb_vs_native_constants);
744 gl_info->limits.glsl_vs_float_constants = gl_info->limits.arb_vs_native_constants;
745 TRACE_(d3d_caps)("Using ARB ps constant limit(=%u) for GLSL.\n", gl_info->limits.arb_ps_native_constants);
746 gl_info->limits.glsl_ps_float_constants = gl_info->limits.arb_ps_native_constants;
747}
748
749static void quirk_apple_glsl_constants(struct wined3d_gl_info *gl_info)
750{
751 quirk_arb_constants(gl_info);
752 /* MacOS needs uniforms for relative addressing offsets. This can accumulate to quite a few uniforms.
753 * Beyond that the general uniform isn't optimal, so reserve a number of uniforms. 12 vec4's should
754 * allow 48 different offsets or other helper immediate values. */
755 TRACE_(d3d_caps)("Reserving 12 GLSL constants for compiler private use.\n");
756 gl_info->reserved_glsl_constants = max(gl_info->reserved_glsl_constants, 12);
757}
758
759/* fglrx crashes with a very bad kernel panic if GL_POINT_SPRITE_ARB is set to GL_COORD_REPLACE_ARB
760 * on more than one texture unit. This means that the d3d9 visual point size test will cause a
761 * kernel panic on any machine running fglrx 9.3(latest that supports r300 to r500 cards). This
762 * quirk only enables point sprites on the first texture unit. This keeps point sprites working in
763 * most games, but avoids the crash
764 *
765 * A more sophisticated way would be to find all units that need texture coordinates and enable
766 * point sprites for one if only one is found, and software emulate point sprites in drawStridedSlow
767 * if more than one unit needs texture coordinates(This requires software ffp and vertex shaders though)
768 *
769 * Note that disabling the extension entirely does not gain predictability because there is no point
770 * sprite capability flag in d3d, so the potential rendering bugs are the same if we disable the extension. */
771static void quirk_one_point_sprite(struct wined3d_gl_info *gl_info)
772{
773 if (gl_info->supported[ARB_POINT_SPRITE])
774 {
775 TRACE("Limiting point sprites to one texture unit.\n");
776 gl_info->limits.point_sprite_units = 1;
777 }
778}
779
780static void quirk_ati_dx9(struct wined3d_gl_info *gl_info)
781{
782 quirk_arb_constants(gl_info);
783
784 /* MacOS advertises GL_ARB_texture_non_power_of_two on ATI r500 and earlier cards, although
785 * these cards only support GL_ARB_texture_rectangle(D3DPTEXTURECAPS_NONPOW2CONDITIONAL).
786 * If real NP2 textures are used, the driver falls back to software. We could just remove the
787 * extension and use GL_ARB_texture_rectangle instead, but texture_rectangle is inconventient
788 * due to the non-normalized texture coordinates. Thus set an internal extension flag,
789 * GL_WINE_normalized_texrect, which signals the code that it can use non power of two textures
790 * as per GL_ARB_texture_non_power_of_two, but has to stick to the texture_rectangle limits.
791 *
792 * fglrx doesn't advertise GL_ARB_texture_non_power_of_two, but it advertises opengl 2.0 which
793 * has this extension promoted to core. The extension loading code sets this extension supported
794 * due to that, so this code works on fglrx as well. */
795 if(gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO])
796 {
797 TRACE("GL_ARB_texture_non_power_of_two advertised on R500 or earlier card, removing.\n");
798 gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO] = FALSE;
799 gl_info->supported[WINE_NORMALIZED_TEXRECT] = TRUE;
800 }
801
802 /* fglrx has the same structural issues as the one described in quirk_apple_glsl_constants, although
803 * it is generally more efficient. Reserve just 8 constants. */
804 TRACE_(d3d_caps)("Reserving 8 GLSL constants for compiler private use.\n");
805 gl_info->reserved_glsl_constants = max(gl_info->reserved_glsl_constants, 8);
806}
807
808static void quirk_no_np2(struct wined3d_gl_info *gl_info)
809{
810 /* The nVidia GeForceFX series reports OpenGL 2.0 capabilities with the latest drivers versions, but
811 * doesn't explicitly advertise the ARB_tex_npot extension in the GL extension string.
812 * This usually means that ARB_tex_npot is supported in hardware as long as the application is staying
813 * within the limits enforced by the ARB_texture_rectangle extension. This however is not true for the
814 * FX series, which instantly falls back to a slower software path as soon as ARB_tex_npot is used.
815 * We therefore completely remove ARB_tex_npot from the list of supported extensions.
816 *
817 * Note that wine_normalized_texrect can't be used in this case because internally it uses ARB_tex_npot,
818 * triggering the software fallback. There is not much we can do here apart from disabling the
819 * software-emulated extension and reenable ARB_tex_rect (which was previously disabled
820 * in IWineD3DImpl_FillGLCaps).
821 * This fixup removes performance problems on both the FX 5900 and FX 5700 (e.g. for framebuffer
822 * post-processing effects in the game "Max Payne 2").
823 * The behaviour can be verified through a simple test app attached in bugreport #14724. */
824 TRACE("GL_ARB_texture_non_power_of_two advertised through OpenGL 2.0 on NV FX card, removing.\n");
825 gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO] = FALSE;
826 gl_info->supported[ARB_TEXTURE_RECTANGLE] = TRUE;
827}
828
829static void quirk_texcoord_w(struct wined3d_gl_info *gl_info)
830{
831 /* The Intel GPUs on MacOS set the .w register of texcoords to 0.0 by default, which causes problems
832 * with fixed function fragment processing. Ideally this flag should be detected with a test shader
833 * and OpenGL feedback mode, but some GL implementations (MacOS ATI at least, probably all MacOS ones)
834 * do not like vertex shaders in feedback mode and return an error, even though it should be valid
835 * according to the spec.
836 *
837 * We don't want to enable this on all cards, as it adds an extra instruction per texcoord used. This
838 * makes the shader slower and eats instruction slots which should be available to the d3d app.
839 *
840 * ATI Radeon HD 2xxx cards on MacOS have the issue. Instead of checking for the buggy cards, blacklist
841 * all radeon cards on Macs and whitelist the good ones. That way we're prepared for the future. If
842 * this workaround is activated on cards that do not need it, it won't break things, just affect
843 * performance negatively. */
844 TRACE("Enabling vertex texture coord fixes in vertex shaders.\n");
845 gl_info->quirks |= WINED3D_QUIRK_SET_TEXCOORD_W;
846}
847
848static void quirk_clip_varying(struct wined3d_gl_info *gl_info)
849{
850 gl_info->quirks |= WINED3D_QUIRK_GLSL_CLIP_VARYING;
851}
852
853static void quirk_allows_specular_alpha(struct wined3d_gl_info *gl_info)
854{
855 gl_info->quirks |= WINED3D_QUIRK_ALLOWS_SPECULAR_ALPHA;
856}
857
858static void quirk_apple_nvts(struct wined3d_gl_info *gl_info)
859{
860 gl_info->supported[NV_TEXTURE_SHADER] = FALSE;
861 gl_info->supported[NV_TEXTURE_SHADER2] = FALSE;
862}
863
864static void quirk_disable_nvvp_clip(struct wined3d_gl_info *gl_info)
865{
866 gl_info->quirks |= WINED3D_QUIRK_NV_CLIP_BROKEN;
867}
868
869static void quirk_fbo_tex_update(struct wined3d_gl_info *gl_info)
870{
871 gl_info->quirks |= WINED3D_QUIRK_FBO_TEX_UPDATE;
872}
873
874static BOOL match_ati_hd4800(const struct wined3d_gl_info *gl_info, const char *gl_renderer,
875 enum wined3d_gl_vendor gl_vendor, enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device)
876{
877 if (card_vendor != HW_VENDOR_ATI) return FALSE;
878 if (device == CARD_ATI_RADEON_HD4800) return TRUE;
879 return FALSE;
880}
881
882static void quirk_fullsize_blit(struct wined3d_gl_info *gl_info)
883{
884 gl_info->quirks |= WINED3D_QUIRK_FULLSIZE_BLIT;
885}
886
887#ifdef VBOX_WITH_WDDM
888static BOOL match_mesa_nvidia(const struct wined3d_gl_info *gl_info, const char *gl_renderer,
889 enum wined3d_gl_vendor gl_vendor, enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device)
890{
891 if (card_vendor != HW_VENDOR_NVIDIA) return FALSE;
892 if (gl_vendor != GL_VENDOR_MESA) return FALSE;
893 return TRUE;
894}
895
896static void quirk_no_shader_3(struct wined3d_gl_info *gl_info)
897{
898 int vs_selected_mode, ps_selected_mode;
899 select_shader_mode(gl_info, &ps_selected_mode, &vs_selected_mode);
900 if (vs_selected_mode != SHADER_GLSL && ps_selected_mode != SHADER_GLSL)
901 return;
902
903 gl_info->limits.arb_ps_instructions = 512;
904}
905#endif
906
907struct driver_quirk
908{
909 BOOL (*match)(const struct wined3d_gl_info *gl_info, const char *gl_renderer,
910 enum wined3d_gl_vendor gl_vendor, enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device);
911 void (*apply)(struct wined3d_gl_info *gl_info);
912 const char *description;
913};
914
915static const struct driver_quirk quirk_table[] =
916{
917 {
918 match_ati_r300_to_500,
919 quirk_ati_dx9,
920 "ATI GLSL constant and normalized texrect quirk"
921 },
922 /* MacOS advertises more GLSL vertex shader uniforms than supported by the hardware, and if more are
923 * used it falls back to software. While the compiler can detect if the shader uses all declared
924 * uniforms, the optimization fails if the shader uses relative addressing. So any GLSL shader
925 * using relative addressing falls back to software.
926 *
927 * ARB vp gives the correct amount of uniforms, so use it instead of GLSL. */
928 {
929 match_apple,
930 quirk_apple_glsl_constants,
931 "Apple GLSL uniform override"
932 },
933 {
934 match_geforce5,
935 quirk_no_np2,
936 "Geforce 5 NP2 disable"
937 },
938 {
939 match_apple_intel,
940 quirk_texcoord_w,
941 "Init texcoord .w for Apple Intel GPU driver"
942 },
943 {
944 match_apple_nonr500ati,
945 quirk_texcoord_w,
946 "Init texcoord .w for Apple ATI >= r600 GPU driver"
947 },
948 {
949 match_fglrx,
950 quirk_one_point_sprite,
951 "Fglrx point sprite crash workaround"
952 },
953 {
954 match_dx10_capable,
955 quirk_clip_varying,
956 "Reserved varying for gl_ClipPos"
957 },
958 {
959 /* GL_EXT_secondary_color does not allow 4 component secondary colors, but most
960 * GL implementations accept it. The Mac GL is the only implementation known to
961 * reject it.
962 *
963 * If we can pass 4 component specular colors, do it, because (a) we don't have
964 * to screw around with the data, and (b) the D3D fixed function vertex pipeline
965 * passes specular alpha to the pixel shader if any is used. Otherwise the
966 * specular alpha is used to pass the fog coordinate, which we pass to opengl
967 * via GL_EXT_fog_coord.
968 */
969 match_allows_spec_alpha,
970 quirk_allows_specular_alpha,
971 "Allow specular alpha quirk"
972 },
973 {
974 /* The pixel formats provided by GL_NV_texture_shader are broken on OSX
975 * (rdar://5682521).
976 */
977 match_apple_nvts,
978 quirk_apple_nvts,
979 "Apple NV_texture_shader disable"
980 },
981 {
982 match_broken_nv_clip,
983 quirk_disable_nvvp_clip,
984 "Apple NV_vertex_program clip bug quirk"
985 },
986 {
987 match_fbo_tex_update,
988 quirk_fbo_tex_update,
989 "FBO rebind for attachment updates"
990 },
991 {
992 match_ati_hd4800,
993 quirk_fullsize_blit,
994 "Fullsize blit"
995 },
996#ifdef VBOX_WITH_WDDM
997 {
998 match_mesa_nvidia,
999 quirk_no_shader_3,
1000 "disable shader 3 support"
1001 },
1002#endif
1003};
1004
1005/* Certain applications (Steam) complain if we report an outdated driver version. In general,
1006 * reporting a driver version is moot because we are not the Windows driver, and we have different
1007 * bugs, features, etc.
1008 *
1009 * The driver version has the form "x.y.z.w".
1010 *
1011 * "x" is the Windows version the driver is meant for:
1012 * 4 -> 95/98/NT4
1013 * 5 -> 2000
1014 * 6 -> 2000/XP
1015 * 7 -> Vista
1016 * 8 -> Win 7
1017 *
1018 * "y" is the Direct3D level the driver supports:
1019 * 11 -> d3d6
1020 * 12 -> d3d7
1021 * 13 -> d3d8
1022 * 14 -> d3d9
1023 * 15 -> d3d10
1024 *
1025 * "z" is unknown, possibly vendor specific.
1026 *
1027 * "w" is the vendor specific driver version.
1028 */
1029struct driver_version_information
1030{
1031 WORD vendor; /* reported PCI card vendor ID */
1032 WORD card; /* reported PCI card device ID */
1033 const char *description; /* Description of the card e.g. NVIDIA RIVA TNT */
1034 WORD d3d_level; /* driver hiword to report */
1035 WORD lopart_hi, lopart_lo; /* driver loword to report */
1036};
1037
1038static const struct driver_version_information driver_version_table[] =
1039{
1040 /* Nvidia drivers. Geforce6 and newer cards are supported by the current driver (180.x)
1041 * 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
1042 * Geforce2MX/3/4 up to 96.x - driver uses numbering 9.6.8.9 for 96.89
1043 * TNT/Geforce1/2 up to 71.x - driver uses numbering 7.1.8.6 for 71.86
1044 *
1045 * All version numbers used below are from the Linux nvidia drivers. */
1046 {HW_VENDOR_NVIDIA, CARD_NVIDIA_RIVA_TNT, "NVIDIA RIVA TNT", 1, 8, 6 },
1047 {HW_VENDOR_NVIDIA, CARD_NVIDIA_RIVA_TNT2, "NVIDIA RIVA TNT2/TNT2 Pro", 1, 8, 6 },
1048 {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE, "NVIDIA GeForce 256", 1, 8, 6 },
1049 {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE2_MX, "NVIDIA GeForce2 MX/MX 400", 6, 4, 3 },
1050 {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE2, "NVIDIA GeForce2 GTS/GeForce2 Pro", 1, 8, 6 },
1051 {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE3, "NVIDIA GeForce3", 6, 10, 9371 },
1052 {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE4_MX, "NVIDIA GeForce4 MX 460", 6, 10, 9371 },
1053 {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE4_TI4200, "NVIDIA GeForce4 Ti 4200", 6, 10, 9371 },
1054 {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCEFX_5200, "NVIDIA GeForce FX 5200", 15, 11, 7516 },
1055 {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCEFX_5600, "NVIDIA GeForce FX 5600", 15, 11, 7516 },
1056 {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCEFX_5800, "NVIDIA GeForce FX 5800", 15, 11, 7516 },
1057 {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_6200, "NVIDIA GeForce 6200", 15, 11, 8618 },
1058 {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_6600GT, "NVIDIA GeForce 6600 GT", 15, 11, 8618 },
1059 {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_6800, "NVIDIA GeForce 6800", 15, 11, 8618 },
1060 {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_7300, "NVIDIA GeForce Go 7300", 15, 11, 8585 },
1061 {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_7400, "NVIDIA GeForce Go 7400", 15, 11, 8585 },
1062 {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_7600, "NVIDIA GeForce 7600 GT", 15, 11, 8618 },
1063 {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_7800GT, "NVIDIA GeForce 7800 GT", 15, 11, 8618 },
1064 {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_8300GS, "NVIDIA GeForce 8300 GS", 15, 11, 8618 },
1065 {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_8600GT, "NVIDIA GeForce 8600 GT", 15, 11, 8618 },
1066 {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_8600MGT, "NVIDIA GeForce 8600M GT", 15, 11, 8585 },
1067 {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_8800GTS, "NVIDIA GeForce 8800 GTS", 15, 11, 8618 },
1068 {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_9200, "NVIDIA GeForce 9200", 15, 11, 8618 },
1069 {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_9400GT, "NVIDIA GeForce 9400 GT", 15, 11, 8618 },
1070 {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_9500GT, "NVIDIA GeForce 9500 GT", 15, 11, 8618 },
1071 {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_9600GT, "NVIDIA GeForce 9600 GT", 15, 11, 8618 },
1072 {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_9800GT, "NVIDIA GeForce 9800 GT", 15, 11, 8618 },
1073 {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX260, "NVIDIA GeForce GTX 260", 15, 11, 8618 },
1074 {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX275, "NVIDIA GeForce GTX 275", 15, 11, 8618 },
1075 {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX280, "NVIDIA GeForce GTX 280", 15, 11, 8618 },
1076 {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GT240, "NVIDIA GeForce GT 240", 15, 11, 8618 },
1077
1078 /* ATI cards. The driver versions are somewhat similar, but not quite the same. Let's hardcode. */
1079 {HW_VENDOR_ATI, CARD_ATI_RADEON_9500, "ATI Radeon 9500", 14, 10, 6764 },
1080 {HW_VENDOR_ATI, CARD_ATI_RADEON_X700, "ATI Radeon X700 SE", 14, 10, 6764 },
1081 {HW_VENDOR_ATI, CARD_ATI_RADEON_X1600, "ATI Radeon X1600 Series", 14, 10, 6764 },
1082 {HW_VENDOR_ATI, CARD_ATI_RADEON_HD2350, "ATI Mobility Radeon HD 2350", 14, 10, 6764 },
1083 {HW_VENDOR_ATI, CARD_ATI_RADEON_HD2600, "ATI Mobility Radeon HD 2600", 14, 10, 6764 },
1084 {HW_VENDOR_ATI, CARD_ATI_RADEON_HD2900, "ATI Radeon HD 2900 XT", 14, 10, 6764 },
1085 {HW_VENDOR_ATI, CARD_ATI_RADEON_HD4350, "ATI Radeon HD 4350", 14, 10, 6764 },
1086 {HW_VENDOR_ATI, CARD_ATI_RADEON_HD4600, "ATI Radeon HD 4600 Series", 14, 10, 6764 },
1087 {HW_VENDOR_ATI, CARD_ATI_RADEON_HD4700, "ATI Radeon HD 4700 Series", 14, 10, 6764 },
1088 {HW_VENDOR_ATI, CARD_ATI_RADEON_HD4800, "ATI Radeon HD 4800 Series", 14, 10, 6764 },
1089 {HW_VENDOR_ATI, CARD_ATI_RADEON_HD5700, "ATI Radeon HD 5700 Series", 14, 10, 8681 },
1090 {HW_VENDOR_ATI, CARD_ATI_RADEON_HD5800, "ATI Radeon HD 5800 Series", 14, 10, 8681 },
1091
1092 /* TODO: Add information about legacy ATI hardware, Intel and other cards. */
1093};
1094
1095static void init_driver_info(struct wined3d_driver_info *driver_info,
1096 enum wined3d_pci_vendor vendor, enum wined3d_pci_device device)
1097{
1098 OSVERSIONINFOW os_version;
1099 WORD driver_os_version;
1100 unsigned int i;
1101
1102 if (wined3d_settings.pci_vendor_id != PCI_VENDOR_NONE)
1103 {
1104 TRACE_(d3d_caps)("Overriding PCI vendor ID with: %04x\n", wined3d_settings.pci_vendor_id);
1105 vendor = wined3d_settings.pci_vendor_id;
1106 }
1107 driver_info->vendor = vendor;
1108
1109 if (wined3d_settings.pci_device_id != PCI_DEVICE_NONE)
1110 {
1111 TRACE_(d3d_caps)("Overriding PCI device ID with: %04x\n", wined3d_settings.pci_device_id);
1112 device = wined3d_settings.pci_device_id;
1113 }
1114 driver_info->device = device;
1115
1116 switch (vendor)
1117 {
1118 case HW_VENDOR_ATI:
1119 driver_info->name = "ati2dvag.dll";
1120 break;
1121
1122 case HW_VENDOR_NVIDIA:
1123 driver_info->name = "nv4_disp.dll";
1124 break;
1125
1126 case HW_VENDOR_INTEL:
1127 default:
1128 FIXME_(d3d_caps)("Unhandled vendor %04x.\n", vendor);
1129 driver_info->name = "Display";
1130 break;
1131 }
1132
1133 memset(&os_version, 0, sizeof(os_version));
1134 os_version.dwOSVersionInfoSize = sizeof(os_version);
1135 if (!GetVersionExW(&os_version))
1136 {
1137 ERR("Failed to get OS version, reporting 2000/XP.\n");
1138 driver_os_version = 6;
1139 }
1140 else
1141 {
1142 TRACE("OS version %u.%u.\n", os_version.dwMajorVersion, os_version.dwMinorVersion);
1143 switch (os_version.dwMajorVersion)
1144 {
1145 case 4:
1146 driver_os_version = 4;
1147 break;
1148
1149 case 5:
1150 driver_os_version = 6;
1151 break;
1152
1153 case 6:
1154 if (os_version.dwMinorVersion == 0)
1155 {
1156 driver_os_version = 7;
1157 }
1158 else
1159 {
1160 if (os_version.dwMinorVersion > 1)
1161 {
1162 FIXME("Unhandled OS version %u.%u, reporting Win 7.\n",
1163 os_version.dwMajorVersion, os_version.dwMinorVersion);
1164 }
1165 driver_os_version = 8;
1166 }
1167 break;
1168
1169 default:
1170 FIXME("Unhandled OS version %u.%u, reporting 2000/XP.\n",
1171 os_version.dwMajorVersion, os_version.dwMinorVersion);
1172 driver_os_version = 6;
1173 break;
1174 }
1175 }
1176
1177 driver_info->description = "Direct3D HAL";
1178 driver_info->version_high = MAKEDWORD_VERSION(driver_os_version, 15);
1179 driver_info->version_low = MAKEDWORD_VERSION(8, 6); /* Nvidia RIVA TNT, arbitrary */
1180
1181 for (i = 0; i < (sizeof(driver_version_table) / sizeof(driver_version_table[0])); ++i)
1182 {
1183 if (vendor == driver_version_table[i].vendor && device == driver_version_table[i].card)
1184 {
1185 TRACE_(d3d_caps)("Found card %04x:%04x in driver DB.\n", vendor, device);
1186
1187 driver_info->description = driver_version_table[i].description;
1188 driver_info->version_high = MAKEDWORD_VERSION(driver_os_version, driver_version_table[i].d3d_level);
1189 driver_info->version_low = MAKEDWORD_VERSION(driver_version_table[i].lopart_hi,
1190 driver_version_table[i].lopart_lo);
1191 break;
1192 }
1193 }
1194
1195 TRACE_(d3d_caps)("Reporting (fake) driver version 0x%08x-0x%08x.\n",
1196 driver_info->version_high, driver_info->version_low);
1197}
1198
1199/* Context activation is done by the caller. */
1200static void fixup_extensions(struct wined3d_gl_info *gl_info, const char *gl_renderer,
1201 enum wined3d_gl_vendor gl_vendor, enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device)
1202{
1203 unsigned int i;
1204
1205 for (i = 0; i < (sizeof(quirk_table) / sizeof(*quirk_table)); ++i)
1206 {
1207 if (!quirk_table[i].match(gl_info, gl_renderer, gl_vendor, card_vendor, device)) continue;
1208 TRACE_(d3d_caps)("Applying driver quirk \"%s\".\n", quirk_table[i].description);
1209 quirk_table[i].apply(gl_info);
1210 }
1211
1212 /* Find out if PBOs work as they are supposed to. */
1213 test_pbo_functionality(gl_info);
1214}
1215
1216static DWORD wined3d_parse_gl_version(const char *gl_version)
1217{
1218 const char *ptr = gl_version;
1219 int major, minor;
1220
1221 major = atoi(ptr);
1222 if (major <= 0) ERR_(d3d_caps)("Invalid opengl major version: %d.\n", major);
1223
1224 while (isdigit(*ptr)) ++ptr;
1225 if (*ptr++ != '.') ERR_(d3d_caps)("Invalid opengl version string: %s.\n", debugstr_a(gl_version));
1226
1227 minor = atoi(ptr);
1228
1229 TRACE_(d3d_caps)("Found OpenGL version: %d.%d.\n", major, minor);
1230
1231 return MAKEDWORD_VERSION(major, minor);
1232}
1233
1234static enum wined3d_gl_vendor wined3d_guess_gl_vendor(struct wined3d_gl_info *gl_info, const char *gl_vendor_string, const char *gl_renderer)
1235{
1236
1237 /* MacOS has various specialities in the extensions it advertises. Some have to be loaded from
1238 * the opengl 1.2+ core, while other extensions are advertised, but software emulated. So try to
1239 * detect the Apple OpenGL implementation to apply some extension fixups afterwards.
1240 *
1241 * Detecting this isn't really easy. The vendor string doesn't mention Apple. Compile-time checks
1242 * aren't sufficient either because a Linux binary may display on a macos X server via remote X11.
1243 * So try to detect the GL implementation by looking at certain Apple extensions. Some extensions
1244 * like client storage might be supported on other implementations too, but GL_APPLE_flush_render
1245 * is specific to the Mac OS X window management, and GL_APPLE_ycbcr_422 is QuickTime specific. So
1246 * the chance that other implementations support them is rather small since Win32 QuickTime uses
1247 * DirectDraw, not OpenGL. */
1248 if (gl_info->supported[APPLE_FENCE]
1249 && gl_info->supported[APPLE_CLIENT_STORAGE]
1250 && gl_info->supported[APPLE_FLUSH_RENDER]
1251 && gl_info->supported[APPLE_YCBCR_422])
1252 return GL_VENDOR_APPLE;
1253
1254 if (strstr(gl_vendor_string, "NVIDIA"))
1255 return GL_VENDOR_NVIDIA;
1256
1257 if (strstr(gl_vendor_string, "ATI"))
1258 return GL_VENDOR_FGLRX;
1259
1260 if (strstr(gl_vendor_string, "Intel(R)")
1261 || strstr(gl_renderer, "Intel(R)")
1262 || strstr(gl_vendor_string, "Intel Inc."))
1263 return GL_VENDOR_INTEL;
1264
1265 if (strstr(gl_vendor_string, "Mesa")
1266 || strstr(gl_vendor_string, "Advanced Micro Devices, Inc.")
1267 || strstr(gl_vendor_string, "DRI R300 Project")
1268 || strstr(gl_vendor_string, "X.Org R300 Project")
1269 || strstr(gl_vendor_string, "Tungsten Graphics, Inc")
1270 || strstr(gl_vendor_string, "VMware, Inc.")
1271 || strstr(gl_renderer, "Mesa")
1272 || strstr(gl_renderer, "Gallium"))
1273 return GL_VENDOR_MESA;
1274
1275 FIXME_(d3d_caps)("Received unrecognized GL_VENDOR %s. Returning GL_VENDOR_UNKNOWN.\n",
1276 debugstr_a(gl_vendor_string));
1277
1278 return GL_VENDOR_UNKNOWN;
1279}
1280
1281static enum wined3d_pci_vendor wined3d_guess_card_vendor(const char *gl_vendor_string, const char *gl_renderer)
1282{
1283 if (strstr(gl_vendor_string, "NVIDIA"))
1284 return HW_VENDOR_NVIDIA;
1285
1286 if (strstr(gl_vendor_string, "ATI")
1287 || strstr(gl_vendor_string, "Advanced Micro Devices, Inc.")
1288 || strstr(gl_vendor_string, "X.Org R300 Project")
1289 || strstr(gl_vendor_string, "DRI R300 Project"))
1290 return HW_VENDOR_ATI;
1291
1292 if (strstr(gl_vendor_string, "Intel(R)")
1293 || strstr(gl_renderer, "Intel(R)")
1294 || strstr(gl_vendor_string, "Intel Inc."))
1295 return HW_VENDOR_INTEL;
1296
1297 if (strstr(gl_vendor_string, "Mesa")
1298 || strstr(gl_vendor_string, "Tungsten Graphics, Inc")
1299 || strstr(gl_vendor_string, "VMware, Inc."))
1300 return HW_VENDOR_SOFTWARE;
1301
1302 FIXME_(d3d_caps)("Received unrecognized GL_VENDOR %s. Returning HW_VENDOR_NVIDIA.\n", debugstr_a(gl_vendor_string));
1303
1304 return HW_VENDOR_NVIDIA;
1305}
1306
1307
1308
1309static enum wined3d_pci_device select_card_nvidia_binary(const struct wined3d_gl_info *gl_info,
1310 const char *gl_renderer, unsigned int *vidmem)
1311{
1312#ifndef VBOX_WITH_WDDM
1313 if (WINE_D3D10_CAPABLE(gl_info))
1314#endif
1315 {
1316 /* Geforce 200 - highend */
1317 if (strstr(gl_renderer, "GTX 280")
1318 || strstr(gl_renderer, "GTX 285")
1319 || strstr(gl_renderer, "GTX 295"))
1320 {
1321 *vidmem = 1024;
1322 return CARD_NVIDIA_GEFORCE_GTX280;
1323 }
1324
1325 /* Geforce 200 - midend high */
1326 if (strstr(gl_renderer, "GTX 275"))
1327 {
1328 *vidmem = 896;
1329 return CARD_NVIDIA_GEFORCE_GTX275;
1330 }
1331
1332 /* Geforce 200 - midend */
1333 if (strstr(gl_renderer, "GTX 260"))
1334 {
1335 *vidmem = 1024;
1336 return CARD_NVIDIA_GEFORCE_GTX260;
1337 }
1338 /* Geforce 200 - midend */
1339 if (strstr(gl_renderer, "GT 240"))
1340 {
1341 *vidmem = 512;
1342 return CARD_NVIDIA_GEFORCE_GT240;
1343 }
1344
1345 /* Geforce9 - highend / Geforce 200 - midend (GTS 150/250 are based on the same core) */
1346 if (strstr(gl_renderer, "9800")
1347 || strstr(gl_renderer, "GTS 150")
1348 || strstr(gl_renderer, "GTS 250"))
1349 {
1350 *vidmem = 512;
1351 return CARD_NVIDIA_GEFORCE_9800GT;
1352 }
1353
1354 /* Geforce9 - midend */
1355 if (strstr(gl_renderer, "9600"))
1356 {
1357 *vidmem = 384; /* The 9600GSO has 384MB, the 9600GT has 512-1024MB */
1358 return CARD_NVIDIA_GEFORCE_9600GT;
1359 }
1360
1361 /* Geforce9 - midend low / Geforce 200 - low */
1362 if (strstr(gl_renderer, "9500")
1363 || strstr(gl_renderer, "GT 120")
1364 || strstr(gl_renderer, "GT 130"))
1365 {
1366 *vidmem = 256; /* The 9500GT has 256-1024MB */
1367 return CARD_NVIDIA_GEFORCE_9500GT;
1368 }
1369
1370 /* Geforce9 - lowend */
1371 if (strstr(gl_renderer, "9400"))
1372 {
1373 *vidmem = 256; /* The 9400GT has 256-1024MB */
1374 return CARD_NVIDIA_GEFORCE_9400GT;
1375 }
1376
1377 /* Geforce9 - lowend low */
1378 if (strstr(gl_renderer, "9100")
1379 || strstr(gl_renderer, "9200")
1380 || strstr(gl_renderer, "9300")
1381 || strstr(gl_renderer, "G 100"))
1382 {
1383 *vidmem = 256; /* The 9100-9300 cards have 256MB */
1384 return CARD_NVIDIA_GEFORCE_9200;
1385 }
1386
1387 /* Geforce8 - highend */
1388 if (strstr(gl_renderer, "8800"))
1389 {
1390 *vidmem = 320; /* The 8800GTS uses 320MB, a 8800GTX can have 768MB */
1391 return CARD_NVIDIA_GEFORCE_8800GTS;
1392 }
1393
1394 /* Geforce8 - midend mobile */
1395 if (strstr(gl_renderer, "8600 M"))
1396 {
1397 *vidmem = 512;
1398 return CARD_NVIDIA_GEFORCE_8600MGT;
1399 }
1400
1401 /* Geforce8 - midend */
1402 if (strstr(gl_renderer, "8600")
1403 || strstr(gl_renderer, "8700"))
1404 {
1405 *vidmem = 256;
1406 return CARD_NVIDIA_GEFORCE_8600GT;
1407 }
1408
1409 /* Geforce8 - lowend */
1410 if (strstr(gl_renderer, "8100")
1411 || strstr(gl_renderer, "8200")
1412 || strstr(gl_renderer, "8300")
1413 || strstr(gl_renderer, "8400")
1414 || strstr(gl_renderer, "8500"))
1415 {
1416 *vidmem = 128; /* 128-256MB for a 8300, 256-512MB for a 8400 */
1417 return CARD_NVIDIA_GEFORCE_8300GS;
1418 }
1419
1420 /* Geforce8-compatible fall back if the GPU is not in the list yet */
1421 *vidmem = 128;
1422 return CARD_NVIDIA_GEFORCE_8300GS;
1423 }
1424
1425 /* Both the GeforceFX, 6xxx and 7xxx series support D3D9. The last two types have more
1426 * shader capabilities, so we use the shader capabilities to distinguish between FX and 6xxx/7xxx.
1427 */
1428 if (WINE_D3D9_CAPABLE(gl_info) && gl_info->supported[NV_VERTEX_PROGRAM3])
1429 {
1430 /* Geforce7 - highend */
1431 if (strstr(gl_renderer, "7800")
1432 || strstr(gl_renderer, "7900")
1433 || strstr(gl_renderer, "7950")
1434 || strstr(gl_renderer, "Quadro FX 4")
1435 || strstr(gl_renderer, "Quadro FX 5"))
1436 {
1437 *vidmem = 256; /* A 7800GT uses 256MB while highend 7900 cards can use 512MB */
1438 return CARD_NVIDIA_GEFORCE_7800GT;
1439 }
1440
1441 /* Geforce7 midend */
1442 if (strstr(gl_renderer, "7600")
1443 || strstr(gl_renderer, "7700"))
1444 {
1445 *vidmem = 256; /* The 7600 uses 256-512MB */
1446 return CARD_NVIDIA_GEFORCE_7600;
1447 }
1448
1449 /* Geforce7 lower medium */
1450 if (strstr(gl_renderer, "7400"))
1451 {
1452 *vidmem = 256; /* The 7400 uses 256-512MB */
1453 return CARD_NVIDIA_GEFORCE_7400;
1454 }
1455
1456 /* Geforce7 lowend */
1457 if (strstr(gl_renderer, "7300"))
1458 {
1459 *vidmem = 256; /* Mac Pros with this card have 256 MB */
1460 return CARD_NVIDIA_GEFORCE_7300;
1461 }
1462
1463 /* Geforce6 highend */
1464 if (strstr(gl_renderer, "6800"))
1465 {
1466 *vidmem = 128; /* The 6800 uses 128-256MB, the 7600 uses 256-512MB */
1467 return CARD_NVIDIA_GEFORCE_6800;
1468 }
1469
1470 /* Geforce6 - midend */
1471 if (strstr(gl_renderer, "6600")
1472 || strstr(gl_renderer, "6610")
1473 || strstr(gl_renderer, "6700"))
1474 {
1475 *vidmem = 128; /* A 6600GT has 128-256MB */
1476 return CARD_NVIDIA_GEFORCE_6600GT;
1477 }
1478
1479 /* Geforce6/7 lowend */
1480 *vidmem = 64; /* */
1481 return CARD_NVIDIA_GEFORCE_6200; /* Geforce 6100/6150/6200/7300/7400/7500 */
1482 }
1483
1484 if (WINE_D3D9_CAPABLE(gl_info))
1485 {
1486 /* GeforceFX - highend */
1487 if (strstr(gl_renderer, "5800")
1488 || strstr(gl_renderer, "5900")
1489 || strstr(gl_renderer, "5950")
1490 || strstr(gl_renderer, "Quadro FX"))
1491 {
1492 *vidmem = 256; /* 5800-5900 cards use 256MB */
1493 return CARD_NVIDIA_GEFORCEFX_5800;
1494 }
1495
1496 /* GeforceFX - midend */
1497 if (strstr(gl_renderer, "5600")
1498 || strstr(gl_renderer, "5650")
1499 || strstr(gl_renderer, "5700")
1500 || strstr(gl_renderer, "5750"))
1501 {
1502 *vidmem = 128; /* A 5600 uses 128-256MB */
1503 return CARD_NVIDIA_GEFORCEFX_5600;
1504 }
1505
1506 /* GeforceFX - lowend */
1507 *vidmem = 64; /* Normal FX5200 cards use 64-256MB; laptop (non-standard) can have less */
1508 return CARD_NVIDIA_GEFORCEFX_5200; /* GeforceFX 5100/5200/5250/5300/5500 */
1509 }
1510
1511 if (WINE_D3D8_CAPABLE(gl_info))
1512 {
1513 if (strstr(gl_renderer, "GeForce4 Ti") || strstr(gl_renderer, "Quadro4"))
1514 {
1515 *vidmem = 64; /* Geforce4 Ti cards have 64-128MB */
1516 return CARD_NVIDIA_GEFORCE4_TI4200; /* Geforce4 Ti4200/Ti4400/Ti4600/Ti4800, Quadro4 */
1517 }
1518
1519 *vidmem = 64; /* Geforce3 cards have 64-128MB */
1520 return CARD_NVIDIA_GEFORCE3; /* Geforce3 standard/Ti200/Ti500, Quadro DCC */
1521 }
1522
1523 if (WINE_D3D7_CAPABLE(gl_info))
1524 {
1525 if (strstr(gl_renderer, "GeForce4 MX"))
1526 {
1527 /* Most Geforce4MX GPUs have at least 64MB of memory, some
1528 * early models had 32MB but most have 64MB or even 128MB. */
1529 *vidmem = 64;
1530 return CARD_NVIDIA_GEFORCE4_MX; /* MX420/MX440/MX460/MX4000 */
1531 }
1532
1533 if (strstr(gl_renderer, "GeForce2 MX") || strstr(gl_renderer, "Quadro2 MXR"))
1534 {
1535 *vidmem = 32; /* Geforce2MX GPUs have 32-64MB of video memory */
1536 return CARD_NVIDIA_GEFORCE2_MX; /* Geforce2 standard/MX100/MX200/MX400, Quadro2 MXR */
1537 }
1538
1539 if (strstr(gl_renderer, "GeForce2") || strstr(gl_renderer, "Quadro2"))
1540 {
1541 *vidmem = 32; /* Geforce2 GPUs have 32-64MB of video memory */
1542 return CARD_NVIDIA_GEFORCE2; /* Geforce2 GTS/Pro/Ti/Ultra, Quadro2 */
1543 }
1544
1545 /* Most Geforce1 cards have 32MB, there are also some rare 16
1546 * and 64MB (Dell) models. */
1547 *vidmem = 32;
1548 return CARD_NVIDIA_GEFORCE; /* Geforce 256/DDR, Quadro */
1549 }
1550
1551 if (strstr(gl_renderer, "TNT2"))
1552 {
1553 *vidmem = 32; /* Most TNT2 boards have 32MB, though there are 16MB boards too */
1554 return CARD_NVIDIA_RIVA_TNT2; /* Riva TNT2 standard/M64/Pro/Ultra */
1555 }
1556
1557 *vidmem = 16; /* Most TNT boards have 16MB, some rare models have 8MB */
1558 return CARD_NVIDIA_RIVA_TNT; /* Riva TNT, Vanta */
1559
1560}
1561
1562static enum wined3d_pci_device select_card_ati_binary(const struct wined3d_gl_info *gl_info,
1563 const char *gl_renderer, unsigned int *vidmem)
1564{
1565 /* See http://developer.amd.com/drivers/pc_vendor_id/Pages/default.aspx
1566 *
1567 * Beware: renderer string do not match exact card model,
1568 * eg HD 4800 is returned for multiple cards, even for RV790 based ones. */
1569#ifndef VBOX_WITH_WDDM
1570 if (WINE_D3D10_CAPABLE(gl_info))
1571#endif
1572 {
1573 /* Radeon EG CYPRESS XT / PRO HD5800 - highend */
1574 if (strstr(gl_renderer, "HD 5800") /* Radeon EG CYPRESS HD58xx generic renderer string */
1575 || strstr(gl_renderer, "HD 5850") /* Radeon EG CYPRESS XT */
1576 || strstr(gl_renderer, "HD 5870")) /* Radeon EG CYPRESS PRO */
1577 {
1578 *vidmem = 1024; /* note: HD58xx cards use 1024MB */
1579 return CARD_ATI_RADEON_HD5800;
1580 }
1581
1582 /* Radeon EG JUNIPER XT / LE HD5700 - midend */
1583 if (strstr(gl_renderer, "HD 5700") /* Radeon EG JUNIPER HD57xx generic renderer string */
1584 || strstr(gl_renderer, "HD 5750") /* Radeon EG JUNIPER LE */
1585 || strstr(gl_renderer, "HD 5770")) /* Radeon EG JUNIPER XT */
1586 {
1587 *vidmem = 512; /* note: HD5770 cards use 1024MB and HD5750 cards use 512MB or 1024MB */
1588 return CARD_ATI_RADEON_HD5700;
1589 }
1590
1591 /* Radeon R7xx HD4800 - highend */
1592 if (strstr(gl_renderer, "HD 4800") /* Radeon RV7xx HD48xx generic renderer string */
1593 || strstr(gl_renderer, "HD 4830") /* Radeon RV770 */
1594 || strstr(gl_renderer, "HD 4850") /* Radeon RV770 */
1595 || strstr(gl_renderer, "HD 4870") /* Radeon RV770 */
1596 || strstr(gl_renderer, "HD 4890")) /* Radeon RV790 */
1597 {
1598 *vidmem = 512; /* note: HD4890 cards use 1024MB */
1599 return CARD_ATI_RADEON_HD4800;
1600 }
1601
1602 /* Radeon R740 HD4700 - midend */
1603 if (strstr(gl_renderer, "HD 4700") /* Radeon RV770 */
1604 || strstr(gl_renderer, "HD 4770")) /* Radeon RV740 */
1605 {
1606 *vidmem = 512;
1607 return CARD_ATI_RADEON_HD4700;
1608 }
1609
1610 /* Radeon R730 HD4600 - midend */
1611 if (strstr(gl_renderer, "HD 4600") /* Radeon RV730 */
1612 || strstr(gl_renderer, "HD 4650") /* Radeon RV730 */
1613 || strstr(gl_renderer, "HD 4670")) /* Radeon RV730 */
1614 {
1615 *vidmem = 512;
1616 return CARD_ATI_RADEON_HD4600;
1617 }
1618
1619 /* Radeon R710 HD4500/HD4350 - lowend */
1620 if (strstr(gl_renderer, "HD 4350") /* Radeon RV710 */
1621 || strstr(gl_renderer, "HD 4550")) /* Radeon RV710 */
1622 {
1623 *vidmem = 256;
1624 return CARD_ATI_RADEON_HD4350;
1625 }
1626
1627 /* Radeon R6xx HD2900/HD3800 - highend */
1628 if (strstr(gl_renderer, "HD 2900")
1629 || strstr(gl_renderer, "HD 3870")
1630 || strstr(gl_renderer, "HD 3850"))
1631 {
1632 *vidmem = 512; /* HD2900/HD3800 uses 256-1024MB */
1633 return CARD_ATI_RADEON_HD2900;
1634 }
1635
1636 /* Radeon R6xx HD2600/HD3600 - midend; HD3830 is China-only midend */
1637 if (strstr(gl_renderer, "HD 2600")
1638 || strstr(gl_renderer, "HD 3830")
1639 || strstr(gl_renderer, "HD 3690")
1640 || strstr(gl_renderer, "HD 3650"))
1641 {
1642 *vidmem = 256; /* HD2600/HD3600 uses 256-512MB */
1643 return CARD_ATI_RADEON_HD2600;
1644 }
1645
1646 /* Radeon R6xx HD2350/HD2400/HD3400 - lowend
1647 * Note HD2300=DX9, HD2350=DX10 */
1648 if (strstr(gl_renderer, "HD 2350")
1649 || strstr(gl_renderer, "HD 2400")
1650 || strstr(gl_renderer, "HD 3470")
1651 || strstr(gl_renderer, "HD 3450")
1652 || strstr(gl_renderer, "HD 3430")
1653 || strstr(gl_renderer, "HD 3400"))
1654 {
1655 *vidmem = 256; /* HD2350/2400 use 256MB, HD34xx use 256-512MB */
1656 return CARD_ATI_RADEON_HD2350;
1657 }
1658
1659 /* Radeon R6xx/R7xx integrated */
1660 if (strstr(gl_renderer, "HD 3100")
1661 || strstr(gl_renderer, "HD 3200")
1662 || strstr(gl_renderer, "HD 3300"))
1663 {
1664 *vidmem = 128; /* 128MB */
1665 return CARD_ATI_RADEON_HD3200;
1666 }
1667
1668 /* Default for when no GPU has been found */
1669 *vidmem = 128; /* 128MB */
1670 return CARD_ATI_RADEON_HD3200;
1671 }
1672
1673 if (WINE_D3D8_CAPABLE(gl_info))
1674 {
1675 /* Radeon R5xx */
1676 if (strstr(gl_renderer, "X1600")
1677 || strstr(gl_renderer, "X1650")
1678 || strstr(gl_renderer, "X1800")
1679 || strstr(gl_renderer, "X1900")
1680 || strstr(gl_renderer, "X1950"))
1681 {
1682 *vidmem = 128; /* X1600 uses 128-256MB, >=X1800 uses 256MB */
1683 return CARD_ATI_RADEON_X1600;
1684 }
1685
1686 /* Radeon R4xx + X1300/X1400/X1450/X1550/X2300/X2500/HD2300 (lowend R5xx)
1687 * Note X2300/X2500/HD2300 are R5xx GPUs with a 2xxx naming but they are still DX9-only */
1688 if (strstr(gl_renderer, "X700")
1689 || strstr(gl_renderer, "X800")
1690 || strstr(gl_renderer, "X850")
1691 || strstr(gl_renderer, "X1300")
1692 || strstr(gl_renderer, "X1400")
1693 || strstr(gl_renderer, "X1450")
1694 || strstr(gl_renderer, "X1550")
1695 || strstr(gl_renderer, "X2300")
1696 || strstr(gl_renderer, "X2500")
1697 || strstr(gl_renderer, "HD 2300")
1698 )
1699 {
1700 *vidmem = 128; /* x700/x8*0 use 128-256MB, >=x1300 128-512MB */
1701 return CARD_ATI_RADEON_X700;
1702 }
1703
1704 /* Radeon Xpress Series - onboard, DX9b, Shader 2.0, 300-400MHz */
1705 if (strstr(gl_renderer, "Radeon Xpress"))
1706 {
1707 *vidmem = 64; /* Shared RAM, BIOS configurable, 64-256M */
1708 return CARD_ATI_RADEON_XPRESS_200M;
1709 }
1710
1711 /* Radeon R3xx */
1712 *vidmem = 64; /* Radeon 9500 uses 64MB, higher models use up to 256MB */
1713 return CARD_ATI_RADEON_9500; /* Radeon 9500/9550/9600/9700/9800/X300/X550/X600 */
1714 }
1715
1716 if (WINE_D3D8_CAPABLE(gl_info))
1717 {
1718 *vidmem = 64; /* 8500/9000 cards use mostly 64MB, though there are 32MB and 128MB models */
1719 return CARD_ATI_RADEON_8500; /* Radeon 8500/9000/9100/9200/9300 */
1720 }
1721
1722 if (WINE_D3D7_CAPABLE(gl_info))
1723 {
1724 *vidmem = 32; /* There are models with up to 64MB */
1725 return CARD_ATI_RADEON_7200; /* Radeon 7000/7100/7200/7500 */
1726 }
1727
1728 *vidmem = 16; /* There are 16-32MB models */
1729 return CARD_ATI_RAGE_128PRO;
1730
1731}
1732
1733static enum wined3d_pci_device select_card_intel_binary(const struct wined3d_gl_info *gl_info,
1734 const char *gl_renderer, unsigned int *vidmem)
1735{
1736 if (strstr(gl_renderer, "X3100"))
1737 {
1738 /* MacOS calls the card GMA X3100, Google findings also suggest the name GM965 */
1739 *vidmem = 128;
1740 return CARD_INTEL_X3100;
1741 }
1742
1743 if (strstr(gl_renderer, "GMA 950") || strstr(gl_renderer, "945GM"))
1744 {
1745 /* MacOS calls the card GMA 950, but everywhere else the PCI ID is named 945GM */
1746 *vidmem = 64;
1747 return CARD_INTEL_I945GM;
1748 }
1749
1750 if (strstr(gl_renderer, "915GM")) return CARD_INTEL_I915GM;
1751 if (strstr(gl_renderer, "915G")) return CARD_INTEL_I915G;
1752 if (strstr(gl_renderer, "865G")) return CARD_INTEL_I865G;
1753 if (strstr(gl_renderer, "855G")) return CARD_INTEL_I855G;
1754 if (strstr(gl_renderer, "830G")) return CARD_INTEL_I830G;
1755 return CARD_INTEL_I915G;
1756
1757}
1758
1759static enum wined3d_pci_device select_card_ati_mesa(const struct wined3d_gl_info *gl_info,
1760 const char *gl_renderer, unsigned int *vidmem)
1761{
1762 /* See http://developer.amd.com/drivers/pc_vendor_id/Pages/default.aspx
1763 *
1764 * Beware: renderer string do not match exact card model,
1765 * eg HD 4800 is returned for multiple cards, even for RV790 based ones. */
1766 if (strstr(gl_renderer, "Gallium"))
1767 {
1768 /* Radeon R7xx HD4800 - highend */
1769 if (strstr(gl_renderer, "R700") /* Radeon R7xx HD48xx generic renderer string */
1770 || strstr(gl_renderer, "RV770") /* Radeon RV770 */
1771 || strstr(gl_renderer, "RV790")) /* Radeon RV790 */
1772 {
1773 *vidmem = 512; /* note: HD4890 cards use 1024MB */
1774 return CARD_ATI_RADEON_HD4800;
1775 }
1776
1777 /* Radeon R740 HD4700 - midend */
1778 if (strstr(gl_renderer, "RV740")) /* Radeon RV740 */
1779 {
1780 *vidmem = 512;
1781 return CARD_ATI_RADEON_HD4700;
1782 }
1783
1784 /* Radeon R730 HD4600 - midend */
1785 if (strstr(gl_renderer, "RV730")) /* Radeon RV730 */
1786 {
1787 *vidmem = 512;
1788 return CARD_ATI_RADEON_HD4600;
1789 }
1790
1791 /* Radeon R710 HD4500/HD4350 - lowend */
1792 if (strstr(gl_renderer, "RV710")) /* Radeon RV710 */
1793 {
1794 *vidmem = 256;
1795 return CARD_ATI_RADEON_HD4350;
1796 }
1797
1798 /* Radeon R6xx HD2900/HD3800 - highend */
1799 if (strstr(gl_renderer, "R600")
1800 || strstr(gl_renderer, "RV670")
1801 || strstr(gl_renderer, "R680"))
1802 {
1803 *vidmem = 512; /* HD2900/HD3800 uses 256-1024MB */
1804 return CARD_ATI_RADEON_HD2900;
1805 }
1806
1807 /* Radeon R6xx HD2600/HD3600 - midend; HD3830 is China-only midend */
1808 if (strstr(gl_renderer, "RV630")
1809 || strstr(gl_renderer, "RV635"))
1810 {
1811 *vidmem = 256; /* HD2600/HD3600 uses 256-512MB */
1812 return CARD_ATI_RADEON_HD2600;
1813 }
1814
1815 /* Radeon R6xx HD2350/HD2400/HD3400 - lowend */
1816 if (strstr(gl_renderer, "RV610")
1817 || strstr(gl_renderer, "RV620"))
1818 {
1819 *vidmem = 256; /* HD2350/2400 use 256MB, HD34xx use 256-512MB */
1820 return CARD_ATI_RADEON_HD2350;
1821 }
1822
1823 /* Radeon R6xx/R7xx integrated */
1824 if (strstr(gl_renderer, "RS780")
1825 || strstr(gl_renderer, "RS880"))
1826 {
1827 *vidmem = 128; /* 128MB */
1828 return CARD_ATI_RADEON_HD3200;
1829 }
1830
1831 /* Radeon R5xx */
1832 if (strstr(gl_renderer, "RV530")
1833 || strstr(gl_renderer, "RV535")
1834 || strstr(gl_renderer, "RV560")
1835 || strstr(gl_renderer, "R520")
1836 || strstr(gl_renderer, "RV570")
1837 || strstr(gl_renderer, "R580"))
1838 {
1839 *vidmem = 128; /* X1600 uses 128-256MB, >=X1800 uses 256MB */
1840 return CARD_ATI_RADEON_X1600;
1841 }
1842
1843 /* Radeon R4xx + X1300/X1400/X1450/X1550/X2300 (lowend R5xx) */
1844 if (strstr(gl_renderer, "R410")
1845 || strstr(gl_renderer, "R420")
1846 || strstr(gl_renderer, "R423")
1847 || strstr(gl_renderer, "R430")
1848 || strstr(gl_renderer, "R480")
1849 || strstr(gl_renderer, "R481")
1850 || strstr(gl_renderer, "RV410")
1851 || strstr(gl_renderer, "RV515")
1852 || strstr(gl_renderer, "RV516"))
1853 {
1854 *vidmem = 128; /* x700/x8*0 use 128-256MB, >=x1300 128-512MB */
1855 return CARD_ATI_RADEON_X700;
1856 }
1857
1858 /* Radeon Xpress Series - onboard, DX9b, Shader 2.0, 300-400MHz */
1859 if (strstr(gl_renderer, "RS400")
1860 || strstr(gl_renderer, "RS480")
1861 || strstr(gl_renderer, "RS482")
1862 || strstr(gl_renderer, "RS485")
1863 || strstr(gl_renderer, "RS600")
1864 || strstr(gl_renderer, "RS690")
1865 || strstr(gl_renderer, "RS740"))
1866 {
1867 *vidmem = 64; /* Shared RAM, BIOS configurable, 64-256M */
1868 return CARD_ATI_RADEON_XPRESS_200M;
1869 }
1870
1871 /* Radeon R3xx */
1872 if (strstr(gl_renderer, "R300")
1873 || strstr(gl_renderer, "RV350")
1874 || strstr(gl_renderer, "RV351")
1875 || strstr(gl_renderer, "RV360")
1876 || strstr(gl_renderer, "RV370")
1877 || strstr(gl_renderer, "R350")
1878 || strstr(gl_renderer, "R360"))
1879 {
1880 *vidmem = 64; /* Radeon 9500 uses 64MB, higher models use up to 256MB */
1881 return CARD_ATI_RADEON_9500; /* Radeon 9500/9550/9600/9700/9800/X300/X550/X600 */
1882 }
1883 }
1884
1885 if (WINE_D3D9_CAPABLE(gl_info))
1886 {
1887 /* Radeon R7xx HD4800 - highend */
1888 if (strstr(gl_renderer, "(R700") /* Radeon R7xx HD48xx generic renderer string */
1889 || strstr(gl_renderer, "(RV770") /* Radeon RV770 */
1890 || strstr(gl_renderer, "(RV790")) /* Radeon RV790 */
1891 {
1892 *vidmem = 512; /* note: HD4890 cards use 1024MB */
1893 return CARD_ATI_RADEON_HD4800;
1894 }
1895
1896 /* Radeon R740 HD4700 - midend */
1897 if (strstr(gl_renderer, "(RV740")) /* Radeon RV740 */
1898 {
1899 *vidmem = 512;
1900 return CARD_ATI_RADEON_HD4700;
1901 }
1902
1903 /* Radeon R730 HD4600 - midend */
1904 if (strstr(gl_renderer, "(RV730")) /* Radeon RV730 */
1905 {
1906 *vidmem = 512;
1907 return CARD_ATI_RADEON_HD4600;
1908 }
1909
1910 /* Radeon R710 HD4500/HD4350 - lowend */
1911 if (strstr(gl_renderer, "(RV710")) /* Radeon RV710 */
1912 {
1913 *vidmem = 256;
1914 return CARD_ATI_RADEON_HD4350;
1915 }
1916
1917 /* Radeon R6xx HD2900/HD3800 - highend */
1918 if (strstr(gl_renderer, "(R600")
1919 || strstr(gl_renderer, "(RV670")
1920 || strstr(gl_renderer, "(R680"))
1921 {
1922 *vidmem = 512; /* HD2900/HD3800 uses 256-1024MB */
1923 return CARD_ATI_RADEON_HD2900;
1924 }
1925
1926 /* Radeon R6xx HD2600/HD3600 - midend; HD3830 is China-only midend */
1927 if (strstr(gl_renderer, "(RV630")
1928 || strstr(gl_renderer, "(RV635"))
1929 {
1930 *vidmem = 256; /* HD2600/HD3600 uses 256-512MB */
1931 return CARD_ATI_RADEON_HD2600;
1932 }
1933
1934 /* Radeon R6xx HD2300/HD2400/HD3400 - lowend */
1935 if (strstr(gl_renderer, "(RV610")
1936 || strstr(gl_renderer, "(RV620"))
1937 {
1938 *vidmem = 256; /* HD2350/2400 use 256MB, HD34xx use 256-512MB */
1939 return CARD_ATI_RADEON_HD2350;
1940 }
1941
1942 /* Radeon R6xx/R7xx integrated */
1943 if (strstr(gl_renderer, "(RS780")
1944 || strstr(gl_renderer, "(RS880"))
1945 {
1946 *vidmem = 128; /* 128MB */
1947 return CARD_ATI_RADEON_HD3200;
1948 }
1949 }
1950
1951 if (WINE_D3D8_CAPABLE(gl_info))
1952 {
1953 *vidmem = 64; /* 8500/9000 cards use mostly 64MB, though there are 32MB and 128MB models */
1954 return CARD_ATI_RADEON_8500; /* Radeon 8500/9000/9100/9200/9300 */
1955 }
1956
1957 if (WINE_D3D7_CAPABLE(gl_info))
1958 {
1959 *vidmem = 32; /* There are models with up to 64MB */
1960 return CARD_ATI_RADEON_7200; /* Radeon 7000/7100/7200/7500 */
1961 }
1962
1963 *vidmem = 16; /* There are 16-32MB models */
1964 return CARD_ATI_RAGE_128PRO;
1965
1966}
1967
1968static enum wined3d_pci_device select_card_nvidia_mesa(const struct wined3d_gl_info *gl_info,
1969 const char *gl_renderer, unsigned int *vidmem)
1970{
1971 FIXME_(d3d_caps)("Card selection not handled for Mesa Nouveau driver\n");
1972#ifndef VBOX_WITH_WDDM
1973 if (WINE_D3D9_CAPABLE(gl_info)) return CARD_NVIDIA_GEFORCEFX_5600;
1974#else
1975 /* tmp work around to disable quirk_no_np2 quirk for mesa drivers */
1976 if (WINE_D3D9_CAPABLE(gl_info)) return CARD_NVIDIA_GEFORCE_6200;
1977#endif
1978 if (WINE_D3D8_CAPABLE(gl_info)) return CARD_NVIDIA_GEFORCE3;
1979 if (WINE_D3D7_CAPABLE(gl_info)) return CARD_NVIDIA_GEFORCE;
1980 if (WINE_D3D6_CAPABLE(gl_info)) return CARD_NVIDIA_RIVA_TNT;
1981 return CARD_NVIDIA_RIVA_128;
1982}
1983
1984static enum wined3d_pci_device select_card_intel_mesa(const struct wined3d_gl_info *gl_info,
1985 const char *gl_renderer, unsigned int *vidmem)
1986{
1987 FIXME_(d3d_caps)("Card selection not handled for Mesa Intel driver\n");
1988 return CARD_INTEL_I915G;
1989}
1990
1991
1992struct vendor_card_selection
1993{
1994 enum wined3d_gl_vendor gl_vendor;
1995 enum wined3d_pci_vendor card_vendor;
1996 const char *description; /* Description of the card selector i.e. Apple OS/X Intel */
1997 enum wined3d_pci_device (*select_card)(const struct wined3d_gl_info *gl_info, const char *gl_renderer,
1998 unsigned int *vidmem );
1999};
2000
2001static const struct vendor_card_selection vendor_card_select_table[] =
2002{
2003 {GL_VENDOR_NVIDIA, HW_VENDOR_NVIDIA, "Nvidia binary driver", select_card_nvidia_binary},
2004 {GL_VENDOR_APPLE, HW_VENDOR_NVIDIA, "Apple OSX NVidia binary driver", select_card_nvidia_binary},
2005 {GL_VENDOR_APPLE, HW_VENDOR_ATI, "Apple OSX AMD/ATI binary driver", select_card_ati_binary},
2006 {GL_VENDOR_APPLE, HW_VENDOR_INTEL, "Apple OSX Intel binary driver", select_card_intel_binary},
2007 {GL_VENDOR_FGLRX, HW_VENDOR_ATI, "AMD/ATI binary driver", select_card_ati_binary},
2008 {GL_VENDOR_MESA, HW_VENDOR_ATI, "Mesa AMD/ATI driver", select_card_ati_mesa},
2009 {GL_VENDOR_MESA, HW_VENDOR_NVIDIA, "Mesa Nouveau driver", select_card_nvidia_mesa},
2010 {GL_VENDOR_MESA, HW_VENDOR_INTEL, "Mesa Intel driver", select_card_intel_mesa}
2011};
2012
2013
2014static enum wined3d_pci_device wined3d_guess_card(const struct wined3d_gl_info *gl_info, const char *gl_renderer,
2015 enum wined3d_gl_vendor *gl_vendor, enum wined3d_pci_vendor *card_vendor, unsigned int *vidmem)
2016{
2017 /* Above is a list of Nvidia and ATI GPUs. Both vendors have dozens of
2018 * different GPUs with roughly the same features. In most cases GPUs from a
2019 * certain family differ in clockspeeds, the amount of video memory and the
2020 * number of shader pipelines.
2021 *
2022 * A Direct3D device object contains the PCI id (vendor + device) of the
2023 * videocard which is used for rendering. Various applications use this
2024 * information to get a rough estimation of the features of the card and
2025 * some might use it for enabling 3d effects only on certain types of
2026 * videocards. In some cases games might even use it to work around bugs
2027 * which happen on certain videocards/driver combinations. The problem is
2028 * that OpenGL only exposes a rendering string containing the name of the
2029 * videocard and not the PCI id.
2030 *
2031 * Various games depend on the PCI id, so somehow we need to provide one.
2032 * A simple option is to parse the renderer string and translate this to
2033 * the right PCI id. This is a lot of work because there are more than 200
2034 * GPUs just for Nvidia. Various cards share the same renderer string, so
2035 * the amount of code might be 'small' but there are quite a number of
2036 * exceptions which would make this a pain to maintain. Another way would
2037 * be to query the PCI id from the operating system (assuming this is the
2038 * videocard which is used for rendering which is not always the case).
2039 * This would work but it is not very portable. Second it would not work
2040 * well in, let's say, a remote X situation in which the amount of 3d
2041 * features which can be used is limited.
2042 *
2043 * As said most games only use the PCI id to get an indication of the
2044 * capabilities of the card. It doesn't really matter if the given id is
2045 * the correct one if we return the id of a card with similar 3d features.
2046 *
2047 * The code below checks the OpenGL capabilities of a videocard and matches
2048 * that to a certain level of Direct3D functionality. Once a card passes
2049 * the Direct3D9 check, we know that the card (in case of Nvidia) is at
2050 * least a GeforceFX. To give a better estimate we do a basic check on the
2051 * renderer string but if that won't pass we return a default card. This
2052 * way is better than maintaining a full card database as even without a
2053 * full database we can return a card with similar features. Second the
2054 * size of the database can be made quite small because when you know what
2055 * type of 3d functionality a card has, you know to which GPU family the
2056 * GPU must belong. Because of this you only have to check a small part of
2057 * the renderer string to distinguishes between different models from that
2058 * family.
2059 *
2060 * The code also selects a default amount of video memory which we will
2061 * use for an estimation of the amount of free texture memory. In case of
2062 * real D3D the amount of texture memory includes video memory and system
2063 * memory (to be specific AGP memory or in case of PCIE TurboCache /
2064 * HyperMemory). We don't know how much system memory can be addressed by
2065 * the system but we can make a reasonable estimation about the amount of
2066 * video memory. If the value is slightly wrong it doesn't matter as we
2067 * didn't include AGP-like memory which makes the amount of addressable
2068 * memory higher and second OpenGL isn't that critical it moves to system
2069 * memory behind our backs if really needed. Note that the amount of video
2070 * memory can be overruled using a registry setting. */
2071
2072 int i;
2073
2074 for (i = 0; i < (sizeof(vendor_card_select_table) / sizeof(*vendor_card_select_table)); ++i)
2075 {
2076 if ((vendor_card_select_table[i].gl_vendor != *gl_vendor)
2077 || (vendor_card_select_table[i].card_vendor != *card_vendor))
2078 continue;
2079 TRACE_(d3d_caps)("Applying card_selector \"%s\".\n", vendor_card_select_table[i].description);
2080 return vendor_card_select_table[i].select_card(gl_info, gl_renderer, vidmem);
2081 }
2082
2083 FIXME_(d3d_caps)("No card selector available for GL vendor %d and card vendor %04x.\n",
2084 *gl_vendor, *card_vendor);
2085
2086 /* Default to generic Nvidia hardware based on the supported OpenGL extensions. The choice
2087 * for Nvidia was because the hardware and drivers they make are of good quality. This makes
2088 * them a good generic choice. */
2089 *card_vendor = HW_VENDOR_NVIDIA;
2090#ifndef VBOX_WITH_WDDM
2091 if (WINE_D3D9_CAPABLE(gl_info)) return CARD_NVIDIA_GEFORCEFX_5600;
2092#else
2093 /* tmp work around to disable quirk_no_np2 quirk for not-recognized drivers */
2094 if (WINE_D3D9_CAPABLE(gl_info)) return CARD_NVIDIA_GEFORCE_6200;
2095#endif
2096
2097 if (WINE_D3D8_CAPABLE(gl_info)) return CARD_NVIDIA_GEFORCE3;
2098 if (WINE_D3D7_CAPABLE(gl_info)) return CARD_NVIDIA_GEFORCE;
2099 if (WINE_D3D6_CAPABLE(gl_info)) return CARD_NVIDIA_RIVA_TNT;
2100 return CARD_NVIDIA_RIVA_128;
2101}
2102
2103static const struct fragment_pipeline *select_fragment_implementation(struct wined3d_adapter *adapter)
2104{
2105 const struct wined3d_gl_info *gl_info = &adapter->gl_info;
2106 int vs_selected_mode, ps_selected_mode;
2107
2108 select_shader_mode(gl_info, &ps_selected_mode, &vs_selected_mode);
2109 if ((ps_selected_mode == SHADER_ARB || ps_selected_mode == SHADER_GLSL)
2110 && gl_info->supported[ARB_FRAGMENT_PROGRAM]) return &arbfp_fragment_pipeline;
2111 else if (ps_selected_mode == SHADER_ATI) return &atifs_fragment_pipeline;
2112 else if (gl_info->supported[NV_REGISTER_COMBINERS]
2113 && gl_info->supported[NV_TEXTURE_SHADER2]) return &nvts_fragment_pipeline;
2114 else if (gl_info->supported[NV_REGISTER_COMBINERS]) return &nvrc_fragment_pipeline;
2115 else return &ffp_fragment_pipeline;
2116}
2117
2118static const shader_backend_t *select_shader_backend(struct wined3d_adapter *adapter)
2119{
2120 int vs_selected_mode, ps_selected_mode;
2121
2122 select_shader_mode(&adapter->gl_info, &ps_selected_mode, &vs_selected_mode);
2123 if (vs_selected_mode == SHADER_GLSL || ps_selected_mode == SHADER_GLSL) return &glsl_shader_backend;
2124 if (vs_selected_mode == SHADER_ARB || ps_selected_mode == SHADER_ARB) return &arb_program_shader_backend;
2125 return &none_shader_backend;
2126}
2127
2128static const struct blit_shader *select_blit_implementation(struct wined3d_adapter *adapter)
2129{
2130 const struct wined3d_gl_info *gl_info = &adapter->gl_info;
2131 int vs_selected_mode, ps_selected_mode;
2132
2133 select_shader_mode(gl_info, &ps_selected_mode, &vs_selected_mode);
2134 if ((ps_selected_mode == SHADER_ARB || ps_selected_mode == SHADER_GLSL)
2135 && gl_info->supported[ARB_FRAGMENT_PROGRAM]) return &arbfp_blit;
2136 else return &ffp_blit;
2137}
2138
2139/* Context activation is done by the caller. */
2140static BOOL IWineD3DImpl_FillGLCaps(struct wined3d_adapter *adapter)
2141{
2142 struct wined3d_driver_info *driver_info = &adapter->driver_info;
2143 struct wined3d_gl_info *gl_info = &adapter->gl_info;
2144 const char *GL_Extensions = NULL;
2145 const char *WGL_Extensions = NULL;
2146 const char *gl_vendor_str, *gl_renderer_str, *gl_version_str;
2147 struct fragment_caps fragment_caps;
2148 enum wined3d_gl_vendor gl_vendor;
2149 enum wined3d_pci_vendor card_vendor;
2150 enum wined3d_pci_device device;
2151 GLint gl_max;
2152 GLfloat gl_floatv[2];
2153 unsigned i;
2154 HDC hdc;
2155 unsigned int vidmem=0;
2156 DWORD gl_version;
2157 size_t len;
2158
2159 TRACE_(d3d_caps)("(%p)\n", gl_info);
2160
2161 ENTER_GL();
2162
2163 gl_renderer_str = (const char *)glGetString(GL_RENDERER);
2164 TRACE_(d3d_caps)("GL_RENDERER: %s.\n", debugstr_a(gl_renderer_str));
2165 if (!gl_renderer_str)
2166 {
2167 LEAVE_GL();
2168 ERR_(d3d_caps)("Received a NULL GL_RENDERER.\n");
2169 return FALSE;
2170 }
2171
2172 gl_vendor_str = (const char *)glGetString(GL_VENDOR);
2173 TRACE_(d3d_caps)("GL_VENDOR: %s.\n", debugstr_a(gl_vendor_str));
2174 if (!gl_vendor_str)
2175 {
2176 LEAVE_GL();
2177 ERR_(d3d_caps)("Received a NULL GL_VENDOR.\n");
2178 return FALSE;
2179 }
2180
2181 /* Parse the GL_VERSION field into major and minor information */
2182 gl_version_str = (const char *)glGetString(GL_VERSION);
2183 TRACE_(d3d_caps)("GL_VERSION: %s.\n", debugstr_a(gl_version_str));
2184 if (!gl_version_str)
2185 {
2186 LEAVE_GL();
2187 ERR_(d3d_caps)("Received a NULL GL_VERSION.\n");
2188 return FALSE;
2189 }
2190 gl_version = wined3d_parse_gl_version(gl_version_str);
2191
2192 /*
2193 * Initialize openGL extension related variables
2194 * with Default values
2195 */
2196 memset(gl_info->supported, 0, sizeof(gl_info->supported));
2197 gl_info->limits.blends = 1;
2198 gl_info->limits.buffers = 1;
2199 gl_info->limits.textures = 1;
2200 gl_info->limits.fragment_samplers = 1;
2201 gl_info->limits.vertex_samplers = 0;
2202 gl_info->limits.combined_samplers = gl_info->limits.fragment_samplers + gl_info->limits.vertex_samplers;
2203 gl_info->limits.sampler_stages = 1;
2204 gl_info->limits.glsl_vs_float_constants = 0;
2205 gl_info->limits.glsl_ps_float_constants = 0;
2206 gl_info->limits.arb_vs_float_constants = 0;
2207 gl_info->limits.arb_vs_native_constants = 0;
2208 gl_info->limits.arb_vs_instructions = 0;
2209 gl_info->limits.arb_vs_temps = 0;
2210 gl_info->limits.arb_ps_float_constants = 0;
2211 gl_info->limits.arb_ps_local_constants = 0;
2212 gl_info->limits.arb_ps_instructions = 0;
2213 gl_info->limits.arb_ps_temps = 0;
2214
2215 /* Retrieve opengl defaults */
2216 glGetIntegerv(GL_MAX_CLIP_PLANES, &gl_max);
2217 gl_info->limits.clipplanes = min(WINED3DMAXUSERCLIPPLANES, gl_max);
2218 TRACE_(d3d_caps)("ClipPlanes support - num Planes=%d\n", gl_max);
2219
2220 glGetIntegerv(GL_MAX_LIGHTS, &gl_max);
2221 gl_info->limits.lights = gl_max;
2222 TRACE_(d3d_caps)("Lights support - max lights=%d\n", gl_max);
2223
2224 glGetIntegerv(GL_MAX_TEXTURE_SIZE, &gl_max);
2225 gl_info->limits.texture_size = gl_max;
2226 TRACE_(d3d_caps)("Maximum texture size support - max texture size=%d\n", gl_max);
2227
2228 glGetFloatv(GL_ALIASED_POINT_SIZE_RANGE, gl_floatv);
2229 gl_info->limits.pointsize_min = gl_floatv[0];
2230 gl_info->limits.pointsize_max = gl_floatv[1];
2231 TRACE_(d3d_caps)("Maximum point size support - max point size=%f\n", gl_floatv[1]);
2232
2233 /* Parse the gl supported features, in theory enabling parts of our code appropriately. */
2234 GL_Extensions = (const char *)glGetString(GL_EXTENSIONS);
2235 if (!GL_Extensions)
2236 {
2237 LEAVE_GL();
2238 ERR_(d3d_caps)("Received a NULL GL_EXTENSIONS.\n");
2239 return FALSE;
2240 }
2241
2242 LEAVE_GL();
2243
2244 TRACE_(d3d_caps)("GL_Extensions reported:\n");
2245
2246 gl_info->supported[WINED3D_GL_EXT_NONE] = TRUE;
2247
2248 gl_info->supported[VBOX_SHARED_CONTEXTS] = TRUE;
2249
2250 while (*GL_Extensions)
2251 {
2252 const char *start;
2253 char current_ext[256];
2254
2255 while (isspace(*GL_Extensions)) ++GL_Extensions;
2256 start = GL_Extensions;
2257 while (!isspace(*GL_Extensions) && *GL_Extensions) ++GL_Extensions;
2258
2259 len = GL_Extensions - start;
2260 if (!len || len >= sizeof(current_ext)) continue;
2261
2262 memcpy(current_ext, start, len);
2263 current_ext[len] = '\0';
2264 TRACE_(d3d_caps)("- %s\n", debugstr_a(current_ext));
2265
2266 for (i = 0; i < (sizeof(EXTENSION_MAP) / sizeof(*EXTENSION_MAP)); ++i)
2267 {
2268 if (!strcmp(current_ext, EXTENSION_MAP[i].extension_string))
2269 {
2270 TRACE_(d3d_caps)(" FOUND: %s support.\n", EXTENSION_MAP[i].extension_string);
2271 gl_info->supported[EXTENSION_MAP[i].extension] = TRUE;
2272 break;
2273 }
2274 }
2275 }
2276
2277 /* Now work out what GL support this card really has */
2278#define USE_GL_FUNC(type, pfn, ext, replace) \
2279{ \
2280 DWORD ver = ver_for_ext(ext); \
2281 if (gl_info->supported[ext]) gl_info->pfn = (type)pwglGetProcAddress(#pfn); \
2282 else if (ver && ver <= gl_version) gl_info->pfn = (type)pwglGetProcAddress(#replace); \
2283 else gl_info->pfn = NULL; \
2284}
2285 GL_EXT_FUNCS_GEN;
2286#undef USE_GL_FUNC
2287
2288#define USE_GL_FUNC(type, pfn, ext, replace) gl_info->pfn = (type)pwglGetProcAddress(#pfn);
2289 WGL_EXT_FUNCS_GEN;
2290#undef USE_GL_FUNC
2291
2292 ENTER_GL();
2293
2294 /* Now mark all the extensions supported which are included in the opengl core version. Do this *after*
2295 * loading the functions, otherwise the code above will load the extension entry points instead of the
2296 * core functions, which may not work. */
2297 for (i = 0; i < (sizeof(EXTENSION_MAP) / sizeof(*EXTENSION_MAP)); ++i)
2298 {
2299 if (!gl_info->supported[EXTENSION_MAP[i].extension]
2300 && EXTENSION_MAP[i].version <= gl_version && EXTENSION_MAP[i].version)
2301 {
2302 TRACE_(d3d_caps)(" GL CORE: %s support.\n", EXTENSION_MAP[i].extension_string);
2303 gl_info->supported[EXTENSION_MAP[i].extension] = TRUE;
2304 }
2305 }
2306
2307 if (gl_info->supported[APPLE_FENCE])
2308 {
2309 /* GL_NV_fence and GL_APPLE_fence provide the same functionality basically.
2310 * The apple extension interacts with some other apple exts. Disable the NV
2311 * extension if the apple one is support to prevent confusion in other parts
2312 * of the code. */
2313 gl_info->supported[NV_FENCE] = FALSE;
2314 }
2315 if (gl_info->supported[APPLE_FLOAT_PIXELS])
2316 {
2317 /* GL_APPLE_float_pixels == GL_ARB_texture_float + GL_ARB_half_float_pixel
2318 *
2319 * The enums are the same:
2320 * GL_RGBA16F_ARB = GL_RGBA_FLOAT16_APPLE = 0x881A
2321 * GL_RGB16F_ARB = GL_RGB_FLOAT16_APPLE = 0x881B
2322 * GL_RGBA32F_ARB = GL_RGBA_FLOAT32_APPLE = 0x8814
2323 * GL_RGB32F_ARB = GL_RGB_FLOAT32_APPLE = 0x8815
2324 * GL_HALF_FLOAT_ARB = GL_HALF_APPLE = 0x140B
2325 */
2326 if (!gl_info->supported[ARB_TEXTURE_FLOAT])
2327 {
2328 TRACE_(d3d_caps)(" IMPLIED: GL_ARB_texture_float support(from GL_APPLE_float_pixels.\n");
2329 gl_info->supported[ARB_TEXTURE_FLOAT] = TRUE;
2330 }
2331 if (!gl_info->supported[ARB_HALF_FLOAT_PIXEL])
2332 {
2333 TRACE_(d3d_caps)(" IMPLIED: GL_ARB_half_float_pixel support(from GL_APPLE_float_pixels.\n");
2334 gl_info->supported[ARB_HALF_FLOAT_PIXEL] = TRUE;
2335 }
2336 }
2337 if (gl_info->supported[ARB_MAP_BUFFER_RANGE])
2338 {
2339 /* GL_ARB_map_buffer_range and GL_APPLE_flush_buffer_range provide the same
2340 * functionality. Prefer the ARB extension */
2341 gl_info->supported[APPLE_FLUSH_BUFFER_RANGE] = FALSE;
2342 }
2343 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
2344 {
2345 TRACE_(d3d_caps)(" IMPLIED: NVIDIA (NV) Texture Gen Reflection support.\n");
2346 gl_info->supported[NV_TEXGEN_REFLECTION] = TRUE;
2347 }
2348 if (!gl_info->supported[ARB_DEPTH_CLAMP] && gl_info->supported[NV_DEPTH_CLAMP])
2349 {
2350 TRACE_(d3d_caps)(" IMPLIED: ARB_depth_clamp support (by NV_depth_clamp).\n");
2351 gl_info->supported[ARB_DEPTH_CLAMP] = TRUE;
2352 }
2353 if (!gl_info->supported[ARB_VERTEX_ARRAY_BGRA] && gl_info->supported[EXT_VERTEX_ARRAY_BGRA])
2354 {
2355 TRACE_(d3d_caps)(" IMPLIED: ARB_vertex_array_bgra support (by EXT_vertex_array_bgra).\n");
2356 gl_info->supported[ARB_VERTEX_ARRAY_BGRA] = TRUE;
2357 }
2358 if (gl_info->supported[NV_TEXTURE_SHADER2])
2359 {
2360 if (gl_info->supported[NV_REGISTER_COMBINERS])
2361 {
2362 /* Also disable ATI_FRAGMENT_SHADER if register combiners and texture_shader2
2363 * are supported. The nv extensions provide the same functionality as the
2364 * ATI one, and a bit more(signed pixelformats). */
2365 gl_info->supported[ATI_FRAGMENT_SHADER] = FALSE;
2366 }
2367 }
2368
2369 if (gl_info->supported[NV_REGISTER_COMBINERS])
2370 {
2371 glGetIntegerv(GL_MAX_GENERAL_COMBINERS_NV, &gl_max);
2372 gl_info->limits.general_combiners = gl_max;
2373 TRACE_(d3d_caps)("Max general combiners: %d.\n", gl_max);
2374 }
2375 if (gl_info->supported[ARB_DRAW_BUFFERS])
2376 {
2377 glGetIntegerv(GL_MAX_DRAW_BUFFERS_ARB, &gl_max);
2378 gl_info->limits.buffers = gl_max;
2379 TRACE_(d3d_caps)("Max draw buffers: %u.\n", gl_max);
2380 }
2381 if (gl_info->supported[ARB_MULTITEXTURE])
2382 {
2383 glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, &gl_max);
2384 gl_info->limits.textures = min(MAX_TEXTURES, gl_max);
2385 TRACE_(d3d_caps)("Max textures: %d.\n", gl_info->limits.textures);
2386
2387 if (gl_info->supported[ARB_FRAGMENT_PROGRAM])
2388 {
2389 GLint tmp;
2390 glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS_ARB, &tmp);
2391 gl_info->limits.fragment_samplers = min(MAX_FRAGMENT_SAMPLERS, tmp);
2392 }
2393 else
2394 {
2395 gl_info->limits.fragment_samplers = max(gl_info->limits.fragment_samplers, gl_max);
2396 }
2397 TRACE_(d3d_caps)("Max fragment samplers: %d.\n", gl_info->limits.fragment_samplers);
2398
2399 if (gl_info->supported[ARB_VERTEX_SHADER])
2400 {
2401 GLint tmp;
2402 glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB, &tmp);
2403 gl_info->limits.vertex_samplers = tmp;
2404 glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB, &tmp);
2405 gl_info->limits.combined_samplers = tmp;
2406
2407 /* Loading GLSL sampler uniforms is much simpler if we can assume that the sampler setup
2408 * is known at shader link time. In a vertex shader + pixel shader combination this isn't
2409 * an issue because then the sampler setup only depends on the two shaders. If a pixel
2410 * shader is used with fixed function vertex processing we're fine too because fixed function
2411 * vertex processing doesn't use any samplers. If fixed function fragment processing is
2412 * used we have to make sure that all vertex sampler setups are valid together with all
2413 * possible fixed function fragment processing setups. This is true if vsamplers + MAX_TEXTURES
2414 * <= max_samplers. This is true on all d3d9 cards that support vtf(gf 6 and gf7 cards).
2415 * dx9 radeon cards do not support vertex texture fetch. DX10 cards have 128 samplers, and
2416 * dx9 is limited to 8 fixed function texture stages and 4 vertex samplers. DX10 does not have
2417 * a fixed function pipeline anymore.
2418 *
2419 * So this is just a check to check that our assumption holds true. If not, write a warning
2420 * and reduce the number of vertex samplers or probably disable vertex texture fetch. */
2421 if (gl_info->limits.vertex_samplers && gl_info->limits.combined_samplers < 12
2422 && MAX_TEXTURES + gl_info->limits.vertex_samplers > gl_info->limits.combined_samplers)
2423 {
2424 FIXME("OpenGL implementation supports %u vertex samplers and %u total samplers.\n",
2425 gl_info->limits.vertex_samplers, gl_info->limits.combined_samplers);
2426 FIXME("Expected vertex samplers + MAX_TEXTURES(=8) > combined_samplers.\n");
2427 if (gl_info->limits.combined_samplers > MAX_TEXTURES)
2428 gl_info->limits.vertex_samplers = gl_info->limits.combined_samplers - MAX_TEXTURES;
2429 else
2430 gl_info->limits.vertex_samplers = 0;
2431 }
2432 }
2433 else
2434 {
2435 gl_info->limits.combined_samplers = gl_info->limits.fragment_samplers;
2436 }
2437 TRACE_(d3d_caps)("Max vertex samplers: %u.\n", gl_info->limits.vertex_samplers);
2438 TRACE_(d3d_caps)("Max combined samplers: %u.\n", gl_info->limits.combined_samplers);
2439 }
2440 if (gl_info->supported[ARB_VERTEX_BLEND])
2441 {
2442 glGetIntegerv(GL_MAX_VERTEX_UNITS_ARB, &gl_max);
2443 gl_info->limits.blends = gl_max;
2444 TRACE_(d3d_caps)("Max blends: %u.\n", gl_info->limits.blends);
2445 }
2446 if (gl_info->supported[EXT_TEXTURE3D])
2447 {
2448 glGetIntegerv(GL_MAX_3D_TEXTURE_SIZE_EXT, &gl_max);
2449 gl_info->limits.texture3d_size = gl_max;
2450 TRACE_(d3d_caps)("Max texture3D size: %d.\n", gl_info->limits.texture3d_size);
2451 }
2452 if (gl_info->supported[EXT_TEXTURE_FILTER_ANISOTROPIC])
2453 {
2454 glGetIntegerv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &gl_max);
2455 gl_info->limits.anisotropy = gl_max;
2456 TRACE_(d3d_caps)("Max anisotropy: %d.\n", gl_info->limits.anisotropy);
2457 }
2458 if (gl_info->supported[ARB_FRAGMENT_PROGRAM])
2459 {
2460 GL_EXTCALL(glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_ENV_PARAMETERS_ARB, &gl_max));
2461 gl_info->limits.arb_ps_float_constants = gl_max;
2462 TRACE_(d3d_caps)("Max ARB_FRAGMENT_PROGRAM float constants: %d.\n", gl_info->limits.arb_ps_float_constants);
2463 GL_EXTCALL(glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB, &gl_max));
2464 gl_info->limits.arb_ps_native_constants = gl_max;
2465 TRACE_(d3d_caps)("Max ARB_FRAGMENT_PROGRAM native float constants: %d.\n",
2466 gl_info->limits.arb_ps_native_constants);
2467 GL_EXTCALL(glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB, &gl_max));
2468 gl_info->limits.arb_ps_temps = gl_max;
2469 TRACE_(d3d_caps)("Max ARB_FRAGMENT_PROGRAM native temporaries: %d.\n", gl_info->limits.arb_ps_temps);
2470 GL_EXTCALL(glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB, &gl_max));
2471 gl_info->limits.arb_ps_instructions = gl_max;
2472 TRACE_(d3d_caps)("Max ARB_FRAGMENT_PROGRAM native instructions: %d.\n", gl_info->limits.arb_ps_instructions);
2473 GL_EXTCALL(glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB, &gl_max));
2474 gl_info->limits.arb_ps_local_constants = gl_max;
2475 TRACE_(d3d_caps)("Max ARB_FRAGMENT_PROGRAM local parameters: %d.\n", gl_info->limits.arb_ps_instructions);
2476 }
2477 if (gl_info->supported[ARB_VERTEX_PROGRAM])
2478 {
2479 GL_EXTCALL(glGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_MAX_PROGRAM_ENV_PARAMETERS_ARB, &gl_max));
2480 gl_info->limits.arb_vs_float_constants = gl_max;
2481 TRACE_(d3d_caps)("Max ARB_VERTEX_PROGRAM float constants: %d.\n", gl_info->limits.arb_vs_float_constants);
2482 GL_EXTCALL(glGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB, &gl_max));
2483 gl_info->limits.arb_vs_native_constants = gl_max;
2484 TRACE_(d3d_caps)("Max ARB_VERTEX_PROGRAM native float constants: %d.\n",
2485 gl_info->limits.arb_vs_native_constants);
2486 GL_EXTCALL(glGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB, &gl_max));
2487 gl_info->limits.arb_vs_temps = gl_max;
2488 TRACE_(d3d_caps)("Max ARB_VERTEX_PROGRAM native temporaries: %d.\n", gl_info->limits.arb_vs_temps);
2489 GL_EXTCALL(glGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB, &gl_max));
2490 gl_info->limits.arb_vs_instructions = gl_max;
2491 TRACE_(d3d_caps)("Max ARB_VERTEX_PROGRAM native instructions: %d.\n", gl_info->limits.arb_vs_instructions);
2492
2493 if (test_arb_vs_offset_limit(gl_info)) gl_info->quirks |= WINED3D_QUIRK_ARB_VS_OFFSET_LIMIT;
2494 }
2495 if (gl_info->supported[ARB_VERTEX_SHADER])
2496 {
2497 glGetIntegerv(GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB, &gl_max);
2498 gl_info->limits.glsl_vs_float_constants = gl_max / 4;
2499 TRACE_(d3d_caps)("Max ARB_VERTEX_SHADER float constants: %u.\n", gl_info->limits.glsl_vs_float_constants);
2500 }
2501 if (gl_info->supported[ARB_FRAGMENT_SHADER])
2502 {
2503 glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB, &gl_max);
2504 gl_info->limits.glsl_ps_float_constants = gl_max / 4;
2505 TRACE_(d3d_caps)("Max ARB_FRAGMENT_SHADER float constants: %u.\n", gl_info->limits.glsl_ps_float_constants);
2506 glGetIntegerv(GL_MAX_VARYING_FLOATS_ARB, &gl_max);
2507 gl_info->limits.glsl_varyings = gl_max;
2508 TRACE_(d3d_caps)("Max GLSL varyings: %u (%u 4 component varyings).\n", gl_max, gl_max / 4);
2509 }
2510 if (gl_info->supported[ARB_SHADING_LANGUAGE_100])
2511 {
2512 const char *str = (const char *)glGetString(GL_SHADING_LANGUAGE_VERSION_ARB);
2513 unsigned int major, minor;
2514
2515 TRACE_(d3d_caps)("GLSL version string: %s.\n", debugstr_a(str));
2516
2517 /* The format of the GLSL version string is "major.minor[.release] [vendor info]". */
2518 sscanf(str, "%u.%u", &major, &minor);
2519 gl_info->glsl_version = MAKEDWORD_VERSION(major, minor);
2520 }
2521 if (gl_info->supported[NV_LIGHT_MAX_EXPONENT])
2522 {
2523 glGetFloatv(GL_MAX_SHININESS_NV, &gl_info->limits.shininess);
2524 }
2525 else
2526 {
2527 gl_info->limits.shininess = 128.0f;
2528 }
2529 if (gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO])
2530 {
2531 /* If we have full NP2 texture support, disable
2532 * GL_ARB_texture_rectangle because we will never use it.
2533 * This saves a few redundant glDisable calls. */
2534 gl_info->supported[ARB_TEXTURE_RECTANGLE] = FALSE;
2535 }
2536 if (gl_info->supported[ATI_FRAGMENT_SHADER])
2537 {
2538 /* Disable NV_register_combiners and fragment shader if this is supported.
2539 * generally the NV extensions are preferred over the ATI ones, and this
2540 * extension is disabled if register_combiners and texture_shader2 are both
2541 * supported. So we reach this place only if we have incomplete NV dxlevel 8
2542 * fragment processing support. */
2543 gl_info->supported[NV_REGISTER_COMBINERS] = FALSE;
2544 gl_info->supported[NV_REGISTER_COMBINERS2] = FALSE;
2545 gl_info->supported[NV_TEXTURE_SHADER] = FALSE;
2546 gl_info->supported[NV_TEXTURE_SHADER2] = FALSE;
2547 }
2548 if (gl_info->supported[NV_HALF_FLOAT])
2549 {
2550 /* GL_ARB_half_float_vertex is a subset of GL_NV_half_float. */
2551 gl_info->supported[ARB_HALF_FLOAT_VERTEX] = TRUE;
2552 }
2553 if (gl_info->supported[ARB_POINT_SPRITE])
2554 {
2555 gl_info->limits.point_sprite_units = gl_info->limits.textures;
2556 }
2557 else
2558 {
2559 gl_info->limits.point_sprite_units = 0;
2560 }
2561 checkGLcall("extension detection");
2562
2563 LEAVE_GL();
2564
2565 adapter->fragment_pipe = select_fragment_implementation(adapter);
2566 adapter->shader_backend = select_shader_backend(adapter);
2567 adapter->blitter = select_blit_implementation(adapter);
2568
2569 adapter->fragment_pipe->get_caps(gl_info, &fragment_caps);
2570 gl_info->limits.texture_stages = fragment_caps.MaxTextureBlendStages;
2571 TRACE_(d3d_caps)("Max texture stages: %u.\n", gl_info->limits.texture_stages);
2572
2573 /* In some cases the number of texture stages can be larger than the number
2574 * of samplers. The GF4 for example can use only 2 samplers (no fragment
2575 * shaders), but 8 texture stages (register combiners). */
2576 gl_info->limits.sampler_stages = max(gl_info->limits.fragment_samplers, gl_info->limits.texture_stages);
2577
2578 if (gl_info->supported[ARB_FRAMEBUFFER_OBJECT])
2579 {
2580 gl_info->fbo_ops.glIsRenderbuffer = gl_info->glIsRenderbuffer;
2581 gl_info->fbo_ops.glBindRenderbuffer = gl_info->glBindRenderbuffer;
2582 gl_info->fbo_ops.glDeleteRenderbuffers = gl_info->glDeleteRenderbuffers;
2583 gl_info->fbo_ops.glGenRenderbuffers = gl_info->glGenRenderbuffers;
2584 gl_info->fbo_ops.glRenderbufferStorage = gl_info->glRenderbufferStorage;
2585 gl_info->fbo_ops.glRenderbufferStorageMultisample = gl_info->glRenderbufferStorageMultisample;
2586 gl_info->fbo_ops.glGetRenderbufferParameteriv = gl_info->glGetRenderbufferParameteriv;
2587 gl_info->fbo_ops.glIsFramebuffer = gl_info->glIsFramebuffer;
2588 gl_info->fbo_ops.glBindFramebuffer = gl_info->glBindFramebuffer;
2589 gl_info->fbo_ops.glDeleteFramebuffers = gl_info->glDeleteFramebuffers;
2590 gl_info->fbo_ops.glGenFramebuffers = gl_info->glGenFramebuffers;
2591 gl_info->fbo_ops.glCheckFramebufferStatus = gl_info->glCheckFramebufferStatus;
2592 gl_info->fbo_ops.glFramebufferTexture1D = gl_info->glFramebufferTexture1D;
2593 gl_info->fbo_ops.glFramebufferTexture2D = gl_info->glFramebufferTexture2D;
2594 gl_info->fbo_ops.glFramebufferTexture3D = gl_info->glFramebufferTexture3D;
2595 gl_info->fbo_ops.glFramebufferRenderbuffer = gl_info->glFramebufferRenderbuffer;
2596 gl_info->fbo_ops.glGetFramebufferAttachmentParameteriv = gl_info->glGetFramebufferAttachmentParameteriv;
2597 gl_info->fbo_ops.glBlitFramebuffer = gl_info->glBlitFramebuffer;
2598 gl_info->fbo_ops.glGenerateMipmap = gl_info->glGenerateMipmap;
2599 }
2600 else
2601 {
2602 if (gl_info->supported[EXT_FRAMEBUFFER_OBJECT])
2603 {
2604 gl_info->fbo_ops.glIsRenderbuffer = gl_info->glIsRenderbufferEXT;
2605 gl_info->fbo_ops.glBindRenderbuffer = gl_info->glBindRenderbufferEXT;
2606 gl_info->fbo_ops.glDeleteRenderbuffers = gl_info->glDeleteRenderbuffersEXT;
2607 gl_info->fbo_ops.glGenRenderbuffers = gl_info->glGenRenderbuffersEXT;
2608 gl_info->fbo_ops.glRenderbufferStorage = gl_info->glRenderbufferStorageEXT;
2609 gl_info->fbo_ops.glGetRenderbufferParameteriv = gl_info->glGetRenderbufferParameterivEXT;
2610 gl_info->fbo_ops.glIsFramebuffer = gl_info->glIsFramebufferEXT;
2611 gl_info->fbo_ops.glBindFramebuffer = gl_info->glBindFramebufferEXT;
2612 gl_info->fbo_ops.glDeleteFramebuffers = gl_info->glDeleteFramebuffersEXT;
2613 gl_info->fbo_ops.glGenFramebuffers = gl_info->glGenFramebuffersEXT;
2614 gl_info->fbo_ops.glCheckFramebufferStatus = gl_info->glCheckFramebufferStatusEXT;
2615 gl_info->fbo_ops.glFramebufferTexture1D = gl_info->glFramebufferTexture1DEXT;
2616 gl_info->fbo_ops.glFramebufferTexture2D = gl_info->glFramebufferTexture2DEXT;
2617 gl_info->fbo_ops.glFramebufferTexture3D = gl_info->glFramebufferTexture3DEXT;
2618 gl_info->fbo_ops.glFramebufferRenderbuffer = gl_info->glFramebufferRenderbufferEXT;
2619 gl_info->fbo_ops.glGetFramebufferAttachmentParameteriv = gl_info->glGetFramebufferAttachmentParameterivEXT;
2620 gl_info->fbo_ops.glGenerateMipmap = gl_info->glGenerateMipmapEXT;
2621 }
2622 else if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
2623 {
2624 WARN_(d3d_caps)("Framebuffer objects not supported, falling back to backbuffer offscreen rendering mode.\n");
2625 wined3d_settings.offscreen_rendering_mode = ORM_BACKBUFFER;
2626 }
2627 if (gl_info->supported[EXT_FRAMEBUFFER_BLIT])
2628 {
2629 gl_info->fbo_ops.glBlitFramebuffer = gl_info->glBlitFramebufferEXT;
2630 }
2631 if (gl_info->supported[EXT_FRAMEBUFFER_MULTISAMPLE])
2632 {
2633 gl_info->fbo_ops.glRenderbufferStorageMultisample = gl_info->glRenderbufferStorageMultisampleEXT;
2634 }
2635 }
2636
2637 /* MRTs are currently only supported when FBOs are used. */
2638 if (wined3d_settings.offscreen_rendering_mode != ORM_FBO)
2639 {
2640 gl_info->limits.buffers = 1;
2641 }
2642
2643 gl_vendor = wined3d_guess_gl_vendor(gl_info, gl_vendor_str, gl_renderer_str);
2644 card_vendor = wined3d_guess_card_vendor(gl_vendor_str, gl_renderer_str);
2645 TRACE_(d3d_caps)("found GL_VENDOR (%s)->(0x%04x/0x%04x)\n", debugstr_a(gl_vendor_str), gl_vendor, card_vendor);
2646
2647 device = wined3d_guess_card(gl_info, gl_renderer_str, &gl_vendor, &card_vendor, &vidmem);
2648 TRACE_(d3d_caps)("FOUND (fake) card: 0x%x (vendor id), 0x%x (device id)\n", card_vendor, device);
2649
2650 /* If we have an estimate use it, else default to 64MB; */
2651 if(vidmem)
2652 gl_info->vidmem = vidmem*1024*1024; /* convert from MBs to bytes */
2653 else
2654 gl_info->vidmem = WINE_DEFAULT_VIDMEM;
2655
2656 gl_info->wrap_lookup[WINED3DTADDRESS_WRAP - WINED3DTADDRESS_WRAP] = GL_REPEAT;
2657 gl_info->wrap_lookup[WINED3DTADDRESS_MIRROR - WINED3DTADDRESS_WRAP] =
2658 gl_info->supported[ARB_TEXTURE_MIRRORED_REPEAT] ? GL_MIRRORED_REPEAT_ARB : GL_REPEAT;
2659 gl_info->wrap_lookup[WINED3DTADDRESS_CLAMP - WINED3DTADDRESS_WRAP] = GL_CLAMP_TO_EDGE;
2660 gl_info->wrap_lookup[WINED3DTADDRESS_BORDER - WINED3DTADDRESS_WRAP] =
2661 gl_info->supported[ARB_TEXTURE_BORDER_CLAMP] ? GL_CLAMP_TO_BORDER_ARB : GL_REPEAT;
2662 gl_info->wrap_lookup[WINED3DTADDRESS_MIRRORONCE - WINED3DTADDRESS_WRAP] =
2663 gl_info->supported[ATI_TEXTURE_MIRROR_ONCE] ? GL_MIRROR_CLAMP_TO_EDGE_ATI : GL_REPEAT;
2664
2665 /* Make sure there's an active HDC else the WGL extensions will fail */
2666 hdc = pwglGetCurrentDC();
2667 if (hdc) {
2668 /* Not all GL drivers might offer WGL extensions e.g. VirtualBox */
2669 if(GL_EXTCALL(wglGetExtensionsStringARB))
2670 WGL_Extensions = GL_EXTCALL(wglGetExtensionsStringARB(hdc));
2671
2672 if (NULL == WGL_Extensions) {
2673 ERR(" WGL_Extensions returns NULL\n");
2674 } else {
2675 TRACE_(d3d_caps)("WGL_Extensions reported:\n");
2676 while (*WGL_Extensions != 0x00) {
2677 const char *Start;
2678 char ThisExtn[256];
2679
2680 while (isspace(*WGL_Extensions)) WGL_Extensions++;
2681 Start = WGL_Extensions;
2682 while (!isspace(*WGL_Extensions) && *WGL_Extensions != 0x00) {
2683 WGL_Extensions++;
2684 }
2685
2686 len = WGL_Extensions - Start;
2687 if (len == 0 || len >= sizeof(ThisExtn))
2688 continue;
2689
2690 memcpy(ThisExtn, Start, len);
2691 ThisExtn[len] = '\0';
2692 TRACE_(d3d_caps)("- %s\n", debugstr_a(ThisExtn));
2693
2694 if (!strcmp(ThisExtn, "WGL_ARB_pixel_format")) {
2695 gl_info->supported[WGL_ARB_PIXEL_FORMAT] = TRUE;
2696 TRACE_(d3d_caps)("FOUND: WGL_ARB_pixel_format support\n");
2697 }
2698 if (!strcmp(ThisExtn, "WGL_WINE_pixel_format_passthrough")) {
2699 gl_info->supported[WGL_WINE_PIXEL_FORMAT_PASSTHROUGH] = TRUE;
2700 TRACE_(d3d_caps)("FOUND: WGL_WINE_pixel_format_passthrough support\n");
2701 }
2702 }
2703 }
2704 }
2705
2706 fixup_extensions(gl_info, gl_renderer_str, gl_vendor, card_vendor, device);
2707 init_driver_info(driver_info, card_vendor, device);
2708 add_gl_compat_wrappers(gl_info);
2709
2710 return TRUE;
2711}
2712
2713/**********************************************************
2714 * IWineD3D implementation follows
2715 **********************************************************/
2716
2717static UINT WINAPI IWineD3DImpl_GetAdapterCount (IWineD3D *iface) {
2718 IWineD3DImpl *This = (IWineD3DImpl *)iface;
2719
2720 TRACE_(d3d_caps)("(%p): Reporting %u adapters\n", This, This->adapter_count);
2721
2722 return This->adapter_count;
2723}
2724
2725static HRESULT WINAPI IWineD3DImpl_RegisterSoftwareDevice(IWineD3D *iface, void *init_function)
2726{
2727 FIXME("iface %p, init_function %p stub!\n", iface, init_function);
2728
2729 return WINED3D_OK;
2730}
2731
2732static HMONITOR WINAPI IWineD3DImpl_GetAdapterMonitor(IWineD3D *iface, UINT Adapter) {
2733 IWineD3DImpl *This = (IWineD3DImpl *)iface;
2734
2735 TRACE_(d3d_caps)("(%p)->(%d)\n", This, Adapter);
2736
2737 if (Adapter >= IWineD3DImpl_GetAdapterCount(iface)) {
2738 return NULL;
2739 }
2740
2741 return MonitorFromPoint(This->adapters[Adapter].monitorPoint, MONITOR_DEFAULTTOPRIMARY);
2742}
2743
2744/* FIXME: GetAdapterModeCount and EnumAdapterModes currently only returns modes
2745 of the same bpp but different resolutions */
2746
2747/* Note: dx9 supplies a format. Calls from d3d8 supply WINED3DFMT_UNKNOWN */
2748static UINT WINAPI IWineD3DImpl_GetAdapterModeCount(IWineD3D *iface, UINT Adapter, WINED3DFORMAT Format) {
2749 IWineD3DImpl *This = (IWineD3DImpl *)iface;
2750 TRACE_(d3d_caps)("(%p}->(Adapter: %d, Format: %s)\n", This, Adapter, debug_d3dformat(Format));
2751
2752 if (Adapter >= IWineD3D_GetAdapterCount(iface)) {
2753 return 0;
2754 }
2755
2756 /* TODO: Store modes per adapter and read it from the adapter structure */
2757 if (Adapter == 0) { /* Display */
2758 const struct wined3d_format_desc *format_desc = getFormatDescEntry(Format, &This->adapters[Adapter].gl_info);
2759 UINT format_bits = format_desc->byte_count * CHAR_BIT;
2760 unsigned int i = 0;
2761 unsigned int j = 0;
2762 DEVMODEW mode;
2763
2764 memset(&mode, 0, sizeof(mode));
2765 mode.dmSize = sizeof(mode);
2766
2767 while (EnumDisplaySettingsExW(NULL, j, &mode, 0))
2768 {
2769 ++j;
2770
2771 if (Format == WINED3DFMT_UNKNOWN)
2772 {
2773 /* This is for D3D8, do not enumerate P8 here */
2774 if (mode.dmBitsPerPel == 32 || mode.dmBitsPerPel == 16) ++i;
2775 }
2776 else if (mode.dmBitsPerPel == format_bits)
2777 {
2778 ++i;
2779 }
2780 }
2781
2782 TRACE_(d3d_caps)("(%p}->(Adapter: %d) => %d (out of %d)\n", This, Adapter, i, j);
2783 return i;
2784 } else {
2785 FIXME_(d3d_caps)("Adapter not primary display\n");
2786 }
2787 return 0;
2788}
2789
2790/* Note: dx9 supplies a format. Calls from d3d8 supply WINED3DFMT_UNKNOWN */
2791static HRESULT WINAPI IWineD3DImpl_EnumAdapterModes(IWineD3D *iface, UINT Adapter, WINED3DFORMAT Format, UINT Mode, WINED3DDISPLAYMODE* pMode) {
2792 IWineD3DImpl *This = (IWineD3DImpl *)iface;
2793 TRACE_(d3d_caps)("(%p}->(Adapter:%d, mode:%d, pMode:%p, format:%s)\n", This, Adapter, Mode, pMode, debug_d3dformat(Format));
2794
2795 /* Validate the parameters as much as possible */
2796 if (NULL == pMode ||
2797 Adapter >= IWineD3DImpl_GetAdapterCount(iface) ||
2798 Mode >= IWineD3DImpl_GetAdapterModeCount(iface, Adapter, Format)) {
2799 return WINED3DERR_INVALIDCALL;
2800 }
2801
2802 /* TODO: Store modes per adapter and read it from the adapter structure */
2803 if (Adapter == 0)
2804 {
2805 const struct wined3d_format_desc *format_desc = getFormatDescEntry(Format, &This->adapters[Adapter].gl_info);
2806 UINT format_bits = format_desc->byte_count * CHAR_BIT;
2807 DEVMODEW DevModeW;
2808 int ModeIdx = 0;
2809 UINT i = 0;
2810 int j = 0;
2811
2812 ZeroMemory(&DevModeW, sizeof(DevModeW));
2813 DevModeW.dmSize = sizeof(DevModeW);
2814
2815 /* If we are filtering to a specific format (D3D9), then need to skip
2816 all unrelated modes, but if mode is irrelevant (D3D8), then we can
2817 just count through the ones with valid bit depths */
2818 while ((i<=Mode) && EnumDisplaySettingsExW(NULL, j++, &DevModeW, 0))
2819 {
2820 if (Format == WINED3DFMT_UNKNOWN)
2821 {
2822 /* This is for D3D8, do not enumerate P8 here */
2823 if (DevModeW.dmBitsPerPel == 32 || DevModeW.dmBitsPerPel == 16) ++i;
2824 }
2825 else if (DevModeW.dmBitsPerPel == format_bits)
2826 {
2827 ++i;
2828 }
2829 }
2830
2831 if (i == 0) {
2832 TRACE_(d3d_caps)("No modes found for format (%x - %s)\n", Format, debug_d3dformat(Format));
2833 return WINED3DERR_INVALIDCALL;
2834 }
2835 ModeIdx = j - 1;
2836
2837 /* Now get the display mode via the calculated index */
2838 if (EnumDisplaySettingsExW(NULL, ModeIdx, &DevModeW, 0)) {
2839 pMode->Width = DevModeW.dmPelsWidth;
2840 pMode->Height = DevModeW.dmPelsHeight;
2841 pMode->RefreshRate = DEFAULT_REFRESH_RATE;
2842 if (DevModeW.dmFields & DM_DISPLAYFREQUENCY)
2843 pMode->RefreshRate = DevModeW.dmDisplayFrequency;
2844
2845 if (Format == WINED3DFMT_UNKNOWN) {
2846 pMode->Format = pixelformat_for_depth(DevModeW.dmBitsPerPel);
2847 } else {
2848 pMode->Format = Format;
2849 }
2850 } else {
2851 TRACE_(d3d_caps)("Requested mode out of range %d\n", Mode);
2852 return WINED3DERR_INVALIDCALL;
2853 }
2854
2855 TRACE_(d3d_caps)("W %d H %d rr %d fmt (%x - %s) bpp %u\n", pMode->Width, pMode->Height,
2856 pMode->RefreshRate, pMode->Format, debug_d3dformat(pMode->Format),
2857 DevModeW.dmBitsPerPel);
2858
2859 }
2860 else
2861 {
2862 FIXME_(d3d_caps)("Adapter not primary display\n");
2863 }
2864
2865 return WINED3D_OK;
2866}
2867
2868static HRESULT WINAPI IWineD3DImpl_GetAdapterDisplayMode(IWineD3D *iface, UINT Adapter, WINED3DDISPLAYMODE *pMode)
2869{
2870 TRACE("iface %p, adapter_idx %u, display_mode %p.\n", iface, Adapter, pMode);
2871
2872 if (NULL == pMode ||
2873 Adapter >= IWineD3D_GetAdapterCount(iface)) {
2874 return WINED3DERR_INVALIDCALL;
2875 }
2876
2877 if (Adapter == 0) { /* Display */
2878 int bpp = 0;
2879 DEVMODEW DevModeW;
2880
2881 ZeroMemory(&DevModeW, sizeof(DevModeW));
2882 DevModeW.dmSize = sizeof(DevModeW);
2883
2884 EnumDisplaySettingsExW(NULL, ENUM_CURRENT_SETTINGS, &DevModeW, 0);
2885 pMode->Width = DevModeW.dmPelsWidth;
2886 pMode->Height = DevModeW.dmPelsHeight;
2887 bpp = DevModeW.dmBitsPerPel;
2888 pMode->RefreshRate = DEFAULT_REFRESH_RATE;
2889 if (DevModeW.dmFields&DM_DISPLAYFREQUENCY)
2890 {
2891 pMode->RefreshRate = DevModeW.dmDisplayFrequency;
2892 }
2893
2894 pMode->Format = pixelformat_for_depth(bpp);
2895 } else {
2896 FIXME_(d3d_caps)("Adapter not primary display\n");
2897 }
2898
2899 TRACE_(d3d_caps)("returning w:%d, h:%d, ref:%d, fmt:%s\n", pMode->Width,
2900 pMode->Height, pMode->RefreshRate, debug_d3dformat(pMode->Format));
2901 return WINED3D_OK;
2902}
2903
2904static HRESULT WINAPI IWineD3DImpl_GetAdapterDisplayModeEx(IWineD3D *iface,
2905 UINT Adapter, WINED3DDISPLAYMODEEX *pMode, WINED3DDISPLAYROTATION *pRotation)
2906{
2907 TRACE("iface %p, adapter_idx %u, display_mode %p, display_rotation %p.\n", iface, Adapter, pMode, pRotation);
2908
2909 if (pMode==NULL && pRotation==NULL)
2910 {
2911 return WINED3D_OK;
2912 }
2913
2914 if (pMode && pMode->Size != sizeof(WINED3DDISPLAYMODEEX))
2915 {
2916 WARN("Invalid mode->Size %u expected %u", pMode->Size, sizeof(WINED3DDISPLAYMODEEX));
2917 return WINED3DERR_INVALIDCALL;
2918 }
2919
2920 if (Adapter >= IWineD3D_GetAdapterCount(iface))
2921 {
2922 return WINED3DERR_INVALIDCALL;
2923 }
2924
2925 if (Adapter == 0) { /* Display */
2926 int bpp = 0;
2927 DEVMODEW DevModeW;
2928
2929 ZeroMemory(&DevModeW, sizeof(DevModeW));
2930 DevModeW.dmSize = sizeof(DevModeW);
2931
2932 EnumDisplaySettingsExW(NULL, ENUM_CURRENT_SETTINGS, &DevModeW, 0);
2933
2934 if (pMode)
2935 {
2936 pMode->Width = DevModeW.dmPelsWidth;
2937 pMode->Height = DevModeW.dmPelsHeight;
2938 bpp = DevModeW.dmBitsPerPel;
2939 pMode->RefreshRate = DEFAULT_REFRESH_RATE;
2940 if (DevModeW.dmFields&DM_DISPLAYFREQUENCY)
2941 {
2942 pMode->RefreshRate = DevModeW.dmDisplayFrequency;
2943 }
2944
2945 pMode->Format = pixelformat_for_depth(bpp);
2946
2947 pMode->ScanLineOrdering = WINED3DSCANLINEORDERING_PROGRESSIVE;
2948 if (DevModeW.dmFields&DM_DISPLAYFLAGS)
2949 {
2950#if 0 //defined(RT_ARCH_AMD64) && !defined(VBOX_WITH_WDDM)
2951# ifndef DM_INTERLACED
2952# define DM_INTERLACED 0x00000002
2953# endif
2954 if (DevModeW.dmDisplayFlags&DM_INTERLACED)
2955#else
2956 if (DevModeW.u2.dmDisplayFlags&DM_INTERLACED)
2957#endif
2958 {
2959 pMode->ScanLineOrdering = WINED3DSCANLINEORDERING_INTERLACED;
2960 }
2961 }
2962 }
2963
2964 if (pRotation)
2965 {
2966 *pRotation = WINED3DDISPLAYROTATION_IDENTITY;
2967 if (DevModeW.dmFields&DM_DISPLAYORIENTATION)
2968 {
2969#if 0 //defined(RT_ARCH_AMD64) && !defined(VBOX_WITH_WDDM)
2970 switch (DevModeW.dmDisplayOrientation)
2971#else
2972 switch (DevModeW.u.s2.dmDisplayOrientation)
2973#endif
2974 {
2975 case DMDO_DEFAULT:
2976 *pRotation = WINED3DDISPLAYROTATION_IDENTITY;
2977 break;
2978 case DMDO_90:
2979 *pRotation = WINED3DDISPLAYROTATION_90;
2980 break;
2981 case DMDO_180:
2982 *pRotation = WINED3DDISPLAYROTATION_180;
2983 break;
2984 case DMDO_270:
2985 *pRotation = WINED3DDISPLAYROTATION_270;
2986 break;
2987 default:
2988#if 0 //defined(RT_ARCH_AMD64) && !defined(VBOX_WITH_WDDM)
2989 WARN("Unexpected display orientation %#x", DevModeW.dmDisplayOrientation);
2990#else
2991 WARN("Unexpected display orientation %#x", DevModeW.u.s2.dmDisplayOrientation);
2992#endif
2993 break;
2994 }
2995 }
2996 }
2997 } else {
2998 FIXME_(d3d_caps)("Adapter not primary display\n");
2999 }
3000
3001 return WINED3D_OK;
3002}
3003
3004/* NOTE: due to structure differences between dx8 and dx9 D3DADAPTER_IDENTIFIER,
3005 and fields being inserted in the middle, a new structure is used in place */
3006static HRESULT WINAPI IWineD3DImpl_GetAdapterIdentifier(IWineD3D *iface, UINT Adapter, DWORD Flags,
3007 WINED3DADAPTER_IDENTIFIER* pIdentifier) {
3008 IWineD3DImpl *This = (IWineD3DImpl *)iface;
3009 struct wined3d_adapter *adapter;
3010 size_t len;
3011
3012 TRACE_(d3d_caps)("(%p}->(Adapter: %d, Flags: %x, pId=%p)\n", This, Adapter, Flags, pIdentifier);
3013
3014 if (Adapter >= IWineD3D_GetAdapterCount(iface)) {
3015 return WINED3DERR_INVALIDCALL;
3016 }
3017
3018 adapter = &This->adapters[Adapter];
3019
3020 /* Return the information requested */
3021 TRACE_(d3d_caps)("device/Vendor Name and Version detection using FillGLCaps\n");
3022
3023 if (pIdentifier->driver_size)
3024 {
3025 const char *name = adapter->driver_info.name;
3026 len = min(strlen(name), pIdentifier->driver_size - 1);
3027 memcpy(pIdentifier->driver, name, len);
3028 pIdentifier->driver[len] = '\0';
3029 }
3030
3031 if (pIdentifier->description_size)
3032 {
3033 const char *description = adapter->driver_info.description;
3034 len = min(strlen(description), pIdentifier->description_size - 1);
3035 memcpy(pIdentifier->description, description, len);
3036 pIdentifier->description[len] = '\0';
3037 }
3038
3039 /* Note that d3d8 doesn't supply a device name. */
3040 if (pIdentifier->device_name_size)
3041 {
3042 static const char *device_name = "\\\\.\\DISPLAY1"; /* FIXME: May depend on desktop? */
3043
3044 len = strlen(device_name);
3045 if (len >= pIdentifier->device_name_size)
3046 {
3047 ERR("Device name size too small.\n");
3048 return WINED3DERR_INVALIDCALL;
3049 }
3050
3051 memcpy(pIdentifier->device_name, device_name, len);
3052 pIdentifier->device_name[len] = '\0';
3053 }
3054
3055 pIdentifier->driver_version.u.HighPart = adapter->driver_info.version_high;
3056 pIdentifier->driver_version.u.LowPart = adapter->driver_info.version_low;
3057 pIdentifier->vendor_id = adapter->driver_info.vendor;
3058 pIdentifier->device_id = adapter->driver_info.device;
3059 pIdentifier->subsystem_id = 0;
3060 pIdentifier->revision = 0;
3061 memcpy(&pIdentifier->device_identifier, &IID_D3DDEVICE_D3DUID, sizeof(pIdentifier->device_identifier));
3062 pIdentifier->whql_level = (Flags & WINED3DENUM_NO_WHQL_LEVEL) ? 0 : 1;
3063 memcpy(&pIdentifier->adapter_luid, &adapter->luid, sizeof(pIdentifier->adapter_luid));
3064 pIdentifier->video_memory = adapter->TextureRam;
3065
3066 return WINED3D_OK;
3067}
3068
3069static BOOL IWineD3DImpl_IsPixelFormatCompatibleWithRenderFmt(const struct wined3d_gl_info *gl_info,
3070 const WineD3D_PixelFormat *cfg, const struct wined3d_format_desc *format_desc)
3071{
3072 short redSize, greenSize, blueSize, alphaSize, colorBits;
3073
3074 if(!cfg)
3075 return FALSE;
3076
3077 /* Float formats need FBOs. If FBOs are used this function isn't called */
3078 if (format_desc->Flags & WINED3DFMT_FLAG_FLOAT) return FALSE;
3079
3080 if(cfg->iPixelType == WGL_TYPE_RGBA_ARB) { /* Integer RGBA formats */
3081 if (!getColorBits(format_desc, &redSize, &greenSize, &blueSize, &alphaSize, &colorBits))
3082 {
3083 ERR("Unable to check compatibility for Format=%s\n", debug_d3dformat(format_desc->format));
3084 return FALSE;
3085 }
3086
3087 if(cfg->redSize < redSize)
3088 return FALSE;
3089
3090 if(cfg->greenSize < greenSize)
3091 return FALSE;
3092
3093 if(cfg->blueSize < blueSize)
3094 return FALSE;
3095
3096 if(cfg->alphaSize < alphaSize)
3097 return FALSE;
3098
3099 return TRUE;
3100 }
3101
3102 /* Probably a RGBA_float or color index mode */
3103 return FALSE;
3104}
3105
3106static BOOL IWineD3DImpl_IsPixelFormatCompatibleWithDepthFmt(const struct wined3d_gl_info *gl_info,
3107 const WineD3D_PixelFormat *cfg, const struct wined3d_format_desc *format_desc)
3108{
3109 short depthSize, stencilSize;
3110 BOOL lockable = FALSE;
3111
3112 if(!cfg)
3113 return FALSE;
3114
3115 if (!getDepthStencilBits(format_desc, &depthSize, &stencilSize))
3116 {
3117 ERR("Unable to check compatibility for Format=%s\n", debug_d3dformat(format_desc->format));
3118 return FALSE;
3119 }
3120
3121 /* Float formats need FBOs. If FBOs are used this function isn't called */
3122 if (format_desc->Flags & WINED3DFMT_FLAG_FLOAT) return FALSE;
3123
3124 if ((format_desc->format == WINED3DFMT_D16_LOCKABLE) || (format_desc->format == WINED3DFMT_D32_FLOAT))
3125 lockable = TRUE;
3126
3127 /* On some modern cards like the Geforce8/9 GLX doesn't offer some dephthstencil formats which D3D9 reports.
3128 * We can safely report 'compatible' formats (e.g. D24 can be used for D16) as long as we aren't dealing with
3129 * a lockable format. This also helps D3D <= 7 as they expect D16 which isn't offered without this on Geforce8 cards. */
3130 if(!(cfg->depthSize == depthSize || (!lockable && cfg->depthSize > depthSize)))
3131 return FALSE;
3132
3133 /* Some cards like Intel i915 ones only offer D24S8 but lots of games also need a format without stencil, so
3134 * allow more stencil bits than requested. */
3135 if(cfg->stencilSize < stencilSize)
3136 return FALSE;
3137
3138 return TRUE;
3139}
3140
3141static HRESULT WINAPI IWineD3DImpl_CheckDepthStencilMatch(IWineD3D *iface, UINT Adapter, WINED3DDEVTYPE DeviceType,
3142 WINED3DFORMAT AdapterFormat,
3143 WINED3DFORMAT RenderTargetFormat,
3144 WINED3DFORMAT DepthStencilFormat) {
3145 IWineD3DImpl *This = (IWineD3DImpl *)iface;
3146 int nCfgs;
3147 const WineD3D_PixelFormat *cfgs;
3148 const struct wined3d_adapter *adapter;
3149 const struct wined3d_format_desc *rt_format_desc;
3150 const struct wined3d_format_desc *ds_format_desc;
3151 int it;
3152
3153 WARN_(d3d_caps)("(%p)-> (STUB) (Adptr:%d, DevType:(%x,%s), AdptFmt:(%x,%s), RendrTgtFmt:(%x,%s), DepthStencilFmt:(%x,%s))\n",
3154 This, Adapter,
3155 DeviceType, debug_d3ddevicetype(DeviceType),
3156 AdapterFormat, debug_d3dformat(AdapterFormat),
3157 RenderTargetFormat, debug_d3dformat(RenderTargetFormat),
3158 DepthStencilFormat, debug_d3dformat(DepthStencilFormat));
3159
3160 if (Adapter >= IWineD3D_GetAdapterCount(iface)) {
3161 TRACE("(%p) Failed: Atapter (%u) higher than supported adapters (%u) returning WINED3DERR_INVALIDCALL\n", This, Adapter, IWineD3D_GetAdapterCount(iface));
3162 return WINED3DERR_INVALIDCALL;
3163 }
3164
3165 adapter = &This->adapters[Adapter];
3166 rt_format_desc = getFormatDescEntry(RenderTargetFormat, &adapter->gl_info);
3167 ds_format_desc = getFormatDescEntry(DepthStencilFormat, &adapter->gl_info);
3168 if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
3169 {
3170 if ((rt_format_desc->Flags & WINED3DFMT_FLAG_RENDERTARGET) &&
3171 (ds_format_desc->Flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL))) {
3172 TRACE_(d3d_caps)("(%p) : Formats matched\n", This);
3173 return WINED3D_OK;
3174 }
3175 }
3176 else
3177 {
3178 cfgs = adapter->cfgs;
3179 nCfgs = adapter->nCfgs;
3180 for (it = 0; it < nCfgs; ++it) {
3181 if (IWineD3DImpl_IsPixelFormatCompatibleWithRenderFmt(&adapter->gl_info, &cfgs[it], rt_format_desc))
3182 {
3183 if (IWineD3DImpl_IsPixelFormatCompatibleWithDepthFmt(&adapter->gl_info, &cfgs[it], ds_format_desc))
3184 {
3185 TRACE_(d3d_caps)("(%p) : Formats matched\n", This);
3186 return WINED3D_OK;
3187 }
3188 }
3189 }
3190 }
3191 WARN_(d3d_caps)("unsupported format pair: %s and %s\n", debug_d3dformat(RenderTargetFormat), debug_d3dformat(DepthStencilFormat));
3192
3193 return WINED3DERR_NOTAVAILABLE;
3194}
3195
3196static HRESULT WINAPI IWineD3DImpl_CheckDeviceMultiSampleType(IWineD3D *iface, UINT Adapter, WINED3DDEVTYPE DeviceType,
3197 WINED3DFORMAT SurfaceFormat, BOOL Windowed, WINED3DMULTISAMPLE_TYPE MultiSampleType, DWORD *pQualityLevels)
3198{
3199 IWineD3DImpl *This = (IWineD3DImpl *)iface;
3200 const struct wined3d_format_desc *glDesc;
3201 const struct wined3d_adapter *adapter;
3202
3203 TRACE_(d3d_caps)("(%p)-> (Adptr:%d, DevType:(%x,%s), SurfFmt:(%x,%s), Win?%d, MultiSamp:%x, pQual:%p)\n",
3204 This,
3205 Adapter,
3206 DeviceType, debug_d3ddevicetype(DeviceType),
3207 SurfaceFormat, debug_d3dformat(SurfaceFormat),
3208 Windowed,
3209 MultiSampleType,
3210 pQualityLevels);
3211
3212 if (Adapter >= IWineD3D_GetAdapterCount(iface)) {
3213 return WINED3DERR_INVALIDCALL;
3214 }
3215
3216 /* TODO: handle Windowed, add more quality levels */
3217
3218 if (WINED3DMULTISAMPLE_NONE == MultiSampleType) {
3219 if(pQualityLevels) *pQualityLevels = 1;
3220 return WINED3D_OK;
3221 }
3222
3223 /* By default multisampling is disabled right now as it causes issues
3224 * on some Nvidia driver versions and it doesn't work well in combination
3225 * with FBOs yet. */
3226 if(!wined3d_settings.allow_multisampling)
3227 return WINED3DERR_NOTAVAILABLE;
3228
3229 adapter = &This->adapters[Adapter];
3230 glDesc = getFormatDescEntry(SurfaceFormat, &adapter->gl_info);
3231 if (!glDesc) return WINED3DERR_INVALIDCALL;
3232
3233 if(glDesc->Flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL)) {
3234 int i, nCfgs;
3235 const WineD3D_PixelFormat *cfgs;
3236
3237 cfgs = adapter->cfgs;
3238 nCfgs = adapter->nCfgs;
3239 for(i=0; i<nCfgs; i++) {
3240 if(cfgs[i].numSamples != MultiSampleType)
3241 continue;
3242
3243 if (!IWineD3DImpl_IsPixelFormatCompatibleWithDepthFmt(&adapter->gl_info, &cfgs[i], glDesc))
3244 continue;
3245
3246 TRACE("Found iPixelFormat=%d to support MultiSampleType=%d for format %s\n", cfgs[i].iPixelFormat, MultiSampleType, debug_d3dformat(SurfaceFormat));
3247
3248 if(pQualityLevels)
3249 *pQualityLevels = 1; /* Guess at a value! */
3250 return WINED3D_OK;
3251 }
3252 }
3253 else if(glDesc->Flags & WINED3DFMT_FLAG_RENDERTARGET) {
3254 short redSize, greenSize, blueSize, alphaSize, colorBits;
3255 int i, nCfgs;
3256 const WineD3D_PixelFormat *cfgs;
3257
3258 if (!getColorBits(glDesc, &redSize, &greenSize, &blueSize, &alphaSize, &colorBits))
3259 {
3260 ERR("Unable to color bits for format %#x, can't check multisampling capability!\n", SurfaceFormat);
3261 return WINED3DERR_NOTAVAILABLE;
3262 }
3263
3264 cfgs = adapter->cfgs;
3265 nCfgs = adapter->nCfgs;
3266 for(i=0; i<nCfgs; i++) {
3267 if(cfgs[i].numSamples != MultiSampleType)
3268 continue;
3269 if(cfgs[i].redSize != redSize)
3270 continue;
3271 if(cfgs[i].greenSize != greenSize)
3272 continue;
3273 if(cfgs[i].blueSize != blueSize)
3274 continue;
3275 /* Not all drivers report alpha-less formats since they use 32-bit anyway, so accept alpha even if we didn't ask for it. */
3276 if(alphaSize && cfgs[i].alphaSize != alphaSize)
3277 continue;
3278 if(cfgs[i].colorSize != (glDesc->byte_count << 3))
3279 continue;
3280
3281 TRACE("Found iPixelFormat=%d to support MultiSampleType=%d for format %s\n", cfgs[i].iPixelFormat, MultiSampleType, debug_d3dformat(SurfaceFormat));
3282
3283 if(pQualityLevels)
3284 *pQualityLevels = 1; /* Guess at a value! */
3285 return WINED3D_OK;
3286 }
3287 }
3288 return WINED3DERR_NOTAVAILABLE;
3289}
3290
3291static HRESULT WINAPI IWineD3DImpl_CheckDeviceType(IWineD3D *iface, UINT Adapter, WINED3DDEVTYPE DeviceType,
3292 WINED3DFORMAT DisplayFormat, WINED3DFORMAT BackBufferFormat, BOOL Windowed)
3293{
3294 HRESULT hr = WINED3DERR_NOTAVAILABLE;
3295 UINT nmodes;
3296
3297 TRACE("iface %p, adapter_idx %u, device_type %s, display_format %s, backbuffer_format %s, windowed %#x.\n",
3298 iface, Adapter, debug_d3ddevicetype(DeviceType), debug_d3dformat(DisplayFormat),
3299 debug_d3dformat(BackBufferFormat), Windowed);
3300
3301 if (Adapter >= IWineD3D_GetAdapterCount(iface)) {
3302 WARN_(d3d_caps)("Adapter >= IWineD3D_GetAdapterCount(iface), returning WINED3DERR_INVALIDCALL\n");
3303 return WINED3DERR_INVALIDCALL;
3304 }
3305
3306 /* The task of this function is to check whether a certain display / backbuffer format
3307 * combination is available on the given adapter. In fullscreen mode microsoft specified
3308 * that the display format shouldn't provide alpha and that ignoring alpha the backbuffer
3309 * and display format should match exactly.
3310 * In windowed mode format conversion can occur and this depends on the driver. When format
3311 * conversion is done, this function should nevertheless fail and applications need to use
3312 * CheckDeviceFormatConversion.
3313 * At the moment we assume that fullscreen and windowed have the same capabilities */
3314
3315 /* There are only 4 display formats */
3316 if (!(DisplayFormat == WINED3DFMT_B5G6R5_UNORM
3317 || DisplayFormat == WINED3DFMT_B5G5R5X1_UNORM
3318 || DisplayFormat == WINED3DFMT_B8G8R8X8_UNORM
3319 || DisplayFormat == WINED3DFMT_B10G10R10A2_UNORM))
3320 {
3321 TRACE_(d3d_caps)("Format %s unsupported as display format\n", debug_d3dformat(DisplayFormat));
3322 return WINED3DERR_NOTAVAILABLE;
3323 }
3324
3325 /* If the requested DisplayFormat is not available, don't continue */
3326 nmodes = IWineD3DImpl_GetAdapterModeCount(iface, Adapter, DisplayFormat);
3327 if(!nmodes) {
3328 TRACE_(d3d_caps)("No available modes for display format %s\n", debug_d3dformat(DisplayFormat));
3329 return WINED3DERR_NOTAVAILABLE;
3330 }
3331
3332 /* Windowed mode allows you to specify WINED3DFMT_UNKNOWN for the backbufferformat, it means 'reuse' the display format for the backbuffer */
3333 if(!Windowed && BackBufferFormat == WINED3DFMT_UNKNOWN) {
3334 TRACE_(d3d_caps)("BackBufferFormat WINED3FMT_UNKNOWN not available in Windowed mode\n");
3335 return WINED3DERR_NOTAVAILABLE;
3336 }
3337
3338 /* In FULLSCREEN mode R5G6B5 can only be mixed with backbuffer format R5G6B5 */
3339 if (DisplayFormat == WINED3DFMT_B5G6R5_UNORM && BackBufferFormat != WINED3DFMT_B5G6R5_UNORM)
3340 {
3341 TRACE_(d3d_caps)("Unsupported display/backbuffer format combination %s/%s\n", debug_d3dformat(DisplayFormat), debug_d3dformat(BackBufferFormat));
3342 return WINED3DERR_NOTAVAILABLE;
3343 }
3344
3345 /* In FULLSCREEN mode X1R5G5B5 can only be mixed with backbuffer format *1R5G5B5 */
3346 if (DisplayFormat == WINED3DFMT_B5G5R5X1_UNORM
3347 && !(BackBufferFormat == WINED3DFMT_B5G5R5X1_UNORM || BackBufferFormat == WINED3DFMT_B5G5R5A1_UNORM))
3348 {
3349 TRACE_(d3d_caps)("Unsupported display/backbuffer format combination %s/%s\n", debug_d3dformat(DisplayFormat), debug_d3dformat(BackBufferFormat));
3350 return WINED3DERR_NOTAVAILABLE;
3351 }
3352
3353 /* In FULLSCREEN mode X8R8G8B8 can only be mixed with backbuffer format *8R8G8B8 */
3354 if (DisplayFormat == WINED3DFMT_B8G8R8X8_UNORM
3355 && !(BackBufferFormat == WINED3DFMT_B8G8R8X8_UNORM || BackBufferFormat == WINED3DFMT_B8G8R8A8_UNORM))
3356 {
3357 TRACE_(d3d_caps)("Unsupported display/backbuffer format combination %s/%s\n", debug_d3dformat(DisplayFormat), debug_d3dformat(BackBufferFormat));
3358 return WINED3DERR_NOTAVAILABLE;
3359 }
3360
3361 /* A2R10G10B10 is only allowed in fullscreen mode and it can only be mixed with backbuffer format A2R10G10B10 */
3362 if (DisplayFormat == WINED3DFMT_B10G10R10A2_UNORM
3363 && (BackBufferFormat != WINED3DFMT_B10G10R10A2_UNORM || Windowed))
3364 {
3365 TRACE_(d3d_caps)("Unsupported display/backbuffer format combination %s/%s\n", debug_d3dformat(DisplayFormat), debug_d3dformat(BackBufferFormat));
3366 return WINED3DERR_NOTAVAILABLE;
3367 }
3368
3369 /* Use CheckDeviceFormat to see if the BackBufferFormat is usable with the given DisplayFormat */
3370 hr = IWineD3DImpl_CheckDeviceFormat(iface, Adapter, DeviceType, DisplayFormat, WINED3DUSAGE_RENDERTARGET, WINED3DRTYPE_SURFACE, BackBufferFormat, SURFACE_OPENGL);
3371 if(FAILED(hr))
3372 TRACE_(d3d_caps)("Unsupported display/backbuffer format combination %s/%s\n", debug_d3dformat(DisplayFormat), debug_d3dformat(BackBufferFormat));
3373
3374 return hr;
3375}
3376
3377
3378/* Check if we support bumpmapping for a format */
3379static BOOL CheckBumpMapCapability(struct wined3d_adapter *adapter,
3380 WINED3DDEVTYPE DeviceType, const struct wined3d_format_desc *format_desc)
3381{
3382 switch(format_desc->format)
3383 {
3384 case WINED3DFMT_R8G8_SNORM:
3385 case WINED3DFMT_R16G16_SNORM:
3386 case WINED3DFMT_R5G5_SNORM_L6_UNORM:
3387 case WINED3DFMT_R8G8_SNORM_L8X8_UNORM:
3388 case WINED3DFMT_R8G8B8A8_SNORM:
3389 /* Ask the fixed function pipeline implementation if it can deal
3390 * with the conversion. If we've got a GL extension giving native
3391 * support this will be an identity conversion. */
3392 if (adapter->fragment_pipe->color_fixup_supported(format_desc->color_fixup))
3393 {
3394 TRACE_(d3d_caps)("[OK]\n");
3395 return TRUE;
3396 }
3397 TRACE_(d3d_caps)("[FAILED]\n");
3398 return FALSE;
3399
3400 default:
3401 TRACE_(d3d_caps)("[FAILED]\n");
3402 return FALSE;
3403 }
3404}
3405
3406/* Check if the given DisplayFormat + DepthStencilFormat combination is valid for the Adapter */
3407static BOOL CheckDepthStencilCapability(struct wined3d_adapter *adapter,
3408 const struct wined3d_format_desc *display_format_desc, const struct wined3d_format_desc *ds_format_desc)
3409{
3410 int it=0;
3411
3412 /* Only allow depth/stencil formats */
3413 if (!(ds_format_desc->depth_size || ds_format_desc->stencil_size)) return FALSE;
3414
3415 if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
3416 {
3417 /* With FBOs WGL limitations do not apply, but the format needs to be FBO attachable */
3418 if (ds_format_desc->Flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL)) return TRUE;
3419 }
3420 else
3421 {
3422 /* Walk through all WGL pixel formats to find a match */
3423 for (it = 0; it < adapter->nCfgs; ++it)
3424 {
3425 WineD3D_PixelFormat *cfg = &adapter->cfgs[it];
3426 if (IWineD3DImpl_IsPixelFormatCompatibleWithRenderFmt(&adapter->gl_info, cfg, display_format_desc))
3427 {
3428 if (IWineD3DImpl_IsPixelFormatCompatibleWithDepthFmt(&adapter->gl_info, cfg, ds_format_desc))
3429 {
3430 return TRUE;
3431 }
3432 }
3433 }
3434 }
3435
3436 return FALSE;
3437}
3438
3439static BOOL CheckFilterCapability(struct wined3d_adapter *adapter, const struct wined3d_format_desc *format_desc)
3440{
3441 /* The flags entry of a format contains the filtering capability */
3442 if (format_desc->Flags & WINED3DFMT_FLAG_FILTERING) return TRUE;
3443
3444 return FALSE;
3445}
3446
3447/* Check the render target capabilities of a format */
3448static BOOL CheckRenderTargetCapability(struct wined3d_adapter *adapter,
3449 const struct wined3d_format_desc *adapter_format_desc, const struct wined3d_format_desc *check_format_desc)
3450{
3451 /* Filter out non-RT formats */
3452 if (!(check_format_desc->Flags & WINED3DFMT_FLAG_RENDERTARGET)) return FALSE;
3453 if(wined3d_settings.offscreen_rendering_mode == ORM_BACKBUFFER) {
3454 WineD3D_PixelFormat *cfgs = adapter->cfgs;
3455 int it;
3456 short AdapterRed, AdapterGreen, AdapterBlue, AdapterAlpha, AdapterTotalSize;
3457 short CheckRed, CheckGreen, CheckBlue, CheckAlpha, CheckTotalSize;
3458
3459 getColorBits(adapter_format_desc, &AdapterRed, &AdapterGreen, &AdapterBlue, &AdapterAlpha, &AdapterTotalSize);
3460 getColorBits(check_format_desc, &CheckRed, &CheckGreen, &CheckBlue, &CheckAlpha, &CheckTotalSize);
3461
3462 /* In backbuffer mode the front and backbuffer share the same WGL pixelformat.
3463 * The format must match in RGB, alpha is allowed to be different. (Only the backbuffer can have alpha) */
3464 if(!((AdapterRed == CheckRed) && (AdapterGreen == CheckGreen) && (AdapterBlue == CheckBlue))) {
3465 TRACE_(d3d_caps)("[FAILED]\n");
3466 return FALSE;
3467 }
3468
3469 /* Check if there is a WGL pixel format matching the requirements, the format should also be window
3470 * drawable (not offscreen; e.g. Nvidia offers R5G6B5 for pbuffers even when X is running at 24bit) */
3471 for (it = 0; it < adapter->nCfgs; ++it)
3472 {
3473 if (cfgs[it].windowDrawable && IWineD3DImpl_IsPixelFormatCompatibleWithRenderFmt(&adapter->gl_info,
3474 &cfgs[it], check_format_desc))
3475 {
3476 TRACE_(d3d_caps)("iPixelFormat=%d is compatible with CheckFormat=%s\n",
3477 cfgs[it].iPixelFormat, debug_d3dformat(check_format_desc->format));
3478 return TRUE;
3479 }
3480 }
3481 }
3482 else if(wined3d_settings.offscreen_rendering_mode == ORM_FBO)
3483 {
3484 /* For now return TRUE for FBOs until we have some proper checks.
3485 * Note that this function will only be called when the format is around for texturing. */
3486 return TRUE;
3487 }
3488 return FALSE;
3489}
3490
3491static BOOL CheckSrgbReadCapability(struct wined3d_adapter *adapter, const struct wined3d_format_desc *format_desc)
3492{
3493 const struct wined3d_gl_info *gl_info = &adapter->gl_info;
3494
3495 /* Check for supported sRGB formats (Texture loading and framebuffer) */
3496 if (!gl_info->supported[EXT_TEXTURE_SRGB])
3497 {
3498 TRACE_(d3d_caps)("[FAILED] GL_EXT_texture_sRGB not supported\n");
3499 return FALSE;
3500 }
3501
3502 switch (format_desc->format)
3503 {
3504 case WINED3DFMT_B8G8R8A8_UNORM:
3505 case WINED3DFMT_B8G8R8X8_UNORM:
3506 case WINED3DFMT_B4G4R4A4_UNORM:
3507 case WINED3DFMT_L8_UNORM:
3508 case WINED3DFMT_L8A8_UNORM:
3509 case WINED3DFMT_DXT1:
3510 case WINED3DFMT_DXT2:
3511 case WINED3DFMT_DXT3:
3512 case WINED3DFMT_DXT4:
3513 case WINED3DFMT_DXT5:
3514 TRACE_(d3d_caps)("[OK]\n");
3515 return TRUE;
3516
3517 default:
3518 TRACE_(d3d_caps)("[FAILED] Gamma texture format %s not supported.\n", debug_d3dformat(format_desc->format));
3519 return FALSE;
3520 }
3521 return FALSE;
3522}
3523
3524static BOOL CheckSrgbWriteCapability(struct wined3d_adapter *adapter,
3525 WINED3DDEVTYPE DeviceType, const struct wined3d_format_desc *format_desc)
3526{
3527 /* Only offer SRGB writing on X8R8G8B8/A8R8G8B8 when we use ARB or GLSL shaders as we are
3528 * doing the color fixup in shaders.
3529 * Note Windows drivers (at least on the Geforce 8800) also offer this on R5G6B5. */
3530 if ((format_desc->format == WINED3DFMT_B8G8R8X8_UNORM) || (format_desc->format == WINED3DFMT_B8G8R8A8_UNORM))
3531 {
3532 int vs_selected_mode;
3533 int ps_selected_mode;
3534 select_shader_mode(&adapter->gl_info, &ps_selected_mode, &vs_selected_mode);
3535
3536 if((ps_selected_mode == SHADER_ARB) || (ps_selected_mode == SHADER_GLSL)) {
3537 TRACE_(d3d_caps)("[OK]\n");
3538 return TRUE;
3539 }
3540 }
3541
3542 TRACE_(d3d_caps)("[FAILED] - no SRGB writing support on format=%s\n", debug_d3dformat(format_desc->format));
3543 return FALSE;
3544}
3545
3546/* Check if a format support blending in combination with pixel shaders */
3547static BOOL CheckPostPixelShaderBlendingCapability(struct wined3d_adapter *adapter,
3548 const struct wined3d_format_desc *format_desc)
3549{
3550 /* The flags entry of a format contains the post pixel shader blending capability */
3551 if (format_desc->Flags & WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING) return TRUE;
3552
3553 return FALSE;
3554}
3555
3556static BOOL CheckWrapAndMipCapability(struct wined3d_adapter *adapter, const struct wined3d_format_desc *format_desc)
3557{
3558 /* OpenGL supports mipmapping on all formats basically. Wrapping is unsupported,
3559 * but we have to report mipmapping so we cannot reject this flag. Tests show that
3560 * windows reports WRAPANDMIP on unfilterable surfaces as well, apparently to show
3561 * that wrapping is supported. The lack of filtering will sort out the mipmapping
3562 * capability anyway.
3563 *
3564 * For now lets report this on all formats, but in the future we may want to
3565 * restrict it to some should games need that
3566 */
3567 return TRUE;
3568}
3569
3570/* Check if a texture format is supported on the given adapter */
3571static BOOL CheckTextureCapability(struct wined3d_adapter *adapter,
3572 WINED3DDEVTYPE DeviceType, const struct wined3d_format_desc *format_desc)
3573{
3574 const struct wined3d_gl_info *gl_info = &adapter->gl_info;
3575
3576 switch (format_desc->format)
3577 {
3578 /*****
3579 * supported: RGB(A) formats
3580 */
3581 case WINED3DFMT_B8G8R8_UNORM: /* Enable for dx7, blacklisted for 8 and 9 above */
3582 case WINED3DFMT_B8G8R8A8_UNORM:
3583 case WINED3DFMT_B8G8R8X8_UNORM:
3584 case WINED3DFMT_B5G6R5_UNORM:
3585 case WINED3DFMT_B5G5R5X1_UNORM:
3586 case WINED3DFMT_B5G5R5A1_UNORM:
3587 case WINED3DFMT_B4G4R4A4_UNORM:
3588 case WINED3DFMT_A8_UNORM:
3589 case WINED3DFMT_B4G4R4X4_UNORM:
3590 case WINED3DFMT_R8G8B8A8_UNORM:
3591 case WINED3DFMT_R8G8B8X8_UNORM:
3592 case WINED3DFMT_B10G10R10A2_UNORM:
3593 case WINED3DFMT_R10G10B10A2_UNORM:
3594 case WINED3DFMT_R16G16_UNORM:
3595 TRACE_(d3d_caps)("[OK]\n");
3596 return TRUE;
3597
3598 case WINED3DFMT_B2G3R3_UNORM:
3599 TRACE_(d3d_caps)("[FAILED] - Not supported on Windows\n");
3600 return FALSE;
3601
3602 /*****
3603 * Not supported: Palettized
3604 * Only some Geforce/Voodoo3/G400 cards offer 8-bit textures in case of <=Direct3D7.
3605 * Since it is not widely available, don't offer it. Further no Windows driver offers
3606 * WINED3DFMT_P8_UINT_A8_NORM, so don't offer it either.
3607 */
3608 case WINED3DFMT_P8_UINT:
3609 case WINED3DFMT_P8_UINT_A8_UNORM:
3610 return FALSE;
3611
3612 /*****
3613 * Supported: (Alpha)-Luminance
3614 */
3615 case WINED3DFMT_L8_UNORM:
3616 case WINED3DFMT_L8A8_UNORM:
3617 case WINED3DFMT_L16_UNORM:
3618 TRACE_(d3d_caps)("[OK]\n");
3619 return TRUE;
3620
3621 /* Not supported on Windows, thus disabled */
3622 case WINED3DFMT_L4A4_UNORM:
3623 TRACE_(d3d_caps)("[FAILED] - not supported on windows\n");
3624 return FALSE;
3625
3626 /*****
3627 * Supported: Depth/Stencil formats
3628 */
3629 case WINED3DFMT_D16_LOCKABLE:
3630 case WINED3DFMT_D16_UNORM:
3631 case WINED3DFMT_S1_UINT_D15_UNORM:
3632 case WINED3DFMT_X8D24_UNORM:
3633 case WINED3DFMT_S4X4_UINT_D24_UNORM:
3634 case WINED3DFMT_D24_UNORM_S8_UINT:
3635 case WINED3DFMT_S8_UINT_D24_FLOAT:
3636 case WINED3DFMT_D32_UNORM:
3637 case WINED3DFMT_D32_FLOAT:
3638 return TRUE;
3639
3640 /*****
3641 * Not supported everywhere(depends on GL_ATI_envmap_bumpmap or
3642 * GL_NV_texture_shader). Emulated by shaders
3643 */
3644 case WINED3DFMT_R8G8_SNORM:
3645 case WINED3DFMT_R8G8_SNORM_L8X8_UNORM:
3646 case WINED3DFMT_R5G5_SNORM_L6_UNORM:
3647 case WINED3DFMT_R8G8B8A8_SNORM:
3648 case WINED3DFMT_R16G16_SNORM:
3649 /* Ask the shader backend if it can deal with the conversion. If
3650 * we've got a GL extension giving native support this will be an
3651 * identity conversion. */
3652 if (adapter->shader_backend->shader_color_fixup_supported(format_desc->color_fixup))
3653 {
3654 TRACE_(d3d_caps)("[OK]\n");
3655 return TRUE;
3656 }
3657 TRACE_(d3d_caps)("[FAILED]\n");
3658 return FALSE;
3659
3660 case WINED3DFMT_DXT1:
3661 case WINED3DFMT_DXT2:
3662 case WINED3DFMT_DXT3:
3663 case WINED3DFMT_DXT4:
3664 case WINED3DFMT_DXT5:
3665 if (gl_info->supported[EXT_TEXTURE_COMPRESSION_S3TC])
3666 {
3667 TRACE_(d3d_caps)("[OK]\n");
3668 return TRUE;
3669 }
3670 TRACE_(d3d_caps)("[FAILED]\n");
3671 return FALSE;
3672
3673
3674 /*****
3675 * Odd formats - not supported
3676 */
3677 case WINED3DFMT_VERTEXDATA:
3678 case WINED3DFMT_R16_UINT:
3679 case WINED3DFMT_R32_UINT:
3680 case WINED3DFMT_R16G16B16A16_SNORM:
3681 case WINED3DFMT_R10G10B10_SNORM_A2_UNORM:
3682 case WINED3DFMT_R10G11B11_SNORM:
3683 TRACE_(d3d_caps)("[FAILED]\n"); /* Enable when implemented */
3684 return FALSE;
3685
3686 /*****
3687 * WINED3DFMT_R8G8_SNORM_Cx: Not supported right now
3688 */
3689 case WINED3DFMT_R8G8_SNORM_Cx:
3690 TRACE_(d3d_caps)("[FAILED]\n"); /* Enable when implemented */
3691 return FALSE;
3692
3693 /* YUV formats */
3694 case WINED3DFMT_UYVY:
3695 case WINED3DFMT_YUY2:
3696 if (gl_info->supported[APPLE_YCBCR_422])
3697 {
3698 TRACE_(d3d_caps)("[OK]\n");
3699 return TRUE;
3700 }
3701 TRACE_(d3d_caps)("[FAILED]\n");
3702 return FALSE;
3703 case WINED3DFMT_YV12:
3704 TRACE_(d3d_caps)("[FAILED]\n");
3705 return FALSE;
3706
3707 /* Not supported */
3708 case WINED3DFMT_R16G16B16A16_UNORM:
3709 case WINED3DFMT_B2G3R3A8_UNORM:
3710 TRACE_(d3d_caps)("[FAILED]\n"); /* Enable when implemented */
3711 return FALSE;
3712
3713 /* Floating point formats */
3714 case WINED3DFMT_R16_FLOAT:
3715 case WINED3DFMT_R16G16_FLOAT:
3716 case WINED3DFMT_R16G16B16A16_FLOAT:
3717 if (gl_info->supported[ARB_TEXTURE_FLOAT] && gl_info->supported[ARB_HALF_FLOAT_PIXEL])
3718 {
3719 TRACE_(d3d_caps)("[OK]\n");
3720 return TRUE;
3721 }
3722 TRACE_(d3d_caps)("[FAILED]\n");
3723 return FALSE;
3724
3725 case WINED3DFMT_R32_FLOAT:
3726 case WINED3DFMT_R32G32_FLOAT:
3727 case WINED3DFMT_R32G32B32A32_FLOAT:
3728 if (gl_info->supported[ARB_TEXTURE_FLOAT])
3729 {
3730 TRACE_(d3d_caps)("[OK]\n");
3731 return TRUE;
3732 }
3733 TRACE_(d3d_caps)("[FAILED]\n");
3734 return FALSE;
3735
3736 /* ATI instancing hack: Although ATI cards do not support Shader Model 3.0, they support
3737 * instancing. To query if the card supports instancing CheckDeviceFormat with the special format
3738 * MAKEFOURCC('I','N','S','T') is used. Should a (broken) app check for this provide a proper return value.
3739 * We can do instancing with all shader versions, but we need vertex shaders.
3740 *
3741 * Additionally applications have to set the D3DRS_POINTSIZE render state to MAKEFOURCC('I','N','S','T') once
3742 * to enable instancing. WineD3D doesn't need that and just ignores it.
3743 *
3744 * With Shader Model 3.0 capable cards Instancing 'just works' in Windows.
3745 */
3746 case WINED3DFMT_INST:
3747 TRACE("ATI Instancing check hack\n");
3748 if (gl_info->supported[ARB_VERTEX_PROGRAM] || gl_info->supported[ARB_VERTEX_SHADER])
3749 {
3750 TRACE_(d3d_caps)("[OK]\n");
3751 return TRUE;
3752 }
3753 TRACE_(d3d_caps)("[FAILED]\n");
3754 return FALSE;
3755
3756 /* Some weird FOURCC formats */
3757 case WINED3DFMT_R8G8_B8G8:
3758 case WINED3DFMT_G8R8_G8B8:
3759 case WINED3DFMT_MULTI2_ARGB8:
3760 TRACE_(d3d_caps)("[FAILED]\n");
3761 return FALSE;
3762
3763 /* Vendor specific formats */
3764 case WINED3DFMT_ATI2N:
3765 if (gl_info->supported[ATI_TEXTURE_COMPRESSION_3DC]
3766 || gl_info->supported[EXT_TEXTURE_COMPRESSION_RGTC])
3767 {
3768 if (adapter->shader_backend->shader_color_fixup_supported(format_desc->color_fixup)
3769 && adapter->fragment_pipe->color_fixup_supported(format_desc->color_fixup))
3770 {
3771 TRACE_(d3d_caps)("[OK]\n");
3772 return TRUE;
3773 }
3774
3775 TRACE_(d3d_caps)("[OK]\n");
3776 return TRUE;
3777 }
3778 TRACE_(d3d_caps)("[FAILED]\n");
3779 return FALSE;
3780
3781 case WINED3DFMT_NVHU:
3782 case WINED3DFMT_NVHS:
3783 /* These formats seem to be similar to the HILO formats in GL_NV_texture_shader. NVHU
3784 * is said to be GL_UNSIGNED_HILO16, NVHS GL_SIGNED_HILO16. Rumours say that d3d computes
3785 * a 3rd channel similarly to D3DFMT_CxV8U8(So NVHS could be called D3DFMT_CxV16U16).
3786 * ATI refused to support formats which can easilly be emulated with pixel shaders, so
3787 * Applications have to deal with not having NVHS and NVHU.
3788 */
3789 TRACE_(d3d_caps)("[FAILED]\n");
3790 return FALSE;
3791
3792 case WINED3DFMT_UNKNOWN:
3793 return FALSE;
3794
3795 default:
3796 ERR("Unhandled format=%s\n", debug_d3dformat(format_desc->format));
3797 break;
3798 }
3799 return FALSE;
3800}
3801
3802static BOOL CheckSurfaceCapability(struct wined3d_adapter *adapter,
3803 const struct wined3d_format_desc *adapter_format_desc,
3804 WINED3DDEVTYPE DeviceType, const struct wined3d_format_desc *check_format_desc,
3805 WINED3DSURFTYPE SurfaceType)
3806{
3807 if(SurfaceType == SURFACE_GDI) {
3808 switch(check_format_desc->format)
3809 {
3810 case WINED3DFMT_B8G8R8_UNORM:
3811 case WINED3DFMT_B8G8R8A8_UNORM:
3812 case WINED3DFMT_B8G8R8X8_UNORM:
3813 case WINED3DFMT_B5G6R5_UNORM:
3814 case WINED3DFMT_B5G5R5X1_UNORM:
3815 case WINED3DFMT_B5G5R5A1_UNORM:
3816 case WINED3DFMT_B4G4R4A4_UNORM:
3817 case WINED3DFMT_B2G3R3_UNORM:
3818 case WINED3DFMT_A8_UNORM:
3819 case WINED3DFMT_B2G3R3A8_UNORM:
3820 case WINED3DFMT_B4G4R4X4_UNORM:
3821 case WINED3DFMT_R10G10B10A2_UNORM:
3822 case WINED3DFMT_R8G8B8A8_UNORM:
3823 case WINED3DFMT_R8G8B8X8_UNORM:
3824 case WINED3DFMT_R16G16_UNORM:
3825 case WINED3DFMT_B10G10R10A2_UNORM:
3826 case WINED3DFMT_R16G16B16A16_UNORM:
3827 case WINED3DFMT_P8_UINT:
3828 TRACE_(d3d_caps)("[OK]\n");
3829 return TRUE;
3830 default:
3831 TRACE_(d3d_caps)("[FAILED] - not available on GDI surfaces\n");
3832 return FALSE;
3833 }
3834 }
3835
3836 /* All format that are supported for textures are supported for surfaces as well */
3837 if (CheckTextureCapability(adapter, DeviceType, check_format_desc)) return TRUE;
3838 /* All depth stencil formats are supported on surfaces */
3839 if (CheckDepthStencilCapability(adapter, adapter_format_desc, check_format_desc)) return TRUE;
3840
3841 /* If opengl can't process the format natively, the blitter may be able to convert it */
3842 if (adapter->blitter->blit_supported(&adapter->gl_info, BLIT_OP_BLIT,
3843 NULL, WINED3DPOOL_DEFAULT, 0, check_format_desc,
3844 NULL, WINED3DPOOL_DEFAULT, 0, adapter_format_desc))
3845 {
3846 TRACE_(d3d_caps)("[OK]\n");
3847 return TRUE;
3848 }
3849
3850 /* Reject other formats */
3851 TRACE_(d3d_caps)("[FAILED]\n");
3852 return FALSE;
3853}
3854
3855static BOOL CheckVertexTextureCapability(struct wined3d_adapter *adapter,
3856 const struct wined3d_format_desc *format_desc)
3857{
3858 const struct wined3d_gl_info *gl_info = &adapter->gl_info;
3859
3860 if (!gl_info->limits.vertex_samplers)
3861 {
3862 TRACE_(d3d_caps)("[FAILED]\n");
3863 return FALSE;
3864 }
3865
3866 switch (format_desc->format)
3867 {
3868 case WINED3DFMT_R32G32B32A32_FLOAT:
3869 if (!gl_info->supported[ARB_TEXTURE_FLOAT])
3870 {
3871 TRACE_(d3d_caps)("[FAILED]\n");
3872 return FALSE;
3873 }
3874 TRACE_(d3d_caps)("[OK]\n");
3875 return TRUE;
3876
3877 default:
3878 TRACE_(d3d_caps)("[FAILED]\n");
3879 return FALSE;
3880 }
3881 return FALSE;
3882}
3883
3884static HRESULT WINAPI IWineD3DImpl_CheckDeviceFormat(IWineD3D *iface, UINT Adapter, WINED3DDEVTYPE DeviceType,
3885 WINED3DFORMAT AdapterFormat, DWORD Usage, WINED3DRESOURCETYPE RType, WINED3DFORMAT CheckFormat,
3886 WINED3DSURFTYPE SurfaceType)
3887{
3888 IWineD3DImpl *This = (IWineD3DImpl *)iface;
3889 struct wined3d_adapter *adapter = &This->adapters[Adapter];
3890 const struct wined3d_gl_info *gl_info = &adapter->gl_info;
3891 const struct wined3d_format_desc *format_desc = getFormatDescEntry(CheckFormat, gl_info);
3892 const struct wined3d_format_desc *adapter_format_desc = getFormatDescEntry(AdapterFormat, gl_info);
3893 DWORD UsageCaps = 0;
3894
3895 TRACE_(d3d_caps)("(%p)-> (STUB) (Adptr:%d, DevType:(%u,%s), AdptFmt:(%u,%s), Use:(%u,%s,%s), ResTyp:(%x,%s), CheckFmt:(%u,%s))\n",
3896 This,
3897 Adapter,
3898 DeviceType, debug_d3ddevicetype(DeviceType),
3899 AdapterFormat, debug_d3dformat(AdapterFormat),
3900 Usage, debug_d3dusage(Usage), debug_d3dusagequery(Usage),
3901 RType, debug_d3dresourcetype(RType),
3902 CheckFormat, debug_d3dformat(CheckFormat));
3903
3904 if (Adapter >= IWineD3D_GetAdapterCount(iface)) {
3905 return WINED3DERR_INVALIDCALL;
3906 }
3907
3908 if(RType == WINED3DRTYPE_CUBETEXTURE) {
3909
3910 if(SurfaceType != SURFACE_OPENGL) {
3911 TRACE("[FAILED]\n");
3912 return WINED3DERR_NOTAVAILABLE;
3913 }
3914
3915 /* Cubetexture allows:
3916 * - D3DUSAGE_AUTOGENMIPMAP
3917 * - D3DUSAGE_DEPTHSTENCIL
3918 * - D3DUSAGE_DYNAMIC
3919 * - D3DUSAGE_NONSECURE (d3d9ex)
3920 * - D3DUSAGE_RENDERTARGET
3921 * - D3DUSAGE_SOFTWAREPROCESSING
3922 * - D3DUSAGE_QUERY_WRAPANDMIP
3923 */
3924 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
3925 {
3926 /* Check if the texture format is around */
3927 if (CheckTextureCapability(adapter, DeviceType, format_desc))
3928 {
3929 if(Usage & WINED3DUSAGE_AUTOGENMIPMAP) {
3930 /* Check for automatic mipmap generation support */
3931 if (gl_info->supported[SGIS_GENERATE_MIPMAP])
3932 {
3933 UsageCaps |= WINED3DUSAGE_AUTOGENMIPMAP;
3934 } else {
3935 /* When autogenmipmap isn't around continue and return WINED3DOK_NOAUTOGEN instead of D3D_OK */
3936 TRACE_(d3d_caps)("[FAILED] - No autogenmipmap support, but continuing\n");
3937 }
3938 }
3939
3940 /* Always report dynamic locking */
3941 if(Usage & WINED3DUSAGE_DYNAMIC)
3942 UsageCaps |= WINED3DUSAGE_DYNAMIC;
3943
3944 if(Usage & WINED3DUSAGE_RENDERTARGET) {
3945 if(CheckRenderTargetCapability(adapter, adapter_format_desc, format_desc))
3946 {
3947 UsageCaps |= WINED3DUSAGE_RENDERTARGET;
3948 } else {
3949 TRACE_(d3d_caps)("[FAILED] - No rendertarget support\n");
3950 return WINED3DERR_NOTAVAILABLE;
3951 }
3952 }
3953
3954 /* Always report software processing */
3955 if(Usage & WINED3DUSAGE_SOFTWAREPROCESSING)
3956 UsageCaps |= WINED3DUSAGE_SOFTWAREPROCESSING;
3957
3958 /* Check QUERY_FILTER support */
3959 if(Usage & WINED3DUSAGE_QUERY_FILTER) {
3960 if (CheckFilterCapability(adapter, format_desc))
3961 {
3962 UsageCaps |= WINED3DUSAGE_QUERY_FILTER;
3963 } else {
3964 TRACE_(d3d_caps)("[FAILED] - No query filter support\n");
3965 return WINED3DERR_NOTAVAILABLE;
3966 }
3967 }
3968
3969 /* Check QUERY_POSTPIXELSHADER_BLENDING support */
3970 if(Usage & WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING) {
3971 if (CheckPostPixelShaderBlendingCapability(adapter, format_desc))
3972 {
3973 UsageCaps |= WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING;
3974 } else {
3975 TRACE_(d3d_caps)("[FAILED] - No query post pixelshader blending support\n");
3976 return WINED3DERR_NOTAVAILABLE;
3977 }
3978 }
3979
3980 /* Check QUERY_SRGBREAD support */
3981 if(Usage & WINED3DUSAGE_QUERY_SRGBREAD) {
3982 if (CheckSrgbReadCapability(adapter, format_desc))
3983 {
3984 UsageCaps |= WINED3DUSAGE_QUERY_SRGBREAD;
3985 } else {
3986 TRACE_(d3d_caps)("[FAILED] - No query srgbread support\n");
3987 return WINED3DERR_NOTAVAILABLE;
3988 }
3989 }
3990
3991 /* Check QUERY_SRGBWRITE support */
3992 if(Usage & WINED3DUSAGE_QUERY_SRGBWRITE) {
3993 if (CheckSrgbWriteCapability(adapter, DeviceType, format_desc))
3994 {
3995 UsageCaps |= WINED3DUSAGE_QUERY_SRGBWRITE;
3996 } else {
3997 TRACE_(d3d_caps)("[FAILED] - No query srgbwrite support\n");
3998 return WINED3DERR_NOTAVAILABLE;
3999 }
4000 }
4001
4002 /* Check QUERY_VERTEXTEXTURE support */
4003 if(Usage & WINED3DUSAGE_QUERY_VERTEXTEXTURE) {
4004 if (CheckVertexTextureCapability(adapter, format_desc))
4005 {
4006 UsageCaps |= WINED3DUSAGE_QUERY_VERTEXTEXTURE;
4007 } else {
4008 TRACE_(d3d_caps)("[FAILED] - No query vertextexture support\n");
4009 return WINED3DERR_NOTAVAILABLE;
4010 }
4011 }
4012
4013 /* Check QUERY_WRAPANDMIP support */
4014 if(Usage & WINED3DUSAGE_QUERY_WRAPANDMIP) {
4015 if (CheckWrapAndMipCapability(adapter, format_desc))
4016 {
4017 UsageCaps |= WINED3DUSAGE_QUERY_WRAPANDMIP;
4018 } else {
4019 TRACE_(d3d_caps)("[FAILED] - No wrapping and mipmapping support\n");
4020 return WINED3DERR_NOTAVAILABLE;
4021 }
4022 }
4023 } else {
4024 TRACE_(d3d_caps)("[FAILED] - Cube texture format not supported\n");
4025 return WINED3DERR_NOTAVAILABLE;
4026 }
4027 } else {
4028 TRACE_(d3d_caps)("[FAILED] - No cube texture support\n");
4029 return WINED3DERR_NOTAVAILABLE;
4030 }
4031 } else if(RType == WINED3DRTYPE_SURFACE) {
4032 /* Surface allows:
4033 * - D3DUSAGE_DEPTHSTENCIL
4034 * - D3DUSAGE_NONSECURE (d3d9ex)
4035 * - D3DUSAGE_RENDERTARGET
4036 */
4037
4038 if (CheckSurfaceCapability(adapter, adapter_format_desc, DeviceType, format_desc, SurfaceType))
4039 {
4040 if(Usage & WINED3DUSAGE_DEPTHSTENCIL) {
4041 if (CheckDepthStencilCapability(adapter, adapter_format_desc, format_desc))
4042 {
4043 UsageCaps |= WINED3DUSAGE_DEPTHSTENCIL;
4044 } else {
4045 TRACE_(d3d_caps)("[FAILED] - No depthstencil support\n");
4046 return WINED3DERR_NOTAVAILABLE;
4047 }
4048 }
4049
4050 if(Usage & WINED3DUSAGE_RENDERTARGET) {
4051 if (CheckRenderTargetCapability(adapter, adapter_format_desc, format_desc))
4052 {
4053 UsageCaps |= WINED3DUSAGE_RENDERTARGET;
4054 } else {
4055 TRACE_(d3d_caps)("[FAILED] - No rendertarget support\n");
4056 return WINED3DERR_NOTAVAILABLE;
4057 }
4058 }
4059
4060 /* Check QUERY_POSTPIXELSHADER_BLENDING support */
4061 if(Usage & WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING) {
4062 if (CheckPostPixelShaderBlendingCapability(adapter, format_desc))
4063 {
4064 UsageCaps |= WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING;
4065 } else {
4066 TRACE_(d3d_caps)("[FAILED] - No query post pixelshader blending support\n");
4067 return WINED3DERR_NOTAVAILABLE;
4068 }
4069 }
4070 } else {
4071 TRACE_(d3d_caps)("[FAILED] - Not supported for plain surfaces\n");
4072 return WINED3DERR_NOTAVAILABLE;
4073 }
4074
4075 } else if(RType == WINED3DRTYPE_TEXTURE) {
4076 /* Texture allows:
4077 * - D3DUSAGE_AUTOGENMIPMAP
4078 * - D3DUSAGE_DEPTHSTENCIL
4079 * - D3DUSAGE_DMAP
4080 * - D3DUSAGE_DYNAMIC
4081 * - D3DUSAGE_NONSECURE (d3d9ex)
4082 * - D3DUSAGE_RENDERTARGET
4083 * - D3DUSAGE_SOFTWAREPROCESSING
4084 * - D3DUSAGE_TEXTAPI (d3d9ex)
4085 * - D3DUSAGE_QUERY_WRAPANDMIP
4086 */
4087
4088 if(SurfaceType != SURFACE_OPENGL) {
4089 TRACE("[FAILED]\n");
4090 return WINED3DERR_NOTAVAILABLE;
4091 }
4092
4093 /* Check if the texture format is around */
4094 if (CheckTextureCapability(adapter, DeviceType, format_desc))
4095 {
4096 if(Usage & WINED3DUSAGE_AUTOGENMIPMAP) {
4097 /* Check for automatic mipmap generation support */
4098 if (gl_info->supported[SGIS_GENERATE_MIPMAP])
4099 {
4100 UsageCaps |= WINED3DUSAGE_AUTOGENMIPMAP;
4101 } else {
4102 /* When autogenmipmap isn't around continue and return WINED3DOK_NOAUTOGEN instead of D3D_OK */
4103 TRACE_(d3d_caps)("[FAILED] - No autogenmipmap support, but continuing\n");
4104 }
4105 }
4106
4107 /* Always report dynamic locking */
4108 if(Usage & WINED3DUSAGE_DYNAMIC)
4109 UsageCaps |= WINED3DUSAGE_DYNAMIC;
4110
4111 if(Usage & WINED3DUSAGE_RENDERTARGET) {
4112 if (CheckRenderTargetCapability(adapter, adapter_format_desc, format_desc))
4113 {
4114 UsageCaps |= WINED3DUSAGE_RENDERTARGET;
4115 } else {
4116 TRACE_(d3d_caps)("[FAILED] - No rendertarget support\n");
4117 return WINED3DERR_NOTAVAILABLE;
4118 }
4119 }
4120
4121 /* Always report software processing */
4122 if(Usage & WINED3DUSAGE_SOFTWAREPROCESSING)
4123 UsageCaps |= WINED3DUSAGE_SOFTWAREPROCESSING;
4124
4125 /* Check QUERY_FILTER support */
4126 if(Usage & WINED3DUSAGE_QUERY_FILTER) {
4127 if (CheckFilterCapability(adapter, format_desc))
4128 {
4129 UsageCaps |= WINED3DUSAGE_QUERY_FILTER;
4130 } else {
4131 TRACE_(d3d_caps)("[FAILED] - No query filter support\n");
4132 return WINED3DERR_NOTAVAILABLE;
4133 }
4134 }
4135
4136 /* Check QUERY_LEGACYBUMPMAP support */
4137 if(Usage & WINED3DUSAGE_QUERY_LEGACYBUMPMAP) {
4138 if (CheckBumpMapCapability(adapter, DeviceType, format_desc))
4139 {
4140 UsageCaps |= WINED3DUSAGE_QUERY_LEGACYBUMPMAP;
4141 } else {
4142 TRACE_(d3d_caps)("[FAILED] - No legacy bumpmap support\n");
4143 return WINED3DERR_NOTAVAILABLE;
4144 }
4145 }
4146
4147 /* Check QUERY_POSTPIXELSHADER_BLENDING support */
4148 if(Usage & WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING) {
4149 if (CheckPostPixelShaderBlendingCapability(adapter, format_desc))
4150 {
4151 UsageCaps |= WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING;
4152 } else {
4153 TRACE_(d3d_caps)("[FAILED] - No query post pixelshader blending support\n");
4154 return WINED3DERR_NOTAVAILABLE;
4155 }
4156 }
4157
4158 /* Check QUERY_SRGBREAD support */
4159 if(Usage & WINED3DUSAGE_QUERY_SRGBREAD) {
4160 if (CheckSrgbReadCapability(adapter, format_desc))
4161 {
4162 UsageCaps |= WINED3DUSAGE_QUERY_SRGBREAD;
4163 } else {
4164 TRACE_(d3d_caps)("[FAILED] - No query srgbread support\n");
4165 return WINED3DERR_NOTAVAILABLE;
4166 }
4167 }
4168
4169 /* Check QUERY_SRGBWRITE support */
4170 if(Usage & WINED3DUSAGE_QUERY_SRGBWRITE) {
4171 if (CheckSrgbWriteCapability(adapter, DeviceType, format_desc))
4172 {
4173 UsageCaps |= WINED3DUSAGE_QUERY_SRGBWRITE;
4174 } else {
4175 TRACE_(d3d_caps)("[FAILED] - No query srgbwrite support\n");
4176 return WINED3DERR_NOTAVAILABLE;
4177 }
4178 }
4179
4180 /* Check QUERY_VERTEXTEXTURE support */
4181 if(Usage & WINED3DUSAGE_QUERY_VERTEXTEXTURE) {
4182 if (CheckVertexTextureCapability(adapter, format_desc))
4183 {
4184 UsageCaps |= WINED3DUSAGE_QUERY_VERTEXTEXTURE;
4185 } else {
4186 TRACE_(d3d_caps)("[FAILED] - No query vertextexture support\n");
4187 return WINED3DERR_NOTAVAILABLE;
4188 }
4189 }
4190
4191 /* Check QUERY_WRAPANDMIP support */
4192 if(Usage & WINED3DUSAGE_QUERY_WRAPANDMIP) {
4193 if (CheckWrapAndMipCapability(adapter, format_desc))
4194 {
4195 UsageCaps |= WINED3DUSAGE_QUERY_WRAPANDMIP;
4196 } else {
4197 TRACE_(d3d_caps)("[FAILED] - No wrapping and mipmapping support\n");
4198 return WINED3DERR_NOTAVAILABLE;
4199 }
4200 }
4201
4202 if(Usage & WINED3DUSAGE_DEPTHSTENCIL) {
4203 if (CheckDepthStencilCapability(adapter, adapter_format_desc, format_desc))
4204 {
4205 UsageCaps |= WINED3DUSAGE_DEPTHSTENCIL;
4206 } else {
4207 TRACE_(d3d_caps)("[FAILED] - No depth stencil support\n");
4208 return WINED3DERR_NOTAVAILABLE;
4209 }
4210 }
4211 } else {
4212 TRACE_(d3d_caps)("[FAILED] - Texture format not supported\n");
4213 return WINED3DERR_NOTAVAILABLE;
4214 }
4215 } else if((RType == WINED3DRTYPE_VOLUME) || (RType == WINED3DRTYPE_VOLUMETEXTURE)) {
4216 /* Volume is to VolumeTexture what Surface is to Texture but its usage caps are not documented.
4217 * Most driver seem to offer (nearly) the same on Volume and VolumeTexture, so do that too.
4218 *
4219 * Volumetexture allows:
4220 * - D3DUSAGE_DYNAMIC
4221 * - D3DUSAGE_NONSECURE (d3d9ex)
4222 * - D3DUSAGE_SOFTWAREPROCESSING
4223 * - D3DUSAGE_QUERY_WRAPANDMIP
4224 */
4225
4226 if(SurfaceType != SURFACE_OPENGL) {
4227 TRACE("[FAILED]\n");
4228 return WINED3DERR_NOTAVAILABLE;
4229 }
4230
4231 /* Check volume texture and volume usage caps */
4232 if (gl_info->supported[EXT_TEXTURE3D])
4233 {
4234 if (!CheckTextureCapability(adapter, DeviceType, format_desc))
4235 {
4236 TRACE_(d3d_caps)("[FAILED] - Format not supported\n");
4237 return WINED3DERR_NOTAVAILABLE;
4238 }
4239
4240 /* Always report dynamic locking */
4241 if(Usage & WINED3DUSAGE_DYNAMIC)
4242 UsageCaps |= WINED3DUSAGE_DYNAMIC;
4243
4244 /* Always report software processing */
4245 if(Usage & WINED3DUSAGE_SOFTWAREPROCESSING)
4246 UsageCaps |= WINED3DUSAGE_SOFTWAREPROCESSING;
4247
4248 /* Check QUERY_FILTER support */
4249 if(Usage & WINED3DUSAGE_QUERY_FILTER) {
4250 if (CheckFilterCapability(adapter, format_desc))
4251 {
4252 UsageCaps |= WINED3DUSAGE_QUERY_FILTER;
4253 } else {
4254 TRACE_(d3d_caps)("[FAILED] - No query filter support\n");
4255 return WINED3DERR_NOTAVAILABLE;
4256 }
4257 }
4258
4259 /* Check QUERY_POSTPIXELSHADER_BLENDING support */
4260 if(Usage & WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING) {
4261 if (CheckPostPixelShaderBlendingCapability(adapter, format_desc))
4262 {
4263 UsageCaps |= WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING;
4264 } else {
4265 TRACE_(d3d_caps)("[FAILED] - No query post pixelshader blending support\n");
4266 return WINED3DERR_NOTAVAILABLE;
4267 }
4268 }
4269
4270 /* Check QUERY_SRGBREAD support */
4271 if(Usage & WINED3DUSAGE_QUERY_SRGBREAD) {
4272 if (CheckSrgbReadCapability(adapter, format_desc))
4273 {
4274 UsageCaps |= WINED3DUSAGE_QUERY_SRGBREAD;
4275 } else {
4276 TRACE_(d3d_caps)("[FAILED] - No query srgbread support\n");
4277 return WINED3DERR_NOTAVAILABLE;
4278 }
4279 }
4280
4281 /* Check QUERY_SRGBWRITE support */
4282 if(Usage & WINED3DUSAGE_QUERY_SRGBWRITE) {
4283 if (CheckSrgbWriteCapability(adapter, DeviceType, format_desc))
4284 {
4285 UsageCaps |= WINED3DUSAGE_QUERY_SRGBWRITE;
4286 } else {
4287 TRACE_(d3d_caps)("[FAILED] - No query srgbwrite support\n");
4288 return WINED3DERR_NOTAVAILABLE;
4289 }
4290 }
4291
4292 /* Check QUERY_VERTEXTEXTURE support */
4293 if(Usage & WINED3DUSAGE_QUERY_VERTEXTEXTURE) {
4294 if (CheckVertexTextureCapability(adapter, format_desc))
4295 {
4296 UsageCaps |= WINED3DUSAGE_QUERY_VERTEXTEXTURE;
4297 } else {
4298 TRACE_(d3d_caps)("[FAILED] - No query vertextexture support\n");
4299 return WINED3DERR_NOTAVAILABLE;
4300 }
4301 }
4302
4303 /* Check QUERY_WRAPANDMIP support */
4304 if(Usage & WINED3DUSAGE_QUERY_WRAPANDMIP) {
4305 if (CheckWrapAndMipCapability(adapter, format_desc))
4306 {
4307 UsageCaps |= WINED3DUSAGE_QUERY_WRAPANDMIP;
4308 } else {
4309 TRACE_(d3d_caps)("[FAILED] - No wrapping and mipmapping support\n");
4310 return WINED3DERR_NOTAVAILABLE;
4311 }
4312 }
4313 } else {
4314 TRACE_(d3d_caps)("[FAILED] - No volume texture support\n");
4315 return WINED3DERR_NOTAVAILABLE;
4316 }
4317
4318 /* Filter formats that need conversion; For one part, this conversion is unimplemented,
4319 * and volume textures are huge, so it would be a big performance hit. Unless we hit an
4320 * app needing one of those formats, don't advertize them to avoid leading apps into
4321 * temptation. The windows drivers don't support most of those formats on volumes anyway,
4322 * except of R32F.
4323 */
4324 switch(CheckFormat) {
4325 case WINED3DFMT_P8_UINT:
4326 case WINED3DFMT_L4A4_UNORM:
4327 case WINED3DFMT_R32_FLOAT:
4328 case WINED3DFMT_R16_FLOAT:
4329 case WINED3DFMT_R8G8_SNORM_L8X8_UNORM:
4330 case WINED3DFMT_R5G5_SNORM_L6_UNORM:
4331 case WINED3DFMT_R16G16_UNORM:
4332 TRACE_(d3d_caps)("[FAILED] - No converted formats on volumes\n");
4333 return WINED3DERR_NOTAVAILABLE;
4334
4335 case WINED3DFMT_R8G8B8A8_SNORM:
4336 case WINED3DFMT_R16G16_SNORM:
4337 if (!gl_info->supported[NV_TEXTURE_SHADER])
4338 {
4339 TRACE_(d3d_caps)("[FAILED] - No converted formats on volumes\n");
4340 return WINED3DERR_NOTAVAILABLE;
4341 }
4342 break;
4343
4344 case WINED3DFMT_R8G8_SNORM:
4345 if (!gl_info->supported[NV_TEXTURE_SHADER])
4346 {
4347 TRACE_(d3d_caps)("[FAILED] - No converted formats on volumes\n");
4348 return WINED3DERR_NOTAVAILABLE;
4349 }
4350 break;
4351
4352 case WINED3DFMT_DXT1:
4353 case WINED3DFMT_DXT2:
4354 case WINED3DFMT_DXT3:
4355 case WINED3DFMT_DXT4:
4356 case WINED3DFMT_DXT5:
4357 /* The GL_EXT_texture_compression_s3tc spec requires that loading an s3tc
4358 * compressed texture results in an error. While the D3D refrast does
4359 * support s3tc volumes, at least the nvidia windows driver does not, so
4360 * we're free not to support this format.
4361 */
4362 TRACE_(d3d_caps)("[FAILED] - DXTn does not support 3D textures\n");
4363 return WINED3DERR_NOTAVAILABLE;
4364
4365 default:
4366 /* Do nothing, continue with checking the format below */
4367 break;
4368 }
4369 } else if(RType == WINED3DRTYPE_BUFFER){
4370 /* For instance vertexbuffer/indexbuffer aren't supported yet because no Windows drivers seem to offer it */
4371 TRACE_(d3d_caps)("Unhandled resource type D3DRTYPE_INDEXBUFFER / D3DRTYPE_VERTEXBUFFER\n");
4372 return WINED3DERR_NOTAVAILABLE;
4373 }
4374
4375 /* When the UsageCaps exactly matches Usage return WINED3D_OK except for the situation in which
4376 * WINED3DUSAGE_AUTOGENMIPMAP isn't around, then WINED3DOK_NOAUTOGEN is returned if all the other
4377 * usage flags match. */
4378 if(UsageCaps == Usage) {
4379 return WINED3D_OK;
4380 } else if((UsageCaps == (Usage & ~WINED3DUSAGE_AUTOGENMIPMAP)) && (Usage & WINED3DUSAGE_AUTOGENMIPMAP)){
4381 return WINED3DOK_NOAUTOGEN;
4382 } else {
4383 TRACE_(d3d_caps)("[FAILED] - Usage=%#08x requested for CheckFormat=%s and RType=%d but only %#08x is available\n", Usage, debug_d3dformat(CheckFormat), RType, UsageCaps);
4384 return WINED3DERR_NOTAVAILABLE;
4385 }
4386}
4387
4388static HRESULT WINAPI IWineD3DImpl_CheckDeviceFormatConversion(IWineD3D *iface, UINT adapter_idx,
4389 WINED3DDEVTYPE device_type, WINED3DFORMAT src_format, WINED3DFORMAT dst_format)
4390{
4391 FIXME("iface %p, adapter_idx %u, device_type %s, src_format %s, dst_format %s stub!\n",
4392 iface, adapter_idx, debug_d3ddevicetype(device_type), debug_d3dformat(src_format),
4393 debug_d3dformat(dst_format));
4394
4395 return WINED3D_OK;
4396}
4397
4398/* Note: d3d8 passes in a pointer to a D3DCAPS8 structure, which is a true
4399 subset of a D3DCAPS9 structure. However, it has to come via a void *
4400 as the d3d8 interface cannot import the d3d9 header */
4401static HRESULT WINAPI IWineD3DImpl_GetDeviceCaps(IWineD3D *iface, UINT Adapter, WINED3DDEVTYPE DeviceType, WINED3DCAPS* pCaps) {
4402
4403 IWineD3DImpl *This = (IWineD3DImpl *)iface;
4404 struct wined3d_adapter *adapter = &This->adapters[Adapter];
4405 const struct wined3d_gl_info *gl_info = &adapter->gl_info;
4406 int vs_selected_mode;
4407 int ps_selected_mode;
4408 struct shader_caps shader_caps;
4409 struct fragment_caps fragment_caps;
4410 DWORD ckey_caps, blit_caps, fx_caps;
4411
4412 TRACE_(d3d_caps)("(%p)->(Adptr:%d, DevType: %x, pCaps: %p)\n", This, Adapter, DeviceType, pCaps);
4413
4414 if (Adapter >= IWineD3D_GetAdapterCount(iface)) {
4415 return WINED3DERR_INVALIDCALL;
4416 }
4417
4418 select_shader_mode(&adapter->gl_info, &ps_selected_mode, &vs_selected_mode);
4419
4420 /* ------------------------------------------------
4421 The following fields apply to both d3d8 and d3d9
4422 ------------------------------------------------ */
4423 pCaps->DeviceType = (DeviceType == WINED3DDEVTYPE_HAL) ? WINED3DDEVTYPE_HAL : WINED3DDEVTYPE_REF; /* Not quite true, but use h/w supported by opengl I suppose */
4424 pCaps->AdapterOrdinal = Adapter;
4425
4426 pCaps->Caps = 0;
4427 pCaps->Caps2 = WINED3DCAPS2_CANRENDERWINDOWED |
4428 WINED3DCAPS2_FULLSCREENGAMMA |
4429 WINED3DCAPS2_DYNAMICTEXTURES;
4430 if (gl_info->supported[SGIS_GENERATE_MIPMAP])
4431 {
4432 pCaps->Caps2 |= WINED3DCAPS2_CANAUTOGENMIPMAP;
4433 }
4434
4435 pCaps->Caps3 = WINED3DCAPS3_ALPHA_FULLSCREEN_FLIP_OR_DISCARD |
4436 WINED3DCAPS3_COPY_TO_VIDMEM |
4437 WINED3DCAPS3_COPY_TO_SYSTEMMEM;
4438
4439 pCaps->PresentationIntervals = WINED3DPRESENT_INTERVAL_IMMEDIATE |
4440 WINED3DPRESENT_INTERVAL_ONE;
4441
4442 pCaps->CursorCaps = WINED3DCURSORCAPS_COLOR |
4443 WINED3DCURSORCAPS_LOWRES;
4444
4445 pCaps->DevCaps = WINED3DDEVCAPS_FLOATTLVERTEX |
4446 WINED3DDEVCAPS_EXECUTESYSTEMMEMORY |
4447 WINED3DDEVCAPS_TLVERTEXSYSTEMMEMORY|
4448 WINED3DDEVCAPS_TLVERTEXVIDEOMEMORY |
4449 WINED3DDEVCAPS_DRAWPRIMTLVERTEX |
4450 WINED3DDEVCAPS_HWTRANSFORMANDLIGHT |
4451 WINED3DDEVCAPS_EXECUTEVIDEOMEMORY |
4452 WINED3DDEVCAPS_PUREDEVICE |
4453 WINED3DDEVCAPS_HWRASTERIZATION |
4454 WINED3DDEVCAPS_TEXTUREVIDEOMEMORY |
4455 WINED3DDEVCAPS_TEXTURESYSTEMMEMORY |
4456 WINED3DDEVCAPS_CANRENDERAFTERFLIP |
4457 WINED3DDEVCAPS_DRAWPRIMITIVES2 |
4458 WINED3DDEVCAPS_DRAWPRIMITIVES2EX |
4459 WINED3DDEVCAPS_RTPATCHES;
4460
4461 pCaps->PrimitiveMiscCaps = WINED3DPMISCCAPS_CULLNONE |
4462 WINED3DPMISCCAPS_CULLCCW |
4463 WINED3DPMISCCAPS_CULLCW |
4464 WINED3DPMISCCAPS_COLORWRITEENABLE |
4465 WINED3DPMISCCAPS_CLIPTLVERTS |
4466 WINED3DPMISCCAPS_CLIPPLANESCALEDPOINTS |
4467 WINED3DPMISCCAPS_MASKZ |
4468 WINED3DPMISCCAPS_BLENDOP |
4469 WINED3DPMISCCAPS_MRTPOSTPIXELSHADERBLENDING;
4470 /* TODO:
4471 WINED3DPMISCCAPS_NULLREFERENCE
4472 WINED3DPMISCCAPS_FOGANDSPECULARALPHA
4473 WINED3DPMISCCAPS_MRTINDEPENDENTBITDEPTHS
4474 WINED3DPMISCCAPS_FOGVERTEXCLAMPED */
4475
4476 if (gl_info->supported[EXT_BLEND_EQUATION_SEPARATE] && gl_info->supported[EXT_BLEND_FUNC_SEPARATE])
4477 pCaps->PrimitiveMiscCaps |= WINED3DPMISCCAPS_SEPARATEALPHABLEND;
4478 if (gl_info->supported[EXT_DRAW_BUFFERS2])
4479 pCaps->PrimitiveMiscCaps |= WINED3DPMISCCAPS_INDEPENDENTWRITEMASKS;
4480
4481 pCaps->RasterCaps = WINED3DPRASTERCAPS_DITHER |
4482 WINED3DPRASTERCAPS_PAT |
4483 WINED3DPRASTERCAPS_WFOG |
4484 WINED3DPRASTERCAPS_ZFOG |
4485 WINED3DPRASTERCAPS_FOGVERTEX |
4486 WINED3DPRASTERCAPS_FOGTABLE |
4487 WINED3DPRASTERCAPS_STIPPLE |
4488 WINED3DPRASTERCAPS_SUBPIXEL |
4489 WINED3DPRASTERCAPS_ZTEST |
4490 WINED3DPRASTERCAPS_SCISSORTEST |
4491 WINED3DPRASTERCAPS_SLOPESCALEDEPTHBIAS |
4492 WINED3DPRASTERCAPS_DEPTHBIAS;
4493
4494 if (gl_info->supported[EXT_TEXTURE_FILTER_ANISOTROPIC])
4495 {
4496 pCaps->RasterCaps |= WINED3DPRASTERCAPS_ANISOTROPY |
4497 WINED3DPRASTERCAPS_ZBIAS |
4498 WINED3DPRASTERCAPS_MIPMAPLODBIAS;
4499 }
4500 if (gl_info->supported[NV_FOG_DISTANCE])
4501 {
4502 pCaps->RasterCaps |= WINED3DPRASTERCAPS_FOGRANGE;
4503 }
4504 /* FIXME Add:
4505 WINED3DPRASTERCAPS_COLORPERSPECTIVE
4506 WINED3DPRASTERCAPS_STRETCHBLTMULTISAMPLE
4507 WINED3DPRASTERCAPS_ANTIALIASEDGES
4508 WINED3DPRASTERCAPS_ZBUFFERLESSHSR
4509 WINED3DPRASTERCAPS_WBUFFER */
4510
4511 pCaps->ZCmpCaps = WINED3DPCMPCAPS_ALWAYS |
4512 WINED3DPCMPCAPS_EQUAL |
4513 WINED3DPCMPCAPS_GREATER |
4514 WINED3DPCMPCAPS_GREATEREQUAL |
4515 WINED3DPCMPCAPS_LESS |
4516 WINED3DPCMPCAPS_LESSEQUAL |
4517 WINED3DPCMPCAPS_NEVER |
4518 WINED3DPCMPCAPS_NOTEQUAL;
4519
4520 pCaps->SrcBlendCaps = WINED3DPBLENDCAPS_BOTHINVSRCALPHA |
4521 WINED3DPBLENDCAPS_BOTHSRCALPHA |
4522 WINED3DPBLENDCAPS_DESTALPHA |
4523 WINED3DPBLENDCAPS_DESTCOLOR |
4524 WINED3DPBLENDCAPS_INVDESTALPHA |
4525 WINED3DPBLENDCAPS_INVDESTCOLOR |
4526 WINED3DPBLENDCAPS_INVSRCALPHA |
4527 WINED3DPBLENDCAPS_INVSRCCOLOR |
4528 WINED3DPBLENDCAPS_ONE |
4529 WINED3DPBLENDCAPS_SRCALPHA |
4530 WINED3DPBLENDCAPS_SRCALPHASAT |
4531 WINED3DPBLENDCAPS_SRCCOLOR |
4532 WINED3DPBLENDCAPS_ZERO;
4533
4534 pCaps->DestBlendCaps = WINED3DPBLENDCAPS_DESTALPHA |
4535 WINED3DPBLENDCAPS_DESTCOLOR |
4536 WINED3DPBLENDCAPS_INVDESTALPHA |
4537 WINED3DPBLENDCAPS_INVDESTCOLOR |
4538 WINED3DPBLENDCAPS_INVSRCALPHA |
4539 WINED3DPBLENDCAPS_INVSRCCOLOR |
4540 WINED3DPBLENDCAPS_ONE |
4541 WINED3DPBLENDCAPS_SRCALPHA |
4542 WINED3DPBLENDCAPS_SRCCOLOR |
4543 WINED3DPBLENDCAPS_ZERO;
4544 /* NOTE: WINED3DPBLENDCAPS_SRCALPHASAT is not supported as dest blend factor,
4545 * according to the glBlendFunc manpage
4546 *
4547 * WINED3DPBLENDCAPS_BOTHINVSRCALPHA and WINED3DPBLENDCAPS_BOTHSRCALPHA are
4548 * legacy settings for srcblend only
4549 */
4550
4551 if (gl_info->supported[EXT_BLEND_COLOR])
4552 {
4553 pCaps->SrcBlendCaps |= WINED3DPBLENDCAPS_BLENDFACTOR;
4554 pCaps->DestBlendCaps |= WINED3DPBLENDCAPS_BLENDFACTOR;
4555 }
4556
4557
4558 pCaps->AlphaCmpCaps = WINED3DPCMPCAPS_ALWAYS |
4559 WINED3DPCMPCAPS_EQUAL |
4560 WINED3DPCMPCAPS_GREATER |
4561 WINED3DPCMPCAPS_GREATEREQUAL |
4562 WINED3DPCMPCAPS_LESS |
4563 WINED3DPCMPCAPS_LESSEQUAL |
4564 WINED3DPCMPCAPS_NEVER |
4565 WINED3DPCMPCAPS_NOTEQUAL;
4566
4567 pCaps->ShadeCaps = WINED3DPSHADECAPS_SPECULARGOURAUDRGB |
4568 WINED3DPSHADECAPS_COLORGOURAUDRGB |
4569 WINED3DPSHADECAPS_ALPHAFLATBLEND |
4570 WINED3DPSHADECAPS_ALPHAGOURAUDBLEND |
4571 WINED3DPSHADECAPS_COLORFLATRGB |
4572 WINED3DPSHADECAPS_FOGFLAT |
4573 WINED3DPSHADECAPS_FOGGOURAUD |
4574 WINED3DPSHADECAPS_SPECULARFLATRGB;
4575
4576 pCaps->TextureCaps = WINED3DPTEXTURECAPS_ALPHA |
4577 WINED3DPTEXTURECAPS_ALPHAPALETTE |
4578 WINED3DPTEXTURECAPS_TRANSPARENCY |
4579 WINED3DPTEXTURECAPS_BORDER |
4580 WINED3DPTEXTURECAPS_MIPMAP |
4581 WINED3DPTEXTURECAPS_PROJECTED |
4582 WINED3DPTEXTURECAPS_PERSPECTIVE;
4583
4584 if (!gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO])
4585 {
4586 pCaps->TextureCaps |= WINED3DPTEXTURECAPS_POW2 |
4587 WINED3DPTEXTURECAPS_NONPOW2CONDITIONAL;
4588 }
4589
4590 if (gl_info->supported[EXT_TEXTURE3D])
4591 {
4592 pCaps->TextureCaps |= WINED3DPTEXTURECAPS_VOLUMEMAP |
4593 WINED3DPTEXTURECAPS_MIPVOLUMEMAP |
4594 WINED3DPTEXTURECAPS_VOLUMEMAP_POW2;
4595 }
4596
4597 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
4598 {
4599 pCaps->TextureCaps |= WINED3DPTEXTURECAPS_CUBEMAP |
4600 WINED3DPTEXTURECAPS_MIPCUBEMAP |
4601 WINED3DPTEXTURECAPS_CUBEMAP_POW2;
4602
4603 }
4604
4605 pCaps->TextureFilterCaps = WINED3DPTFILTERCAPS_MAGFLINEAR |
4606 WINED3DPTFILTERCAPS_MAGFPOINT |
4607 WINED3DPTFILTERCAPS_MINFLINEAR |
4608 WINED3DPTFILTERCAPS_MINFPOINT |
4609 WINED3DPTFILTERCAPS_MIPFLINEAR |
4610 WINED3DPTFILTERCAPS_MIPFPOINT |
4611 WINED3DPTFILTERCAPS_LINEAR |
4612 WINED3DPTFILTERCAPS_LINEARMIPLINEAR |
4613 WINED3DPTFILTERCAPS_LINEARMIPNEAREST |
4614 WINED3DPTFILTERCAPS_MIPLINEAR |
4615 WINED3DPTFILTERCAPS_MIPNEAREST |
4616 WINED3DPTFILTERCAPS_NEAREST;
4617
4618 if (gl_info->supported[EXT_TEXTURE_FILTER_ANISOTROPIC])
4619 {
4620 pCaps->TextureFilterCaps |= WINED3DPTFILTERCAPS_MAGFANISOTROPIC |
4621 WINED3DPTFILTERCAPS_MINFANISOTROPIC;
4622 }
4623
4624 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
4625 {
4626 pCaps->CubeTextureFilterCaps = WINED3DPTFILTERCAPS_MAGFLINEAR |
4627 WINED3DPTFILTERCAPS_MAGFPOINT |
4628 WINED3DPTFILTERCAPS_MINFLINEAR |
4629 WINED3DPTFILTERCAPS_MINFPOINT |
4630 WINED3DPTFILTERCAPS_MIPFLINEAR |
4631 WINED3DPTFILTERCAPS_MIPFPOINT |
4632 WINED3DPTFILTERCAPS_LINEAR |
4633 WINED3DPTFILTERCAPS_LINEARMIPLINEAR |
4634 WINED3DPTFILTERCAPS_LINEARMIPNEAREST |
4635 WINED3DPTFILTERCAPS_MIPLINEAR |
4636 WINED3DPTFILTERCAPS_MIPNEAREST |
4637 WINED3DPTFILTERCAPS_NEAREST;
4638
4639 if (gl_info->supported[EXT_TEXTURE_FILTER_ANISOTROPIC])
4640 {
4641 pCaps->CubeTextureFilterCaps |= WINED3DPTFILTERCAPS_MAGFANISOTROPIC |
4642 WINED3DPTFILTERCAPS_MINFANISOTROPIC;
4643 }
4644 } else
4645 pCaps->CubeTextureFilterCaps = 0;
4646
4647 if (gl_info->supported[EXT_TEXTURE3D])
4648 {
4649 pCaps->VolumeTextureFilterCaps = WINED3DPTFILTERCAPS_MAGFLINEAR |
4650 WINED3DPTFILTERCAPS_MAGFPOINT |
4651 WINED3DPTFILTERCAPS_MINFLINEAR |
4652 WINED3DPTFILTERCAPS_MINFPOINT |
4653 WINED3DPTFILTERCAPS_MIPFLINEAR |
4654 WINED3DPTFILTERCAPS_MIPFPOINT |
4655 WINED3DPTFILTERCAPS_LINEAR |
4656 WINED3DPTFILTERCAPS_LINEARMIPLINEAR |
4657 WINED3DPTFILTERCAPS_LINEARMIPNEAREST |
4658 WINED3DPTFILTERCAPS_MIPLINEAR |
4659 WINED3DPTFILTERCAPS_MIPNEAREST |
4660 WINED3DPTFILTERCAPS_NEAREST;
4661 } else
4662 pCaps->VolumeTextureFilterCaps = 0;
4663
4664 pCaps->TextureAddressCaps = WINED3DPTADDRESSCAPS_INDEPENDENTUV |
4665 WINED3DPTADDRESSCAPS_CLAMP |
4666 WINED3DPTADDRESSCAPS_WRAP;
4667
4668 if (gl_info->supported[ARB_TEXTURE_BORDER_CLAMP])
4669 {
4670 pCaps->TextureAddressCaps |= WINED3DPTADDRESSCAPS_BORDER;
4671 }
4672 if (gl_info->supported[ARB_TEXTURE_MIRRORED_REPEAT])
4673 {
4674 pCaps->TextureAddressCaps |= WINED3DPTADDRESSCAPS_MIRROR;
4675 }
4676 if (gl_info->supported[ATI_TEXTURE_MIRROR_ONCE])
4677 {
4678 pCaps->TextureAddressCaps |= WINED3DPTADDRESSCAPS_MIRRORONCE;
4679 }
4680
4681 if (gl_info->supported[EXT_TEXTURE3D])
4682 {
4683 pCaps->VolumeTextureAddressCaps = WINED3DPTADDRESSCAPS_INDEPENDENTUV |
4684 WINED3DPTADDRESSCAPS_CLAMP |
4685 WINED3DPTADDRESSCAPS_WRAP;
4686 if (gl_info->supported[ARB_TEXTURE_BORDER_CLAMP])
4687 {
4688 pCaps->VolumeTextureAddressCaps |= WINED3DPTADDRESSCAPS_BORDER;
4689 }
4690 if (gl_info->supported[ARB_TEXTURE_MIRRORED_REPEAT])
4691 {
4692 pCaps->VolumeTextureAddressCaps |= WINED3DPTADDRESSCAPS_MIRROR;
4693 }
4694 if (gl_info->supported[ATI_TEXTURE_MIRROR_ONCE])
4695 {
4696 pCaps->VolumeTextureAddressCaps |= WINED3DPTADDRESSCAPS_MIRRORONCE;
4697 }
4698 } else
4699 pCaps->VolumeTextureAddressCaps = 0;
4700
4701 pCaps->LineCaps = WINED3DLINECAPS_TEXTURE |
4702 WINED3DLINECAPS_ZTEST |
4703 WINED3DLINECAPS_BLEND |
4704 WINED3DLINECAPS_ALPHACMP |
4705 WINED3DLINECAPS_FOG;
4706 /* WINED3DLINECAPS_ANTIALIAS is not supported on Windows, and dx and gl seem to have a different
4707 * idea how generating the smoothing alpha values works; the result is different
4708 */
4709
4710 pCaps->MaxTextureWidth = gl_info->limits.texture_size;
4711 pCaps->MaxTextureHeight = gl_info->limits.texture_size;
4712
4713 if (gl_info->supported[EXT_TEXTURE3D])
4714 pCaps->MaxVolumeExtent = gl_info->limits.texture3d_size;
4715 else
4716 pCaps->MaxVolumeExtent = 0;
4717
4718 pCaps->MaxTextureRepeat = 32768;
4719 pCaps->MaxTextureAspectRatio = gl_info->limits.texture_size;
4720 pCaps->MaxVertexW = 1.0f;
4721
4722 pCaps->GuardBandLeft = 0.0f;
4723 pCaps->GuardBandTop = 0.0f;
4724 pCaps->GuardBandRight = 0.0f;
4725 pCaps->GuardBandBottom = 0.0f;
4726
4727 pCaps->ExtentsAdjust = 0.0f;
4728
4729 pCaps->StencilCaps = WINED3DSTENCILCAPS_DECRSAT |
4730 WINED3DSTENCILCAPS_INCRSAT |
4731 WINED3DSTENCILCAPS_INVERT |
4732 WINED3DSTENCILCAPS_KEEP |
4733 WINED3DSTENCILCAPS_REPLACE |
4734 WINED3DSTENCILCAPS_ZERO;
4735 if (gl_info->supported[EXT_STENCIL_WRAP])
4736 {
4737 pCaps->StencilCaps |= WINED3DSTENCILCAPS_DECR |
4738 WINED3DSTENCILCAPS_INCR;
4739 }
4740 if (gl_info->supported[EXT_STENCIL_TWO_SIDE] || gl_info->supported[ATI_SEPARATE_STENCIL])
4741 {
4742 pCaps->StencilCaps |= WINED3DSTENCILCAPS_TWOSIDED;
4743 }
4744
4745 pCaps->FVFCaps = WINED3DFVFCAPS_PSIZE | 0x0008; /* 8 texture coords */
4746
4747 pCaps->MaxUserClipPlanes = gl_info->limits.clipplanes;
4748 pCaps->MaxActiveLights = gl_info->limits.lights;
4749
4750 pCaps->MaxVertexBlendMatrices = gl_info->limits.blends;
4751 pCaps->MaxVertexBlendMatrixIndex = 0;
4752
4753 pCaps->MaxAnisotropy = gl_info->limits.anisotropy;
4754 pCaps->MaxPointSize = gl_info->limits.pointsize_max;
4755
4756
4757 /* FIXME: Add D3DVTXPCAPS_TWEENING, D3DVTXPCAPS_TEXGEN_SPHEREMAP */
4758 pCaps->VertexProcessingCaps = WINED3DVTXPCAPS_DIRECTIONALLIGHTS |
4759 WINED3DVTXPCAPS_MATERIALSOURCE7 |
4760 WINED3DVTXPCAPS_POSITIONALLIGHTS |
4761 WINED3DVTXPCAPS_LOCALVIEWER |
4762 WINED3DVTXPCAPS_VERTEXFOG |
4763 WINED3DVTXPCAPS_TEXGEN;
4764
4765 pCaps->MaxPrimitiveCount = 0xFFFFF; /* For now set 2^20-1 which is used by most >=Geforce3/Radeon8500 cards */
4766 pCaps->MaxVertexIndex = 0xFFFFF;
4767 pCaps->MaxStreams = MAX_STREAMS;
4768 pCaps->MaxStreamStride = 1024;
4769
4770 /* d3d9.dll sets D3DDEVCAPS2_CAN_STRETCHRECT_FROM_TEXTURES here because StretchRects is implemented in d3d9 */
4771 pCaps->DevCaps2 = WINED3DDEVCAPS2_STREAMOFFSET |
4772 WINED3DDEVCAPS2_VERTEXELEMENTSCANSHARESTREAMOFFSET;
4773 pCaps->MaxNpatchTessellationLevel = 0;
4774 pCaps->MasterAdapterOrdinal = 0;
4775 pCaps->AdapterOrdinalInGroup = 0;
4776 pCaps->NumberOfAdaptersInGroup = 1;
4777
4778 pCaps->NumSimultaneousRTs = gl_info->limits.buffers;
4779
4780 pCaps->StretchRectFilterCaps = WINED3DPTFILTERCAPS_MINFPOINT |
4781 WINED3DPTFILTERCAPS_MAGFPOINT |
4782 WINED3DPTFILTERCAPS_MINFLINEAR |
4783 WINED3DPTFILTERCAPS_MAGFLINEAR;
4784 pCaps->VertexTextureFilterCaps = 0;
4785
4786 memset(&shader_caps, 0, sizeof(shader_caps));
4787 adapter->shader_backend->shader_get_caps(&adapter->gl_info, &shader_caps);
4788
4789 memset(&fragment_caps, 0, sizeof(fragment_caps));
4790 adapter->fragment_pipe->get_caps(&adapter->gl_info, &fragment_caps);
4791
4792 /* Add shader misc caps. Only some of them belong to the shader parts of the pipeline */
4793 pCaps->PrimitiveMiscCaps |= fragment_caps.PrimitiveMiscCaps;
4794
4795 /* This takes care for disabling vertex shader or pixel shader caps while leaving the other one enabled.
4796 * Ignore shader model capabilities if disabled in config
4797 */
4798 if(vs_selected_mode == SHADER_NONE) {
4799 TRACE_(d3d_caps)("Vertex shader disabled in config, reporting version 0.0\n");
4800 pCaps->VertexShaderVersion = WINED3DVS_VERSION(0,0);
4801 pCaps->MaxVertexShaderConst = 0;
4802 } else {
4803 pCaps->VertexShaderVersion = shader_caps.VertexShaderVersion;
4804 pCaps->MaxVertexShaderConst = shader_caps.MaxVertexShaderConst;
4805 }
4806
4807 if(ps_selected_mode == SHADER_NONE) {
4808 TRACE_(d3d_caps)("Pixel shader disabled in config, reporting version 0.0\n");
4809 pCaps->PixelShaderVersion = WINED3DPS_VERSION(0,0);
4810 pCaps->PixelShader1xMaxValue = 0.0f;
4811 } else {
4812 pCaps->PixelShaderVersion = shader_caps.PixelShaderVersion;
4813 pCaps->PixelShader1xMaxValue = shader_caps.PixelShader1xMaxValue;
4814 }
4815
4816 pCaps->TextureOpCaps = fragment_caps.TextureOpCaps;
4817 pCaps->MaxTextureBlendStages = fragment_caps.MaxTextureBlendStages;
4818 pCaps->MaxSimultaneousTextures = fragment_caps.MaxSimultaneousTextures;
4819
4820 pCaps->VS20Caps = shader_caps.VS20Caps;
4821 pCaps->MaxVShaderInstructionsExecuted = shader_caps.MaxVShaderInstructionsExecuted;
4822 pCaps->MaxVertexShader30InstructionSlots= shader_caps.MaxVertexShader30InstructionSlots;
4823 pCaps->PS20Caps = shader_caps.PS20Caps;
4824 pCaps->MaxPShaderInstructionsExecuted = shader_caps.MaxPShaderInstructionsExecuted;
4825 pCaps->MaxPixelShader30InstructionSlots = shader_caps.MaxPixelShader30InstructionSlots;
4826
4827 /* The following caps are shader specific, but they are things we cannot detect, or which
4828 * are the same among all shader models. So to avoid code duplication set the shader version
4829 * specific, but otherwise constant caps here
4830 */
4831 if(pCaps->VertexShaderVersion == WINED3DVS_VERSION(3,0)) {
4832 /* Where possible set the caps based on OpenGL extensions and if they aren't set (in case of software rendering)
4833 use the VS 3.0 from MSDN or else if there's OpenGL spec use a hardcoded value minimum VS3.0 value. */
4834 pCaps->VS20Caps.Caps = WINED3DVS20CAPS_PREDICATION;
4835 pCaps->VS20Caps.DynamicFlowControlDepth = WINED3DVS20_MAX_DYNAMICFLOWCONTROLDEPTH; /* VS 3.0 requires MAX_DYNAMICFLOWCONTROLDEPTH (24) */
4836 pCaps->VS20Caps.NumTemps = max(32, adapter->gl_info.limits.arb_vs_temps);
4837 pCaps->VS20Caps.StaticFlowControlDepth = WINED3DVS20_MAX_STATICFLOWCONTROLDEPTH ; /* level of nesting in loops / if-statements; VS 3.0 requires MAX (4) */
4838
4839 pCaps->MaxVShaderInstructionsExecuted = 65535; /* VS 3.0 needs at least 65535, some cards even use 2^32-1 */
4840 pCaps->MaxVertexShader30InstructionSlots = max(512, adapter->gl_info.limits.arb_vs_instructions);
4841 }
4842 else if (pCaps->VertexShaderVersion == WINED3DVS_VERSION(2,0))
4843 {
4844 pCaps->VS20Caps.Caps = 0;
4845 pCaps->VS20Caps.DynamicFlowControlDepth = WINED3DVS20_MIN_DYNAMICFLOWCONTROLDEPTH;
4846 pCaps->VS20Caps.NumTemps = max(12, adapter->gl_info.limits.arb_vs_temps);
4847 pCaps->VS20Caps.StaticFlowControlDepth = 1;
4848
4849 pCaps->MaxVShaderInstructionsExecuted = 65535;
4850 pCaps->MaxVertexShader30InstructionSlots = 0;
4851 } else { /* VS 1.x */
4852 pCaps->VS20Caps.Caps = 0;
4853 pCaps->VS20Caps.DynamicFlowControlDepth = 0;
4854 pCaps->VS20Caps.NumTemps = 0;
4855 pCaps->VS20Caps.StaticFlowControlDepth = 0;
4856
4857 pCaps->MaxVShaderInstructionsExecuted = 0;
4858 pCaps->MaxVertexShader30InstructionSlots = 0;
4859 }
4860
4861 if(pCaps->PixelShaderVersion == WINED3DPS_VERSION(3,0)) {
4862 /* Where possible set the caps based on OpenGL extensions and if they aren't set (in case of software rendering)
4863 use the PS 3.0 from MSDN or else if there's OpenGL spec use a hardcoded value minimum PS 3.0 value. */
4864
4865 /* 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 */
4866 pCaps->PS20Caps.Caps = WINED3DPS20CAPS_ARBITRARYSWIZZLE |
4867 WINED3DPS20CAPS_GRADIENTINSTRUCTIONS |
4868 WINED3DPS20CAPS_PREDICATION |
4869 WINED3DPS20CAPS_NODEPENDENTREADLIMIT |
4870 WINED3DPS20CAPS_NOTEXINSTRUCTIONLIMIT;
4871 pCaps->PS20Caps.DynamicFlowControlDepth = WINED3DPS20_MAX_DYNAMICFLOWCONTROLDEPTH; /* PS 3.0 requires MAX_DYNAMICFLOWCONTROLDEPTH (24) */
4872 pCaps->PS20Caps.NumTemps = max(32, adapter->gl_info.limits.arb_ps_temps);
4873 pCaps->PS20Caps.StaticFlowControlDepth = WINED3DPS20_MAX_STATICFLOWCONTROLDEPTH; /* PS 3.0 requires MAX_STATICFLOWCONTROLDEPTH (4) */
4874 pCaps->PS20Caps.NumInstructionSlots = WINED3DPS20_MAX_NUMINSTRUCTIONSLOTS; /* PS 3.0 requires MAX_NUMINSTRUCTIONSLOTS (512) */
4875
4876 pCaps->MaxPShaderInstructionsExecuted = 65535;
4877 pCaps->MaxPixelShader30InstructionSlots = max(WINED3DMIN30SHADERINSTRUCTIONS,
4878 adapter->gl_info.limits.arb_ps_instructions);
4879 }
4880 else if(pCaps->PixelShaderVersion == WINED3DPS_VERSION(2,0))
4881 {
4882 /* Below we assume PS2.0 specs, not extended 2.0a(GeforceFX)/2.0b(Radeon R3xx) ones */
4883 pCaps->PS20Caps.Caps = 0;
4884 pCaps->PS20Caps.DynamicFlowControlDepth = 0; /* WINED3DVS20_MIN_DYNAMICFLOWCONTROLDEPTH = 0 */
4885 pCaps->PS20Caps.NumTemps = max(12, adapter->gl_info.limits.arb_ps_temps);
4886 pCaps->PS20Caps.StaticFlowControlDepth = WINED3DPS20_MIN_STATICFLOWCONTROLDEPTH; /* Minimum: 1 */
4887 pCaps->PS20Caps.NumInstructionSlots = WINED3DPS20_MIN_NUMINSTRUCTIONSLOTS; /* Minimum number (64 ALU + 32 Texture), a GeforceFX uses 512 */
4888
4889 pCaps->MaxPShaderInstructionsExecuted = 512; /* Minimum value, a GeforceFX uses 1024 */
4890 pCaps->MaxPixelShader30InstructionSlots = 0;
4891 } else { /* PS 1.x */
4892 pCaps->PS20Caps.Caps = 0;
4893 pCaps->PS20Caps.DynamicFlowControlDepth = 0;
4894 pCaps->PS20Caps.NumTemps = 0;
4895 pCaps->PS20Caps.StaticFlowControlDepth = 0;
4896 pCaps->PS20Caps.NumInstructionSlots = 0;
4897
4898 pCaps->MaxPShaderInstructionsExecuted = 0;
4899 pCaps->MaxPixelShader30InstructionSlots = 0;
4900 }
4901
4902 if(pCaps->VertexShaderVersion >= WINED3DVS_VERSION(2,0)) {
4903 /* OpenGL supports all the formats below, perhaps not always
4904 * without conversion, but it supports them.
4905 * Further GLSL doesn't seem to have an official unsigned type so
4906 * don't advertise it yet as I'm not sure how we handle it.
4907 * We might need to add some clamping in the shader engine to
4908 * support it.
4909 * TODO: WINED3DDTCAPS_USHORT2N, WINED3DDTCAPS_USHORT4N, WINED3DDTCAPS_UDEC3, WINED3DDTCAPS_DEC3N */
4910 pCaps->DeclTypes = WINED3DDTCAPS_UBYTE4 |
4911 WINED3DDTCAPS_UBYTE4N |
4912 WINED3DDTCAPS_SHORT2N |
4913 WINED3DDTCAPS_SHORT4N;
4914 if (gl_info->supported[ARB_HALF_FLOAT_VERTEX])
4915 {
4916 pCaps->DeclTypes |= WINED3DDTCAPS_FLOAT16_2 |
4917 WINED3DDTCAPS_FLOAT16_4;
4918 }
4919 } else
4920 pCaps->DeclTypes = 0;
4921
4922 /* Set DirectDraw helper Caps */
4923 ckey_caps = WINEDDCKEYCAPS_DESTBLT |
4924 WINEDDCKEYCAPS_SRCBLT;
4925 fx_caps = WINEDDFXCAPS_BLTALPHA |
4926 WINEDDFXCAPS_BLTMIRRORLEFTRIGHT |
4927 WINEDDFXCAPS_BLTMIRRORUPDOWN |
4928 WINEDDFXCAPS_BLTROTATION90 |
4929 WINEDDFXCAPS_BLTSHRINKX |
4930 WINEDDFXCAPS_BLTSHRINKXN |
4931 WINEDDFXCAPS_BLTSHRINKY |
4932 WINEDDFXCAPS_BLTSHRINKXN |
4933 WINEDDFXCAPS_BLTSTRETCHX |
4934 WINEDDFXCAPS_BLTSTRETCHXN |
4935 WINEDDFXCAPS_BLTSTRETCHY |
4936 WINEDDFXCAPS_BLTSTRETCHYN;
4937 blit_caps = WINEDDCAPS_BLT |
4938 WINEDDCAPS_BLTCOLORFILL |
4939 WINEDDCAPS_BLTDEPTHFILL |
4940 WINEDDCAPS_BLTSTRETCH |
4941 WINEDDCAPS_CANBLTSYSMEM |
4942 WINEDDCAPS_CANCLIP |
4943 WINEDDCAPS_CANCLIPSTRETCHED |
4944 WINEDDCAPS_COLORKEY |
4945 WINEDDCAPS_COLORKEYHWASSIST |
4946 WINEDDCAPS_ALIGNBOUNDARYSRC;
4947
4948 /* Fill the ddraw caps structure */
4949 pCaps->DirectDrawCaps.Caps = WINEDDCAPS_GDI |
4950 WINEDDCAPS_PALETTE |
4951 blit_caps;
4952 pCaps->DirectDrawCaps.Caps2 = WINEDDCAPS2_CERTIFIED |
4953 WINEDDCAPS2_NOPAGELOCKREQUIRED |
4954 WINEDDCAPS2_PRIMARYGAMMA |
4955 WINEDDCAPS2_WIDESURFACES |
4956 WINEDDCAPS2_CANRENDERWINDOWED;
4957 pCaps->DirectDrawCaps.SVBCaps = blit_caps;
4958 pCaps->DirectDrawCaps.SVBCKeyCaps = ckey_caps;
4959 pCaps->DirectDrawCaps.SVBFXCaps = fx_caps;
4960 pCaps->DirectDrawCaps.VSBCaps = blit_caps;
4961 pCaps->DirectDrawCaps.VSBCKeyCaps = ckey_caps;
4962 pCaps->DirectDrawCaps.VSBFXCaps = fx_caps;
4963 pCaps->DirectDrawCaps.SSBCaps = blit_caps;
4964 pCaps->DirectDrawCaps.SSBCKeyCaps = ckey_caps;
4965 pCaps->DirectDrawCaps.SSBFXCaps = fx_caps;
4966
4967 pCaps->DirectDrawCaps.ddsCaps = WINEDDSCAPS_ALPHA |
4968 WINEDDSCAPS_BACKBUFFER |
4969 WINEDDSCAPS_FLIP |
4970 WINEDDSCAPS_FRONTBUFFER |
4971 WINEDDSCAPS_OFFSCREENPLAIN |
4972 WINEDDSCAPS_PALETTE |
4973 WINEDDSCAPS_PRIMARYSURFACE |
4974 WINEDDSCAPS_SYSTEMMEMORY |
4975 WINEDDSCAPS_VIDEOMEMORY |
4976 WINEDDSCAPS_VISIBLE;
4977 pCaps->DirectDrawCaps.StrideAlign = DDRAW_PITCH_ALIGNMENT;
4978
4979 /* Set D3D caps if OpenGL is available. */
4980 if (adapter->opengl)
4981 {
4982 pCaps->DirectDrawCaps.ddsCaps |=WINEDDSCAPS_3DDEVICE |
4983 WINEDDSCAPS_MIPMAP |
4984 WINEDDSCAPS_TEXTURE |
4985 WINEDDSCAPS_ZBUFFER;
4986 pCaps->DirectDrawCaps.Caps |= WINEDDCAPS_3D;
4987 }
4988
4989 return WINED3D_OK;
4990}
4991
4992static HRESULT WINAPI IWineD3DImpl_CreateDevice(IWineD3D *iface, UINT adapter_idx,
4993 WINED3DDEVTYPE device_type, HWND focus_window, DWORD flags, IUnknown *parent,
4994 IWineD3DDeviceParent *device_parent, IWineD3DDevice **device)
4995{
4996 IWineD3DImpl *This = (IWineD3DImpl *)iface;
4997 IWineD3DDeviceImpl *object;
4998 HRESULT hr;
4999
5000 TRACE("iface %p, adapter_idx %u, device_type %#x, focus_window %p, flags %#x.\n"
5001 "parent %p, device_parent %p, device %p.\n",
5002 iface, adapter_idx, device_type, focus_window, flags,
5003 parent, device_parent, device);
5004
5005 /* Validate the adapter number. If no adapters are available(no GL), ignore the adapter
5006 * number and create a device without a 3D adapter for 2D only operation. */
5007 if (IWineD3D_GetAdapterCount(iface) && adapter_idx >= IWineD3D_GetAdapterCount(iface))
5008 {
5009 return WINED3DERR_INVALIDCALL;
5010 }
5011
5012 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
5013 if (!object)
5014 {
5015 ERR("Failed to allocate device memory.\n");
5016 return E_OUTOFMEMORY;
5017 }
5018
5019 hr = device_init(object, This, adapter_idx, device_type, focus_window, flags, parent, device_parent);
5020 if (FAILED(hr))
5021 {
5022 WARN("Failed to initialize device, hr %#x.\n", hr);
5023 HeapFree(GetProcessHeap(), 0, object);
5024 return hr;
5025 }
5026
5027 TRACE("Created device %p.\n", object);
5028 *device = (IWineD3DDevice *)object;
5029
5030 IWineD3DDeviceParent_WineD3DDeviceCreated(device_parent, *device);
5031
5032 return WINED3D_OK;
5033}
5034
5035static HRESULT WINAPI IWineD3DImpl_GetParent(IWineD3D *iface, IUnknown **pParent) {
5036 IWineD3DImpl *This = (IWineD3DImpl *)iface;
5037 IUnknown_AddRef(This->parent);
5038 *pParent = This->parent;
5039 return WINED3D_OK;
5040}
5041
5042static void WINE_GLAPI invalid_func(const void *data)
5043{
5044 ERR("Invalid vertex attribute function called\n");
5045 DebugBreak();
5046}
5047
5048static void WINE_GLAPI invalid_texcoord_func(GLenum unit, const void *data)
5049{
5050 ERR("Invalid texcoord function called\n");
5051 DebugBreak();
5052}
5053
5054/* Helper functions for providing vertex data to opengl. The arrays are initialized based on
5055 * the extension detection and are used in drawStridedSlow
5056 */
5057static void WINE_GLAPI position_d3dcolor(const void *data)
5058{
5059 DWORD pos = *((const DWORD *)data);
5060
5061 FIXME("Add a test for fixed function position from d3dcolor type\n");
5062 glVertex4s(D3DCOLOR_B_R(pos),
5063 D3DCOLOR_B_G(pos),
5064 D3DCOLOR_B_B(pos),
5065 D3DCOLOR_B_A(pos));
5066}
5067
5068static void WINE_GLAPI position_float4(const void *data)
5069{
5070 const GLfloat *pos = data;
5071
5072 if (pos[3] != 0.0f && pos[3] != 1.0f)
5073 {
5074 float w = 1.0f / pos[3];
5075
5076 glVertex4f(pos[0] * w, pos[1] * w, pos[2] * w, w);
5077 }
5078 else
5079 {
5080 glVertex3fv(pos);
5081 }
5082}
5083
5084static void WINE_GLAPI diffuse_d3dcolor(const void *data)
5085{
5086 DWORD diffuseColor = *((const DWORD *)data);
5087
5088 glColor4ub(D3DCOLOR_B_R(diffuseColor),
5089 D3DCOLOR_B_G(diffuseColor),
5090 D3DCOLOR_B_B(diffuseColor),
5091 D3DCOLOR_B_A(diffuseColor));
5092}
5093
5094static void WINE_GLAPI specular_d3dcolor(const void *data)
5095{
5096 DWORD specularColor = *((const DWORD *)data);
5097 GLbyte d[] = {D3DCOLOR_B_R(specularColor),
5098 D3DCOLOR_B_G(specularColor),
5099 D3DCOLOR_B_B(specularColor)};
5100
5101 specular_func_3ubv(d);
5102}
5103
5104static void WINE_GLAPI warn_no_specular_func(const void *data)
5105{
5106 WARN("GL_EXT_secondary_color not supported\n");
5107}
5108
5109static void fillGLAttribFuncs(const struct wined3d_gl_info *gl_info)
5110{
5111 position_funcs[WINED3D_FFP_EMIT_FLOAT1] = invalid_func;
5112 position_funcs[WINED3D_FFP_EMIT_FLOAT2] = invalid_func;
5113 position_funcs[WINED3D_FFP_EMIT_FLOAT3] = (glAttribFunc)glVertex3fv;
5114 position_funcs[WINED3D_FFP_EMIT_FLOAT4] = position_float4;
5115 position_funcs[WINED3D_FFP_EMIT_D3DCOLOR] = position_d3dcolor;
5116 position_funcs[WINED3D_FFP_EMIT_UBYTE4] = invalid_func;
5117 position_funcs[WINED3D_FFP_EMIT_SHORT2] = invalid_func;
5118 position_funcs[WINED3D_FFP_EMIT_SHORT4] = (glAttribFunc)glVertex2sv;
5119 position_funcs[WINED3D_FFP_EMIT_UBYTE4N] = invalid_func;
5120 position_funcs[WINED3D_FFP_EMIT_SHORT2N] = invalid_func;
5121 position_funcs[WINED3D_FFP_EMIT_SHORT4N] = invalid_func;
5122 position_funcs[WINED3D_FFP_EMIT_USHORT2N] = invalid_func;
5123 position_funcs[WINED3D_FFP_EMIT_USHORT4N] = invalid_func;
5124 position_funcs[WINED3D_FFP_EMIT_UDEC3] = invalid_func;
5125 position_funcs[WINED3D_FFP_EMIT_DEC3N] = invalid_func;
5126 position_funcs[WINED3D_FFP_EMIT_FLOAT16_2] = invalid_func;
5127 position_funcs[WINED3D_FFP_EMIT_FLOAT16_4] = invalid_func;
5128
5129 diffuse_funcs[WINED3D_FFP_EMIT_FLOAT1] = invalid_func;
5130 diffuse_funcs[WINED3D_FFP_EMIT_FLOAT2] = invalid_func;
5131 diffuse_funcs[WINED3D_FFP_EMIT_FLOAT3] = (glAttribFunc)glColor3fv;
5132 diffuse_funcs[WINED3D_FFP_EMIT_FLOAT4] = (glAttribFunc)glColor4fv;
5133 diffuse_funcs[WINED3D_FFP_EMIT_D3DCOLOR] = diffuse_d3dcolor;
5134 diffuse_funcs[WINED3D_FFP_EMIT_UBYTE4] = invalid_func;
5135 diffuse_funcs[WINED3D_FFP_EMIT_SHORT2] = invalid_func;
5136 diffuse_funcs[WINED3D_FFP_EMIT_SHORT4] = invalid_func;
5137 diffuse_funcs[WINED3D_FFP_EMIT_UBYTE4N] = (glAttribFunc)glColor4ubv;
5138 diffuse_funcs[WINED3D_FFP_EMIT_SHORT2N] = invalid_func;
5139 diffuse_funcs[WINED3D_FFP_EMIT_SHORT4N] = (glAttribFunc)glColor4sv;
5140 diffuse_funcs[WINED3D_FFP_EMIT_USHORT2N] = invalid_func;
5141 diffuse_funcs[WINED3D_FFP_EMIT_USHORT4N] = (glAttribFunc)glColor4usv;
5142 diffuse_funcs[WINED3D_FFP_EMIT_UDEC3] = invalid_func;
5143 diffuse_funcs[WINED3D_FFP_EMIT_DEC3N] = invalid_func;
5144 diffuse_funcs[WINED3D_FFP_EMIT_FLOAT16_2] = invalid_func;
5145 diffuse_funcs[WINED3D_FFP_EMIT_FLOAT16_4] = invalid_func;
5146
5147 /* No 4 component entry points here */
5148 specular_funcs[WINED3D_FFP_EMIT_FLOAT1] = invalid_func;
5149 specular_funcs[WINED3D_FFP_EMIT_FLOAT2] = invalid_func;
5150 if (gl_info->supported[EXT_SECONDARY_COLOR])
5151 {
5152 specular_funcs[WINED3D_FFP_EMIT_FLOAT3] = (glAttribFunc)GL_EXTCALL(glSecondaryColor3fvEXT);
5153 }
5154 else
5155 {
5156 specular_funcs[WINED3D_FFP_EMIT_FLOAT3] = warn_no_specular_func;
5157 }
5158 specular_funcs[WINED3D_FFP_EMIT_FLOAT4] = invalid_func;
5159 if (gl_info->supported[EXT_SECONDARY_COLOR])
5160 {
5161 specular_func_3ubv = (glAttribFunc)GL_EXTCALL(glSecondaryColor3ubvEXT);
5162 specular_funcs[WINED3D_FFP_EMIT_D3DCOLOR] = specular_d3dcolor;
5163 }
5164 else
5165 {
5166 specular_funcs[WINED3D_FFP_EMIT_D3DCOLOR] = warn_no_specular_func;
5167 }
5168 specular_funcs[WINED3D_FFP_EMIT_UBYTE4] = invalid_func;
5169 specular_funcs[WINED3D_FFP_EMIT_SHORT2] = invalid_func;
5170 specular_funcs[WINED3D_FFP_EMIT_SHORT4] = invalid_func;
5171 specular_funcs[WINED3D_FFP_EMIT_UBYTE4N] = invalid_func;
5172 specular_funcs[WINED3D_FFP_EMIT_SHORT2N] = invalid_func;
5173 specular_funcs[WINED3D_FFP_EMIT_SHORT4N] = invalid_func;
5174 specular_funcs[WINED3D_FFP_EMIT_USHORT2N] = invalid_func;
5175 specular_funcs[WINED3D_FFP_EMIT_USHORT4N] = invalid_func;
5176 specular_funcs[WINED3D_FFP_EMIT_UDEC3] = invalid_func;
5177 specular_funcs[WINED3D_FFP_EMIT_DEC3N] = invalid_func;
5178 specular_funcs[WINED3D_FFP_EMIT_FLOAT16_2] = invalid_func;
5179 specular_funcs[WINED3D_FFP_EMIT_FLOAT16_4] = invalid_func;
5180
5181 /* Only 3 component entry points here. Test how others behave. Float4 normals are used
5182 * by one of our tests, trying to pass it to the pixel shader, which fails on Windows.
5183 */
5184 normal_funcs[WINED3D_FFP_EMIT_FLOAT1] = invalid_func;
5185 normal_funcs[WINED3D_FFP_EMIT_FLOAT2] = invalid_func;
5186 normal_funcs[WINED3D_FFP_EMIT_FLOAT3] = (glAttribFunc)glNormal3fv;
5187 normal_funcs[WINED3D_FFP_EMIT_FLOAT4] = (glAttribFunc)glNormal3fv; /* Just ignore the 4th value */
5188 normal_funcs[WINED3D_FFP_EMIT_D3DCOLOR] = invalid_func;
5189 normal_funcs[WINED3D_FFP_EMIT_UBYTE4] = invalid_func;
5190 normal_funcs[WINED3D_FFP_EMIT_SHORT2] = invalid_func;
5191 normal_funcs[WINED3D_FFP_EMIT_SHORT4] = invalid_func;
5192 normal_funcs[WINED3D_FFP_EMIT_UBYTE4N] = invalid_func;
5193 normal_funcs[WINED3D_FFP_EMIT_SHORT2N] = invalid_func;
5194 normal_funcs[WINED3D_FFP_EMIT_SHORT4N] = invalid_func;
5195 normal_funcs[WINED3D_FFP_EMIT_USHORT2N] = invalid_func;
5196 normal_funcs[WINED3D_FFP_EMIT_USHORT4N] = invalid_func;
5197 normal_funcs[WINED3D_FFP_EMIT_UDEC3] = invalid_func;
5198 normal_funcs[WINED3D_FFP_EMIT_DEC3N] = invalid_func;
5199 normal_funcs[WINED3D_FFP_EMIT_FLOAT16_2] = invalid_func;
5200 normal_funcs[WINED3D_FFP_EMIT_FLOAT16_4] = invalid_func;
5201
5202 multi_texcoord_funcs[WINED3D_FFP_EMIT_FLOAT1] = (glMultiTexCoordFunc)GL_EXTCALL(glMultiTexCoord1fvARB);
5203 multi_texcoord_funcs[WINED3D_FFP_EMIT_FLOAT2] = (glMultiTexCoordFunc)GL_EXTCALL(glMultiTexCoord2fvARB);
5204 multi_texcoord_funcs[WINED3D_FFP_EMIT_FLOAT3] = (glMultiTexCoordFunc)GL_EXTCALL(glMultiTexCoord3fvARB);
5205 multi_texcoord_funcs[WINED3D_FFP_EMIT_FLOAT4] = (glMultiTexCoordFunc)GL_EXTCALL(glMultiTexCoord4fvARB);
5206 multi_texcoord_funcs[WINED3D_FFP_EMIT_D3DCOLOR] = invalid_texcoord_func;
5207 multi_texcoord_funcs[WINED3D_FFP_EMIT_UBYTE4] = invalid_texcoord_func;
5208 multi_texcoord_funcs[WINED3D_FFP_EMIT_SHORT2] = (glMultiTexCoordFunc)GL_EXTCALL(glMultiTexCoord2svARB);
5209 multi_texcoord_funcs[WINED3D_FFP_EMIT_SHORT4] = (glMultiTexCoordFunc)GL_EXTCALL(glMultiTexCoord4svARB);
5210 multi_texcoord_funcs[WINED3D_FFP_EMIT_UBYTE4N] = invalid_texcoord_func;
5211 multi_texcoord_funcs[WINED3D_FFP_EMIT_SHORT2N] = invalid_texcoord_func;
5212 multi_texcoord_funcs[WINED3D_FFP_EMIT_SHORT4N] = invalid_texcoord_func;
5213 multi_texcoord_funcs[WINED3D_FFP_EMIT_USHORT2N] = invalid_texcoord_func;
5214 multi_texcoord_funcs[WINED3D_FFP_EMIT_USHORT4N] = invalid_texcoord_func;
5215 multi_texcoord_funcs[WINED3D_FFP_EMIT_UDEC3] = invalid_texcoord_func;
5216 multi_texcoord_funcs[WINED3D_FFP_EMIT_DEC3N] = invalid_texcoord_func;
5217 if (gl_info->supported[NV_HALF_FLOAT])
5218 {
5219 /* Not supported by ARB_HALF_FLOAT_VERTEX, so check for NV_HALF_FLOAT */
5220 multi_texcoord_funcs[WINED3D_FFP_EMIT_FLOAT16_2] = (glMultiTexCoordFunc)GL_EXTCALL(glMultiTexCoord2hvNV);
5221 multi_texcoord_funcs[WINED3D_FFP_EMIT_FLOAT16_4] = (glMultiTexCoordFunc)GL_EXTCALL(glMultiTexCoord4hvNV);
5222 } else {
5223 multi_texcoord_funcs[WINED3D_FFP_EMIT_FLOAT16_2] = invalid_texcoord_func;
5224 multi_texcoord_funcs[WINED3D_FFP_EMIT_FLOAT16_4] = invalid_texcoord_func;
5225 }
5226}
5227
5228static BOOL InitAdapters(IWineD3DImpl *This)
5229{
5230 static HMODULE mod_gl;
5231 BOOL ret;
5232 int ps_selected_mode, vs_selected_mode;
5233
5234 /* No need to hold any lock. The calling library makes sure only one thread calls
5235 * wined3d simultaneously
5236 */
5237
5238 TRACE("Initializing adapters\n");
5239
5240 if(!mod_gl) {
5241#ifdef USE_WIN32_OPENGL
5242#define USE_GL_FUNC(pfn) pfn = (void*)GetProcAddress(mod_gl, #pfn);
5243#if defined(VBOX_WITH_WDDM) || defined(VBOX_WINE_WITH_SINGLE_SWAPCHAIN_CONTEXT)
5244 BOOL (APIENTRY *pDrvValidateVersion)(DWORD) DECLSPEC_HIDDEN;
5245#ifdef VBOX_WDDM_WOW64
5246 mod_gl = LoadLibraryA("VBoxOGL-x86.dll");
5247#else
5248 mod_gl = LoadLibraryA("VBoxOGL.dll");
5249#endif
5250#else
5251 mod_gl = LoadLibraryA("opengl32.dll");
5252#endif
5253 if(!mod_gl) {
5254 ERR("Can't load opengl32.dll!\n");
5255 goto nogl_adapter;
5256 }
5257#if defined(VBOX_WITH_WDDM) || defined(VBOX_WINE_WITH_SINGLE_SWAPCHAIN_CONTEXT)
5258 /* init properly */
5259 pDrvValidateVersion = (void*)GetProcAddress(mod_gl, "DrvValidateVersion");
5260 if(!pDrvValidateVersion) {
5261 ERR("Can't get DrvValidateVersion\n");
5262 goto nogl_adapter;
5263 }
5264 if(!pDrvValidateVersion(1)) {
5265 ERR("DrvValidateVersion FAILED\n");
5266 goto nogl_adapter;
5267 }
5268#endif
5269#else
5270#define USE_GL_FUNC(pfn) pfn = (void*)pwglGetProcAddress(#pfn);
5271 /* To bypass the opengl32 thunks load wglGetProcAddress from gdi32 (glXGetProcAddress wrapper) instead of opengl32's */
5272 mod_gl = GetModuleHandleA("gdi32.dll");
5273#endif
5274 }
5275
5276/* Load WGL core functions from opengl32.dll */
5277#define USE_WGL_FUNC(pfn) p##pfn = (void*)GetProcAddress(mod_gl, #pfn);
5278 WGL_FUNCS_GEN;
5279#undef USE_WGL_FUNC
5280
5281 if(!pwglGetProcAddress) {
5282 ERR("Unable to load wglGetProcAddress!\n");
5283 goto nogl_adapter;
5284 }
5285
5286/* Dynamically load all GL core functions */
5287 GL_FUNCS_GEN;
5288#undef USE_GL_FUNC
5289
5290 /* Load glFinish and glFlush from opengl32.dll even if we're not using WIN32 opengl
5291 * otherwise because we have to use winex11.drv's override
5292 */
5293#ifdef USE_WIN32_OPENGL
5294 wglFinish = (void*)GetProcAddress(mod_gl, "glFinish");
5295 wglFlush = (void*)GetProcAddress(mod_gl, "glFlush");
5296#else
5297 wglFinish = (void*)pwglGetProcAddress("wglFinish");
5298 wglFlush = (void*)pwglGetProcAddress("wglFlush");
5299#endif
5300
5301 glEnableWINE = glEnable;
5302 glDisableWINE = glDisable;
5303
5304 /* For now only one default adapter */
5305 {
5306 struct wined3d_adapter *adapter = &This->adapters[0];
5307 const struct wined3d_gl_info *gl_info = &adapter->gl_info;
5308 struct wined3d_fake_gl_ctx fake_gl_ctx = {0};
5309 int iPixelFormat;
5310 int res;
5311 int i;
5312 WineD3D_PixelFormat *cfgs;
5313 DISPLAY_DEVICEW DisplayDevice;
5314 HDC hdc;
5315
5316 TRACE("Initializing default adapter\n");
5317 adapter->ordinal = 0;
5318 adapter->monitorPoint.x = -1;
5319 adapter->monitorPoint.y = -1;
5320
5321 if (!AllocateLocallyUniqueId(&adapter->luid))
5322 {
5323 DWORD err = GetLastError();
5324 ERR("Failed to set adapter LUID (%#x).\n", err);
5325 goto nogl_adapter;
5326 }
5327 TRACE("Allocated LUID %08x:%08x for adapter.\n",
5328 adapter->luid.HighPart, adapter->luid.LowPart);
5329
5330 if (!WineD3D_CreateFakeGLContext(&fake_gl_ctx))
5331 {
5332 ERR("Failed to get a gl context for default adapter\n");
5333 goto nogl_adapter;
5334 }
5335
5336 ret = IWineD3DImpl_FillGLCaps(adapter);
5337 if(!ret) {
5338 ERR("Failed to initialize gl caps for default adapter\n");
5339 WineD3D_ReleaseFakeGLContext(&fake_gl_ctx);
5340 goto nogl_adapter;
5341 }
5342 ret = initPixelFormats(&adapter->gl_info, adapter->driver_info.vendor);
5343 if(!ret) {
5344 ERR("Failed to init gl formats\n");
5345 WineD3D_ReleaseFakeGLContext(&fake_gl_ctx);
5346 goto nogl_adapter;
5347 }
5348
5349 hdc = fake_gl_ctx.dc;
5350
5351 /* Use the VideoRamSize registry setting when set */
5352 if(wined3d_settings.emulated_textureram)
5353 adapter->TextureRam = wined3d_settings.emulated_textureram;
5354 else
5355 adapter->TextureRam = adapter->gl_info.vidmem;
5356 adapter->UsedTextureRam = 0;
5357 TRACE("Emulating %dMB of texture ram\n", adapter->TextureRam/(1024*1024));
5358
5359 /* Initialize the Adapter's DeviceName which is required for ChangeDisplaySettings and friends */
5360 DisplayDevice.cb = sizeof(DisplayDevice);
5361 EnumDisplayDevicesW(NULL, 0 /* Adapter 0 = iDevNum 0 */, &DisplayDevice, 0);
5362 TRACE("DeviceName: %s\n", debugstr_w(DisplayDevice.DeviceName));
5363 strcpyW(adapter->DeviceName, DisplayDevice.DeviceName);
5364
5365 if (gl_info->supported[WGL_ARB_PIXEL_FORMAT])
5366 {
5367 int attribute;
5368 int attribs[11];
5369 int values[11];
5370 int nAttribs = 0;
5371
5372 attribute = WGL_NUMBER_PIXEL_FORMATS_ARB;
5373 GL_EXTCALL(wglGetPixelFormatAttribivARB(hdc, 0, 0, 1, &attribute, &adapter->nCfgs));
5374
5375 adapter->cfgs = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, adapter->nCfgs *sizeof(WineD3D_PixelFormat));
5376 cfgs = adapter->cfgs;
5377 attribs[nAttribs++] = WGL_RED_BITS_ARB;
5378 attribs[nAttribs++] = WGL_GREEN_BITS_ARB;
5379 attribs[nAttribs++] = WGL_BLUE_BITS_ARB;
5380 attribs[nAttribs++] = WGL_ALPHA_BITS_ARB;
5381 attribs[nAttribs++] = WGL_COLOR_BITS_ARB;
5382 attribs[nAttribs++] = WGL_DEPTH_BITS_ARB;
5383 attribs[nAttribs++] = WGL_STENCIL_BITS_ARB;
5384 attribs[nAttribs++] = WGL_DRAW_TO_WINDOW_ARB;
5385 attribs[nAttribs++] = WGL_PIXEL_TYPE_ARB;
5386 attribs[nAttribs++] = WGL_DOUBLE_BUFFER_ARB;
5387 attribs[nAttribs++] = WGL_AUX_BUFFERS_ARB;
5388
5389 for (iPixelFormat=1; iPixelFormat <= adapter->nCfgs; ++iPixelFormat)
5390 {
5391 res = GL_EXTCALL(wglGetPixelFormatAttribivARB(hdc, iPixelFormat, 0, nAttribs, attribs, values));
5392
5393 if(!res)
5394 continue;
5395
5396 /* Cache the pixel format */
5397 cfgs->iPixelFormat = iPixelFormat;
5398 cfgs->redSize = values[0];
5399 cfgs->greenSize = values[1];
5400 cfgs->blueSize = values[2];
5401 cfgs->alphaSize = values[3];
5402 cfgs->colorSize = values[4];
5403 cfgs->depthSize = values[5];
5404 cfgs->stencilSize = values[6];
5405 cfgs->windowDrawable = values[7];
5406 cfgs->iPixelType = values[8];
5407 cfgs->doubleBuffer = values[9];
5408 cfgs->auxBuffers = values[10];
5409
5410 cfgs->numSamples = 0;
5411 /* Check multisample support */
5412 if (gl_info->supported[ARB_MULTISAMPLE])
5413 {
5414 int attrib[2] = {WGL_SAMPLE_BUFFERS_ARB, WGL_SAMPLES_ARB};
5415 int value[2];
5416 if(GL_EXTCALL(wglGetPixelFormatAttribivARB(hdc, iPixelFormat, 0, 2, attrib, value))) {
5417 /* value[0] = WGL_SAMPLE_BUFFERS_ARB which tells whether multisampling is supported.
5418 * value[1] = number of multi sample buffers*/
5419 if(value[0])
5420 cfgs->numSamples = value[1];
5421 }
5422 }
5423
5424 TRACE("iPixelFormat=%d, iPixelType=%#x, doubleBuffer=%d, RGBA=%d/%d/%d/%d, "
5425 "depth=%d, stencil=%d, samples=%d, windowDrawable=%d\n",
5426 cfgs->iPixelFormat, cfgs->iPixelType, cfgs->doubleBuffer,
5427 cfgs->redSize, cfgs->greenSize, cfgs->blueSize, cfgs->alphaSize,
5428 cfgs->depthSize, cfgs->stencilSize, cfgs->numSamples, cfgs->windowDrawable);
5429 cfgs++;
5430 }
5431 }
5432 else
5433 {
5434 int nCfgs = DescribePixelFormat(hdc, 0, 0, 0);
5435 adapter->cfgs = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, nCfgs*sizeof(WineD3D_PixelFormat));
5436 adapter->nCfgs = 0; /* We won't accept all formats e.g. software accelerated ones will be skipped */
5437
5438 cfgs = adapter->cfgs;
5439 for(iPixelFormat=1; iPixelFormat<=nCfgs; iPixelFormat++)
5440 {
5441 PIXELFORMATDESCRIPTOR ppfd;
5442
5443 res = DescribePixelFormat(hdc, iPixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &ppfd);
5444 if(!res)
5445 continue;
5446
5447 /* We only want HW acceleration using an OpenGL ICD driver.
5448 * PFD_GENERIC_FORMAT = slow opengl 1.1 gdi software rendering
5449 * PFD_GENERIC_ACCELERATED = partial hw acceleration using a MCD driver (e.g. 3dfx minigl)
5450 */
5451 if(ppfd.dwFlags & (PFD_GENERIC_FORMAT | PFD_GENERIC_ACCELERATED))
5452 {
5453 TRACE("Skipping iPixelFormat=%d because it isn't ICD accelerated\n", iPixelFormat);
5454 continue;
5455 }
5456
5457 cfgs->iPixelFormat = iPixelFormat;
5458 cfgs->redSize = ppfd.cRedBits;
5459 cfgs->greenSize = ppfd.cGreenBits;
5460 cfgs->blueSize = ppfd.cBlueBits;
5461 cfgs->alphaSize = ppfd.cAlphaBits;
5462 cfgs->colorSize = ppfd.cColorBits;
5463 cfgs->depthSize = ppfd.cDepthBits;
5464 cfgs->stencilSize = ppfd.cStencilBits;
5465 cfgs->windowDrawable = (ppfd.dwFlags & PFD_DRAW_TO_WINDOW) ? 1 : 0;
5466 cfgs->iPixelType = (ppfd.iPixelType == PFD_TYPE_RGBA) ? WGL_TYPE_RGBA_ARB : WGL_TYPE_COLORINDEX_ARB;
5467 cfgs->doubleBuffer = (ppfd.dwFlags & PFD_DOUBLEBUFFER) ? 1 : 0;
5468 cfgs->auxBuffers = ppfd.cAuxBuffers;
5469 cfgs->numSamples = 0;
5470
5471 TRACE("iPixelFormat=%d, iPixelType=%#x, doubleBuffer=%d, RGBA=%d/%d/%d/%d, "
5472 "depth=%d, stencil=%d, windowDrawable=%d\n",
5473 cfgs->iPixelFormat, cfgs->iPixelType, cfgs->doubleBuffer,
5474 cfgs->redSize, cfgs->greenSize, cfgs->blueSize, cfgs->alphaSize,
5475 cfgs->depthSize, cfgs->stencilSize, cfgs->windowDrawable);
5476 cfgs++;
5477 adapter->nCfgs++;
5478 }
5479
5480 /* 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 */
5481 if(!adapter->nCfgs)
5482 {
5483 ERR("Disabling Direct3D because no hardware accelerated pixel formats have been found!\n");
5484
5485 WineD3D_ReleaseFakeGLContext(&fake_gl_ctx);
5486 HeapFree(GetProcessHeap(), 0, adapter->cfgs);
5487 goto nogl_adapter;
5488 }
5489 }
5490
5491 /* D16, D24X8 and D24S8 are common depth / depth+stencil formats. All drivers support them though this doesn't
5492 * mean that the format is offered in hardware. For instance Geforce8 cards don't have offer D16 in hardware
5493 * but just fake it using D24(X8?) which is fine. D3D also allows that.
5494 * Some display drivers (i915 on Linux) only report mixed depth+stencil formats like D24S8. MSDN clearly mentions
5495 * that only on lockable formats (e.g. D16_locked) the bit order is guaranteed and that on other formats the
5496 * driver is allowed to consume more bits EXCEPT for stencil bits.
5497 *
5498 * Mark an adapter with this broken stencil behavior.
5499 */
5500 adapter->brokenStencil = TRUE;
5501 for (i = 0, cfgs = adapter->cfgs; i < adapter->nCfgs; ++i)
5502 {
5503 /* Nearly all drivers offer depth formats without stencil, only on i915 this if-statement won't be entered. */
5504 if(cfgs[i].depthSize && !cfgs[i].stencilSize) {
5505 adapter->brokenStencil = FALSE;
5506 break;
5507 }
5508 }
5509
5510 WineD3D_ReleaseFakeGLContext(&fake_gl_ctx);
5511
5512 select_shader_mode(&adapter->gl_info, &ps_selected_mode, &vs_selected_mode);
5513 fillGLAttribFuncs(&adapter->gl_info);
5514 adapter->opengl = TRUE;
5515 }
5516 This->adapter_count = 1;
5517 TRACE("%u adapters successfully initialized\n", This->adapter_count);
5518
5519 return TRUE;
5520
5521nogl_adapter:
5522 /* Initialize an adapter for ddraw-only memory counting */
5523 memset(This->adapters, 0, sizeof(This->adapters));
5524 This->adapters[0].ordinal = 0;
5525 This->adapters[0].opengl = FALSE;
5526 This->adapters[0].monitorPoint.x = -1;
5527 This->adapters[0].monitorPoint.y = -1;
5528
5529 This->adapters[0].driver_info.name = "Display";
5530 This->adapters[0].driver_info.description = "WineD3D DirectDraw Emulation";
5531 if(wined3d_settings.emulated_textureram) {
5532 This->adapters[0].TextureRam = wined3d_settings.emulated_textureram;
5533 } else {
5534 This->adapters[0].TextureRam = 8 * 1024 * 1024; /* This is plenty for a DDraw-only card */
5535 }
5536
5537 initPixelFormatsNoGL(&This->adapters[0].gl_info);
5538
5539 This->adapter_count = 1;
5540 return FALSE;
5541}
5542
5543/**********************************************************
5544 * IWineD3D VTbl follows
5545 **********************************************************/
5546
5547static const struct IWineD3DVtbl IWineD3D_Vtbl =
5548{
5549 /* IUnknown */
5550 IWineD3DImpl_QueryInterface,
5551 IWineD3DImpl_AddRef,
5552 IWineD3DImpl_Release,
5553 /* IWineD3D */
5554 IWineD3DImpl_GetParent,
5555 IWineD3DImpl_GetAdapterCount,
5556 IWineD3DImpl_RegisterSoftwareDevice,
5557 IWineD3DImpl_GetAdapterMonitor,
5558 IWineD3DImpl_GetAdapterModeCount,
5559 IWineD3DImpl_EnumAdapterModes,
5560 IWineD3DImpl_GetAdapterDisplayMode,
5561 IWineD3DImpl_GetAdapterDisplayModeEx,
5562 IWineD3DImpl_GetAdapterIdentifier,
5563 IWineD3DImpl_CheckDeviceMultiSampleType,
5564 IWineD3DImpl_CheckDepthStencilMatch,
5565 IWineD3DImpl_CheckDeviceType,
5566 IWineD3DImpl_CheckDeviceFormat,
5567 IWineD3DImpl_CheckDeviceFormatConversion,
5568 IWineD3DImpl_GetDeviceCaps,
5569 IWineD3DImpl_CreateDevice
5570};
5571
5572static void STDMETHODCALLTYPE wined3d_null_wined3d_object_destroyed(void *parent) {}
5573
5574const struct wined3d_parent_ops wined3d_null_parent_ops =
5575{
5576 wined3d_null_wined3d_object_destroyed,
5577};
5578
5579HRESULT wined3d_init(IWineD3DImpl *wined3d, UINT version, IUnknown *parent)
5580{
5581 wined3d->lpVtbl = &IWineD3D_Vtbl;
5582 wined3d->dxVersion = version;
5583 wined3d->ref = 1;
5584 wined3d->parent = parent;
5585
5586 if (!InitAdapters(wined3d))
5587 {
5588 WARN("Failed to initialize adapters.\n");
5589 if (version > 7)
5590 {
5591 MESSAGE("Direct3D%u is not available without OpenGL.\n", version);
5592 return E_FAIL;
5593 }
5594 }
5595
5596 return WINED3D_OK;
5597}
Note: See TracBrowser for help on using the repository browser.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette