VirtualBox

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

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

wine: reenable shaver v3 support

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

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