VirtualBox

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

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

wine/XPDM: 1. Additional swapchain creation fixes 2. De-libwine'ize wined3d 3. Single context per swapchain 4. wine & crOgl current context sync fixes 5. Proper Get/ReleaseDC handling

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

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