VirtualBox

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

Last change on this file since 38438 was 38112, checked in by vboxsync, 14 years ago

wddm/3d: 1. fix invalid visible rectreporting on swapchain destruction 2. single context for wine (disabled so far), 3 wine & 3d driver bugfixes

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