VirtualBox

source: vbox/trunk/src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/directx.c@ 69496

Last change on this file since 69496 was 68890, checked in by vboxsync, 7 years ago

Additions/WDDM: Corrected loading DEBUG versions of VBoxOGL*.dll libraries, bugref:8998

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