2 * IWineD3D implementation
4 * Copyright 2002-2004 Jason Edmeades
5 * Copyright 2003-2004 Raphael Junqueira
6 * Copyright 2004 Christian Costa
7 * Copyright 2005 Oliver Stieber
8 * Copyright 2007-2008 Stefan Dösinger for CodeWeavers
9 * Copyright 2009 Henri Verbeet for CodeWeavers
11 * This library is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU Lesser General Public
13 * License as published by the Free Software Foundation; either
14 * version 2.1 of the License, or (at your option) any later version.
16 * This library is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * Lesser General Public License for more details.
21 * You should have received a copy of the GNU Lesser General Public
22 * License along with this library; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
28 #include "wined3d_private.h"
30 WINE_DEFAULT_DEBUG_CHANNEL(d3d
);
31 WINE_DECLARE_DEBUG_CHANNEL(d3d_caps
);
33 #define WINE_DEFAULT_VIDMEM (64 * 1024 * 1024)
35 /* The d3d device ID */
36 static const GUID IID_D3DDEVICE_D3DUID
= { 0xaeb2cdd4, 0x6e41, 0x43ea, { 0x94,0x1c,0x83,0x61,0xcc,0x76,0x07,0x81 } };
38 /* Extension detection */
40 const char *extension_string
;
41 GL_SupportedExt extension
;
45 {"GL_APPLE_client_storage", APPLE_CLIENT_STORAGE
, 0 },
46 {"GL_APPLE_fence", APPLE_FENCE
, 0 },
47 {"GL_APPLE_float_pixels", APPLE_FLOAT_PIXELS
, 0 },
48 {"GL_APPLE_flush_buffer_range", APPLE_FLUSH_BUFFER_RANGE
, 0 },
49 {"GL_APPLE_flush_render", APPLE_FLUSH_RENDER
, 0 },
50 {"GL_APPLE_ycbcr_422", APPLE_YCBCR_422
, 0 },
53 {"GL_ARB_color_buffer_float", ARB_COLOR_BUFFER_FLOAT
, 0 },
54 {"GL_ARB_depth_buffer_float", ARB_DEPTH_BUFFER_FLOAT
, 0 },
55 {"GL_ARB_depth_clamp", ARB_DEPTH_CLAMP
, 0 },
56 {"GL_ARB_depth_texture", ARB_DEPTH_TEXTURE
, 0 },
57 {"GL_ARB_draw_buffers", ARB_DRAW_BUFFERS
, 0 },
58 {"GL_ARB_fragment_program", ARB_FRAGMENT_PROGRAM
, 0 },
59 {"GL_ARB_fragment_shader", ARB_FRAGMENT_SHADER
, 0 },
60 {"GL_ARB_framebuffer_object", ARB_FRAMEBUFFER_OBJECT
, 0 },
61 {"GL_ARB_geometry_shader4", ARB_GEOMETRY_SHADER4
, 0 },
62 {"GL_ARB_half_float_pixel", ARB_HALF_FLOAT_PIXEL
, 0 },
63 {"GL_ARB_half_float_vertex", ARB_HALF_FLOAT_VERTEX
, 0 },
64 {"GL_ARB_imaging", ARB_IMAGING
, 0 },
65 {"GL_ARB_map_buffer_range", ARB_MAP_BUFFER_RANGE
, 0 },
66 {"GL_ARB_multisample", ARB_MULTISAMPLE
, 0 }, /* needs GLX_ARB_MULTISAMPLE as well */
67 {"GL_ARB_multitexture", ARB_MULTITEXTURE
, 0 },
68 {"GL_ARB_occlusion_query", ARB_OCCLUSION_QUERY
, 0 },
69 {"GL_ARB_pixel_buffer_object", ARB_PIXEL_BUFFER_OBJECT
, 0 },
70 {"GL_ARB_point_parameters", ARB_POINT_PARAMETERS
, 0 },
71 {"GL_ARB_point_sprite", ARB_POINT_SPRITE
, 0 },
72 {"GL_ARB_provoking_vertex", ARB_PROVOKING_VERTEX
, 0 },
73 {"GL_ARB_shader_objects", ARB_SHADER_OBJECTS
, 0 },
74 {"GL_ARB_shader_texture_lod", ARB_SHADER_TEXTURE_LOD
, 0 },
75 {"GL_ARB_shading_language_100", ARB_SHADING_LANGUAGE_100
, 0 },
76 {"GL_ARB_shadow", ARB_SHADOW
, 0 },
77 {"GL_ARB_sync", ARB_SYNC
, 0 },
78 {"GL_ARB_texture_border_clamp", ARB_TEXTURE_BORDER_CLAMP
, 0 },
79 {"GL_ARB_texture_compression", ARB_TEXTURE_COMPRESSION
, 0 },
80 {"GL_ARB_texture_compression_rgtc", ARB_TEXTURE_COMPRESSION_RGTC
, 0 },
81 {"GL_ARB_texture_cube_map", ARB_TEXTURE_CUBE_MAP
, 0 },
82 {"GL_ARB_texture_env_add", ARB_TEXTURE_ENV_ADD
, 0 },
83 {"GL_ARB_texture_env_combine", ARB_TEXTURE_ENV_COMBINE
, 0 },
84 {"GL_ARB_texture_env_dot3", ARB_TEXTURE_ENV_DOT3
, 0 },
85 {"GL_ARB_texture_float", ARB_TEXTURE_FLOAT
, 0 },
86 {"GL_ARB_texture_mirrored_repeat", ARB_TEXTURE_MIRRORED_REPEAT
, 0 },
87 {"GL_ARB_texture_non_power_of_two", ARB_TEXTURE_NON_POWER_OF_TWO
, MAKEDWORD_VERSION(2, 0) },
88 {"GL_ARB_texture_rectangle", ARB_TEXTURE_RECTANGLE
, 0 },
89 {"GL_ARB_texture_rg", ARB_TEXTURE_RG
, 0 },
90 {"GL_ARB_vertex_array_bgra", ARB_VERTEX_ARRAY_BGRA
, 0 },
91 {"GL_ARB_vertex_blend", ARB_VERTEX_BLEND
, 0 },
92 {"GL_ARB_vertex_buffer_object", ARB_VERTEX_BUFFER_OBJECT
, 0 },
93 {"GL_ARB_vertex_program", ARB_VERTEX_PROGRAM
, 0 },
94 {"GL_ARB_vertex_shader", ARB_VERTEX_SHADER
, 0 },
97 {"GL_ATI_fragment_shader", ATI_FRAGMENT_SHADER
, 0 },
98 {"GL_ATI_separate_stencil", ATI_SEPARATE_STENCIL
, 0 },
99 {"GL_ATI_texture_compression_3dc", ATI_TEXTURE_COMPRESSION_3DC
, 0 },
100 {"GL_ATI_texture_env_combine3", ATI_TEXTURE_ENV_COMBINE3
, 0 },
101 {"GL_ATI_texture_mirror_once", ATI_TEXTURE_MIRROR_ONCE
, 0 },
104 {"GL_EXT_blend_color", EXT_BLEND_COLOR
, 0 },
105 {"GL_EXT_blend_equation_separate", EXT_BLEND_EQUATION_SEPARATE
, 0 },
106 {"GL_EXT_blend_func_separate", EXT_BLEND_FUNC_SEPARATE
, 0 },
107 {"GL_EXT_blend_minmax", EXT_BLEND_MINMAX
, 0 },
108 {"GL_EXT_draw_buffers2", EXT_DRAW_BUFFERS2
, 0 },
109 {"GL_EXT_fog_coord", EXT_FOG_COORD
, 0 },
110 {"GL_EXT_framebuffer_blit", EXT_FRAMEBUFFER_BLIT
, 0 },
111 {"GL_EXT_framebuffer_multisample", EXT_FRAMEBUFFER_MULTISAMPLE
, 0 },
112 {"GL_EXT_framebuffer_object", EXT_FRAMEBUFFER_OBJECT
, 0 },
113 {"GL_EXT_gpu_program_parameters", EXT_GPU_PROGRAM_PARAMETERS
, 0 },
114 {"GL_EXT_gpu_shader4", EXT_GPU_SHADER4
, 0 },
115 {"GL_EXT_packed_depth_stencil", EXT_PACKED_DEPTH_STENCIL
, 0 },
116 {"GL_EXT_paletted_texture", EXT_PALETTED_TEXTURE
, 0 },
117 {"GL_EXT_point_parameters", EXT_POINT_PARAMETERS
, 0 },
118 {"GL_EXT_provoking_vertex", EXT_PROVOKING_VERTEX
, 0 },
119 {"GL_EXT_secondary_color", EXT_SECONDARY_COLOR
, 0 },
120 {"GL_EXT_stencil_two_side", EXT_STENCIL_TWO_SIDE
, 0 },
121 {"GL_EXT_stencil_wrap", EXT_STENCIL_WRAP
, 0 },
122 {"GL_EXT_texture3D", EXT_TEXTURE3D
, MAKEDWORD_VERSION(1, 2) },
123 {"GL_EXT_texture_compression_rgtc", EXT_TEXTURE_COMPRESSION_RGTC
, 0 },
124 {"GL_EXT_texture_compression_s3tc", EXT_TEXTURE_COMPRESSION_S3TC
, 0 },
125 {"GL_EXT_texture_env_add", EXT_TEXTURE_ENV_ADD
, 0 },
126 {"GL_EXT_texture_env_combine", EXT_TEXTURE_ENV_COMBINE
, 0 },
127 {"GL_EXT_texture_env_dot3", EXT_TEXTURE_ENV_DOT3
, 0 },
128 {"GL_EXT_texture_filter_anisotropic", EXT_TEXTURE_FILTER_ANISOTROPIC
, 0 },
129 {"GL_EXT_texture_lod_bias", EXT_TEXTURE_LOD_BIAS
, 0 },
130 {"GL_EXT_texture_sRGB", EXT_TEXTURE_SRGB
, 0 },
131 {"GL_EXT_vertex_array_bgra", EXT_VERTEX_ARRAY_BGRA
, 0 },
134 {"GL_NV_depth_clamp", NV_DEPTH_CLAMP
, 0 },
135 {"GL_NV_fence", NV_FENCE
, 0 },
136 {"GL_NV_fog_distance", NV_FOG_DISTANCE
, 0 },
137 {"GL_NV_fragment_program", NV_FRAGMENT_PROGRAM
, 0 },
138 {"GL_NV_fragment_program2", NV_FRAGMENT_PROGRAM2
, 0 },
139 {"GL_NV_fragment_program_option", NV_FRAGMENT_PROGRAM_OPTION
, 0 },
140 {"GL_NV_half_float", NV_HALF_FLOAT
, 0 },
141 {"GL_NV_light_max_exponent", NV_LIGHT_MAX_EXPONENT
, 0 },
142 {"GL_NV_point_sprite", NV_POINT_SPRITE
, 0 },
143 {"GL_NV_register_combiners", NV_REGISTER_COMBINERS
, 0 },
144 {"GL_NV_register_combiners2", NV_REGISTER_COMBINERS2
, 0 },
145 {"GL_NV_texgen_reflection", NV_TEXGEN_REFLECTION
, 0 },
146 {"GL_NV_texture_env_combine4", NV_TEXTURE_ENV_COMBINE4
, 0 },
147 {"GL_NV_texture_shader", NV_TEXTURE_SHADER
, 0 },
148 {"GL_NV_texture_shader2", NV_TEXTURE_SHADER2
, 0 },
149 {"GL_NV_vertex_program", NV_VERTEX_PROGRAM
, 0 },
150 {"GL_NV_vertex_program1_1", NV_VERTEX_PROGRAM1_1
, 0 },
151 {"GL_NV_vertex_program2", NV_VERTEX_PROGRAM2
, 0 },
152 {"GL_NV_vertex_program2_option", NV_VERTEX_PROGRAM2_OPTION
, 0 },
153 {"GL_NV_vertex_program3", NV_VERTEX_PROGRAM3
, 0 },
156 {"GL_SGIS_generate_mipmap", SGIS_GENERATE_MIPMAP
, 0 },
159 /**********************************************************
160 * Utility functions follow
161 **********************************************************/
163 static HRESULT WINAPI
IWineD3DImpl_CheckDeviceFormat(IWineD3D
*iface
, UINT Adapter
,
164 WINED3DDEVTYPE DeviceType
, enum wined3d_format_id AdapterFormat
, DWORD Usage
,
165 WINED3DRESOURCETYPE RType
, enum wined3d_format_id CheckFormat
, WINED3DSURFTYPE SurfaceType
);
167 const struct min_lookup minMipLookup
[] =
169 /* NONE POINT LINEAR */
170 {{GL_NEAREST
, GL_NEAREST
, GL_NEAREST
}}, /* NONE */
171 {{GL_NEAREST
, GL_NEAREST_MIPMAP_NEAREST
, GL_NEAREST_MIPMAP_LINEAR
}}, /* POINT*/
172 {{GL_LINEAR
, GL_LINEAR_MIPMAP_NEAREST
, GL_LINEAR_MIPMAP_LINEAR
}}, /* LINEAR */
175 const struct min_lookup minMipLookup_noFilter
[] =
177 /* NONE POINT LINEAR */
178 {{GL_NEAREST
, GL_NEAREST
, GL_NEAREST
}}, /* NONE */
179 {{GL_NEAREST
, GL_NEAREST
, GL_NEAREST
}}, /* POINT */
180 {{GL_NEAREST
, GL_NEAREST
, GL_NEAREST
}}, /* LINEAR */
183 const struct min_lookup minMipLookup_noMip
[] =
185 /* NONE POINT LINEAR */
186 {{GL_NEAREST
, GL_NEAREST
, GL_NEAREST
}}, /* NONE */
187 {{GL_NEAREST
, GL_NEAREST
, GL_NEAREST
}}, /* POINT */
188 {{GL_LINEAR
, GL_LINEAR
, GL_LINEAR
}}, /* LINEAR */
191 const GLenum magLookup
[] =
193 /* NONE POINT LINEAR */
194 GL_NEAREST
, GL_NEAREST
, GL_LINEAR
,
197 const GLenum magLookup_noFilter
[] =
199 /* NONE POINT LINEAR */
200 GL_NEAREST
, GL_NEAREST
, GL_NEAREST
,
203 /* drawStridedSlow attributes */
204 glAttribFunc position_funcs
[WINED3D_FFP_EMIT_COUNT
];
205 glAttribFunc diffuse_funcs
[WINED3D_FFP_EMIT_COUNT
];
206 glAttribFunc specular_func_3ubv
;
207 glAttribFunc specular_funcs
[WINED3D_FFP_EMIT_COUNT
];
208 glAttribFunc normal_funcs
[WINED3D_FFP_EMIT_COUNT
];
209 glMultiTexCoordFunc multi_texcoord_funcs
[WINED3D_FFP_EMIT_COUNT
];
212 * Note: GL seems to trap if GetDeviceCaps is called before any HWND's created,
213 * i.e., there is no GL Context - Get a default rendering context to enable the
214 * function query some info from GL.
217 struct wined3d_fake_gl_ctx
223 HGLRC restore_gl_ctx
;
226 static void WineD3D_ReleaseFakeGLContext(struct wined3d_fake_gl_ctx
*ctx
)
228 TRACE_(d3d_caps
)("Destroying fake GL context.\n");
230 if (!pwglMakeCurrent(NULL
, NULL
))
232 ERR_(d3d_caps
)("Failed to disable fake GL context.\n");
235 if (!pwglDeleteContext(ctx
->gl_ctx
))
237 DWORD err
= GetLastError();
238 ERR("wglDeleteContext(%p) failed, last error %#x.\n", ctx
->gl_ctx
, err
);
241 ReleaseDC(ctx
->wnd
, ctx
->dc
);
242 DestroyWindow(ctx
->wnd
);
244 if (ctx
->restore_gl_ctx
&& !pwglMakeCurrent(ctx
->restore_dc
, ctx
->restore_gl_ctx
))
246 ERR_(d3d_caps
)("Failed to restore previous GL context.\n");
250 static BOOL
WineD3D_CreateFakeGLContext(struct wined3d_fake_gl_ctx
*ctx
)
252 PIXELFORMATDESCRIPTOR pfd
;
255 TRACE("getting context...\n");
257 ctx
->restore_dc
= pwglGetCurrentDC();
258 ctx
->restore_gl_ctx
= pwglGetCurrentContext();
260 /* We need a fake window as a hdc retrieved using GetDC(0) can't be used for much GL purposes. */
261 ctx
->wnd
= CreateWindowA(WINED3D_OPENGL_WINDOW_CLASS_NAME
, "WineD3D fake window",
262 WS_OVERLAPPEDWINDOW
, 10, 10, 10, 10, NULL
, NULL
, NULL
, NULL
);
265 ERR_(d3d_caps
)("Failed to create a window.\n");
269 ctx
->dc
= GetDC(ctx
->wnd
);
272 ERR_(d3d_caps
)("Failed to get a DC.\n");
276 /* PixelFormat selection */
277 ZeroMemory(&pfd
, sizeof(pfd
));
278 pfd
.nSize
= sizeof(pfd
);
280 pfd
.dwFlags
= PFD_SUPPORT_OPENGL
| PFD_DOUBLEBUFFER
| PFD_DRAW_TO_WINDOW
; /* PFD_GENERIC_ACCELERATED */
281 pfd
.iPixelType
= PFD_TYPE_RGBA
;
283 pfd
.iLayerType
= PFD_MAIN_PLANE
;
285 iPixelFormat
= ChoosePixelFormat(ctx
->dc
, &pfd
);
288 /* If this happens something is very wrong as ChoosePixelFormat barely fails. */
289 ERR_(d3d_caps
)("Can't find a suitable iPixelFormat.\n");
292 DescribePixelFormat(ctx
->dc
, iPixelFormat
, sizeof(pfd
), &pfd
);
293 SetPixelFormat(ctx
->dc
, iPixelFormat
, &pfd
);
295 /* Create a GL context. */
296 ctx
->gl_ctx
= pwglCreateContext(ctx
->dc
);
299 WARN_(d3d_caps
)("Error creating default context for capabilities initialization.\n");
303 /* Make it the current GL context. */
304 if (!context_set_current(NULL
))
306 ERR_(d3d_caps
)("Failed to clear current D3D context.\n");
309 if (!pwglMakeCurrent(ctx
->dc
, ctx
->gl_ctx
))
311 ERR_(d3d_caps
)("Failed to make fake GL context current.\n");
318 if (ctx
->gl_ctx
) pwglDeleteContext(ctx
->gl_ctx
);
320 if (ctx
->dc
) ReleaseDC(ctx
->wnd
, ctx
->dc
);
322 if (ctx
->wnd
) DestroyWindow(ctx
->wnd
);
324 if (ctx
->restore_gl_ctx
&& !pwglMakeCurrent(ctx
->restore_dc
, ctx
->restore_gl_ctx
))
326 ERR_(d3d_caps
)("Failed to restore previous GL context.\n");
332 /* Adjust the amount of used texture memory */
333 unsigned int WineD3DAdapterChangeGLRam(IWineD3DDeviceImpl
*device
, unsigned int glram
)
335 struct wined3d_adapter
*adapter
= device
->adapter
;
337 adapter
->UsedTextureRam
+= glram
;
338 TRACE("Adjusted gl ram by %d to %d\n", glram
, adapter
->UsedTextureRam
);
339 return adapter
->UsedTextureRam
;
342 static void wined3d_adapter_cleanup(struct wined3d_adapter
*adapter
)
344 HeapFree(GetProcessHeap(), 0, adapter
->gl_info
.gl_formats
);
345 HeapFree(GetProcessHeap(), 0, adapter
->cfgs
);
348 /**********************************************************
349 * IUnknown parts follows
350 **********************************************************/
352 static HRESULT WINAPI
IWineD3DImpl_QueryInterface(IWineD3D
*iface
,REFIID riid
,LPVOID
*ppobj
)
354 IWineD3DDeviceImpl
*This
= (IWineD3DDeviceImpl
*)iface
;
356 TRACE("(%p)->(%s,%p)\n",This
,debugstr_guid(riid
),ppobj
);
357 if (IsEqualGUID(riid
, &IID_IUnknown
)
358 || IsEqualGUID(riid
, &IID_IWineD3DBase
)
359 || IsEqualGUID(riid
, &IID_IWineD3DDevice
)) {
360 IUnknown_AddRef(iface
);
365 return E_NOINTERFACE
;
368 static ULONG WINAPI
IWineD3DImpl_AddRef(IWineD3D
*iface
) {
369 IWineD3DImpl
*This
= (IWineD3DImpl
*)iface
;
370 ULONG refCount
= InterlockedIncrement(&This
->ref
);
372 TRACE("(%p) : AddRef increasing from %d\n", This
, refCount
- 1);
376 static ULONG WINAPI
IWineD3DImpl_Release(IWineD3D
*iface
) {
377 IWineD3DImpl
*This
= (IWineD3DImpl
*)iface
;
379 TRACE("(%p) : Releasing from %d\n", This
, This
->ref
);
380 ref
= InterlockedDecrement(&This
->ref
);
384 for (i
= 0; i
< This
->adapter_count
; ++i
)
386 wined3d_adapter_cleanup(&This
->adapters
[i
]);
388 HeapFree(GetProcessHeap(), 0, This
);
394 /**********************************************************
395 * IWineD3D parts follows
396 **********************************************************/
398 /* GL locking is done by the caller */
399 static inline BOOL
test_arb_vs_offset_limit(const struct wined3d_gl_info
*gl_info
)
403 const char *testcode
=
405 "PARAM C[66] = { program.env[0..65] };\n"
407 "PARAM zero = {0.0, 0.0, 0.0, 0.0};\n"
408 "ARL A0.x, zero.x;\n"
409 "MOV result.position, C[A0.x + 65];\n"
413 GL_EXTCALL(glGenProgramsARB(1, &prog
));
415 ERR("Failed to create an ARB offset limit test program\n");
417 GL_EXTCALL(glBindProgramARB(GL_VERTEX_PROGRAM_ARB
, prog
));
418 GL_EXTCALL(glProgramStringARB(GL_VERTEX_PROGRAM_ARB
, GL_PROGRAM_FORMAT_ASCII_ARB
,
419 strlen(testcode
), testcode
));
420 if(glGetError() != 0) {
421 TRACE("OpenGL implementation does not allow indirect addressing offsets > 63\n");
422 TRACE("error: %s\n", debugstr_a((const char *)glGetString(GL_PROGRAM_ERROR_STRING_ARB
)));
424 } else TRACE("OpenGL implementation allows offsets > 63\n");
426 GL_EXTCALL(glBindProgramARB(GL_VERTEX_PROGRAM_ARB
, 0));
427 GL_EXTCALL(glDeleteProgramsARB(1, &prog
));
428 checkGLcall("ARB vp offset limit test cleanup");
433 static DWORD
ver_for_ext(GL_SupportedExt ext
)
436 for (i
= 0; i
< (sizeof(EXTENSION_MAP
) / sizeof(*EXTENSION_MAP
)); ++i
) {
437 if(EXTENSION_MAP
[i
].extension
== ext
) {
438 return EXTENSION_MAP
[i
].version
;
444 static BOOL
match_ati_r300_to_500(const struct wined3d_gl_info
*gl_info
, const char *gl_renderer
,
445 enum wined3d_gl_vendor gl_vendor
, enum wined3d_pci_vendor card_vendor
, enum wined3d_pci_device device
)
447 if (card_vendor
!= HW_VENDOR_ATI
) return FALSE
;
448 if (device
== CARD_ATI_RADEON_9500
) return TRUE
;
449 if (device
== CARD_ATI_RADEON_X700
) return TRUE
;
450 if (device
== CARD_ATI_RADEON_X1600
) return TRUE
;
454 static BOOL
match_geforce5(const struct wined3d_gl_info
*gl_info
, const char *gl_renderer
,
455 enum wined3d_gl_vendor gl_vendor
, enum wined3d_pci_vendor card_vendor
, enum wined3d_pci_device device
)
457 if (card_vendor
== HW_VENDOR_NVIDIA
)
459 if (device
== CARD_NVIDIA_GEFORCEFX_5200
||
460 device
== CARD_NVIDIA_GEFORCEFX_5600
||
461 device
== CARD_NVIDIA_GEFORCEFX_5800
)
469 static BOOL
match_apple(const struct wined3d_gl_info
*gl_info
, const char *gl_renderer
,
470 enum wined3d_gl_vendor gl_vendor
, enum wined3d_pci_vendor card_vendor
, enum wined3d_pci_device device
)
472 /* MacOS has various specialities in the extensions it advertises. Some have to be loaded from
473 * the opengl 1.2+ core, while other extensions are advertised, but software emulated. So try to
474 * detect the Apple OpenGL implementation to apply some extension fixups afterwards.
476 * Detecting this isn't really easy. The vendor string doesn't mention Apple. Compile-time checks
477 * aren't sufficient either because a Linux binary may display on a macos X server via remote X11.
478 * So try to detect the GL implementation by looking at certain Apple extensions. Some extensions
479 * like client storage might be supported on other implementations too, but GL_APPLE_flush_render
480 * is specific to the Mac OS X window management, and GL_APPLE_ycbcr_422 is QuickTime specific. So
481 * the chance that other implementations support them is rather small since Win32 QuickTime uses
482 * DirectDraw, not OpenGL.
484 * This test has been moved into wined3d_guess_gl_vendor()
486 if (gl_vendor
== GL_VENDOR_APPLE
)
493 /* Context activation is done by the caller. */
494 static void test_pbo_functionality(struct wined3d_gl_info
*gl_info
)
496 /* Some OpenGL implementations, namely Apple's Geforce 8 driver, advertises PBOs,
497 * but glTexSubImage from a PBO fails miserably, with the first line repeated over
498 * all the texture. This function detects this bug by its symptom and disables PBOs
501 * The test uploads a 4x4 texture via the PBO in the "native" format GL_BGRA,
502 * GL_UNSIGNED_INT_8_8_8_8_REV. This format triggers the bug, and it is what we use
503 * for D3DFMT_A8R8G8B8. Then the texture is read back without any PBO and the data
504 * read back is compared to the original. If they are equal PBOs are assumed to work,
505 * otherwise the PBO extension is disabled. */
507 static const unsigned int pattern
[] =
509 0x00000000, 0x000000ff, 0x0000ff00, 0x40ff0000,
510 0x80ffffff, 0x40ffff00, 0x00ff00ff, 0x0000ffff,
511 0x00ffff00, 0x00ff00ff, 0x0000ffff, 0x000000ff,
512 0x80ff00ff, 0x0000ffff, 0x00ff00ff, 0x40ff00ff
514 unsigned int check
[sizeof(pattern
) / sizeof(pattern
[0])];
516 /* No PBO -> No point in testing them. */
517 if (!gl_info
->supported
[ARB_PIXEL_BUFFER_OBJECT
]) return;
521 while (glGetError());
522 glGenTextures(1, &texture
);
523 glBindTexture(GL_TEXTURE_2D
, texture
);
525 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MAX_LEVEL
, 0);
526 glTexImage2D(GL_TEXTURE_2D
, 0, GL_RGBA8
, 4, 4, 0, GL_BGRA
, GL_UNSIGNED_INT_8_8_8_8_REV
, 0);
527 checkGLcall("Specifying the PBO test texture");
529 GL_EXTCALL(glGenBuffersARB(1, &pbo
));
530 GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB
, pbo
));
531 GL_EXTCALL(glBufferDataARB(GL_PIXEL_UNPACK_BUFFER_ARB
, sizeof(pattern
), pattern
, GL_STREAM_DRAW_ARB
));
532 checkGLcall("Specifying the PBO test pbo");
534 glTexSubImage2D(GL_TEXTURE_2D
, 0, 0, 0, 4, 4, GL_BGRA
, GL_UNSIGNED_INT_8_8_8_8_REV
, NULL
);
535 checkGLcall("Loading the PBO test texture");
537 GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB
, 0));
540 wglFinish(); /* just to be sure */
542 memset(check
, 0, sizeof(check
));
544 glGetTexImage(GL_TEXTURE_2D
, 0, GL_BGRA
, GL_UNSIGNED_INT_8_8_8_8_REV
, check
);
545 checkGLcall("Reading back the PBO test texture");
547 glDeleteTextures(1, &texture
);
548 GL_EXTCALL(glDeleteBuffersARB(1, &pbo
));
549 checkGLcall("PBO test cleanup");
553 if (memcmp(check
, pattern
, sizeof(check
)))
555 WARN_(d3d_caps
)("PBO test failed, read back data doesn't match original.\n");
556 WARN_(d3d_caps
)("Disabling PBOs. This may result in slower performance.\n");
557 gl_info
->supported
[ARB_PIXEL_BUFFER_OBJECT
] = FALSE
;
561 TRACE_(d3d_caps
)("PBO test successful.\n");
565 static BOOL
match_apple_intel(const struct wined3d_gl_info
*gl_info
, const char *gl_renderer
,
566 enum wined3d_gl_vendor gl_vendor
, enum wined3d_pci_vendor card_vendor
, enum wined3d_pci_device device
)
568 return (card_vendor
== HW_VENDOR_INTEL
) && (gl_vendor
== GL_VENDOR_APPLE
);
571 static BOOL
match_apple_nonr500ati(const struct wined3d_gl_info
*gl_info
, const char *gl_renderer
,
572 enum wined3d_gl_vendor gl_vendor
, enum wined3d_pci_vendor card_vendor
, enum wined3d_pci_device device
)
574 if (gl_vendor
!= GL_VENDOR_APPLE
) return FALSE
;
575 if (card_vendor
!= HW_VENDOR_ATI
) return FALSE
;
576 if (device
== CARD_ATI_RADEON_X1600
) return FALSE
;
580 static BOOL
match_fglrx(const struct wined3d_gl_info
*gl_info
, const char *gl_renderer
,
581 enum wined3d_gl_vendor gl_vendor
, enum wined3d_pci_vendor card_vendor
, enum wined3d_pci_device device
)
583 return gl_vendor
== GL_VENDOR_FGLRX
;
587 static BOOL
match_dx10_capable(const struct wined3d_gl_info
*gl_info
, const char *gl_renderer
,
588 enum wined3d_gl_vendor gl_vendor
, enum wined3d_pci_vendor card_vendor
, enum wined3d_pci_device device
)
590 /* DX9 cards support 40 single float varyings in hardware, most drivers report 32. ATI misreports
591 * 44 varyings. So assume that if we have more than 44 varyings we have a dx10 card.
592 * This detection is for the gl_ClipPos varying quirk. If a d3d9 card really supports more than 44
593 * varyings and we subtract one in dx9 shaders its not going to hurt us because the dx9 limit is
596 * dx10 cards usually have 64 varyings */
597 return gl_info
->limits
.glsl_varyings
> 44;
600 /* A GL context is provided by the caller */
601 static BOOL
match_allows_spec_alpha(const struct wined3d_gl_info
*gl_info
, const char *gl_renderer
,
602 enum wined3d_gl_vendor gl_vendor
, enum wined3d_pci_vendor card_vendor
, enum wined3d_pci_device device
)
607 if (!gl_info
->supported
[EXT_SECONDARY_COLOR
]) return FALSE
;
611 GL_EXTCALL(glSecondaryColorPointerEXT
)(4, GL_UNSIGNED_BYTE
, 4, data
);
612 error
= glGetError();
615 if(error
== GL_NO_ERROR
)
617 TRACE("GL Implementation accepts 4 component specular color pointers\n");
622 TRACE("GL implementation does not accept 4 component specular colors, error %s\n",
623 debug_glerror(error
));
628 static BOOL
match_apple_nvts(const struct wined3d_gl_info
*gl_info
, const char *gl_renderer
,
629 enum wined3d_gl_vendor gl_vendor
, enum wined3d_pci_vendor card_vendor
, enum wined3d_pci_device device
)
631 if (!match_apple(gl_info
, gl_renderer
, gl_vendor
, card_vendor
, device
)) return FALSE
;
632 return gl_info
->supported
[NV_TEXTURE_SHADER
];
635 /* A GL context is provided by the caller */
636 static BOOL
match_broken_nv_clip(const struct wined3d_gl_info
*gl_info
, const char *gl_renderer
,
637 enum wined3d_gl_vendor gl_vendor
, enum wined3d_pci_vendor card_vendor
, enum wined3d_pci_device device
)
642 const char *testcode
=
644 "OPTION NV_vertex_program2;\n"
645 "MOV result.clip[0], 0.0;\n"
646 "MOV result.position, 0.0;\n"
649 if (!gl_info
->supported
[NV_VERTEX_PROGRAM2_OPTION
]) return FALSE
;
654 GL_EXTCALL(glGenProgramsARB(1, &prog
));
657 ERR("Failed to create the NVvp clip test program\n");
661 GL_EXTCALL(glBindProgramARB(GL_VERTEX_PROGRAM_ARB
, prog
));
662 GL_EXTCALL(glProgramStringARB(GL_VERTEX_PROGRAM_ARB
, GL_PROGRAM_FORMAT_ASCII_ARB
,
663 strlen(testcode
), testcode
));
664 glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB
, &pos
);
667 WARN("GL_NV_vertex_program2_option result.clip[] test failed\n");
668 TRACE("error: %s\n", debugstr_a((const char *)glGetString(GL_PROGRAM_ERROR_STRING_ARB
)));
672 else TRACE("GL_NV_vertex_program2_option result.clip[] test passed\n");
674 GL_EXTCALL(glBindProgramARB(GL_VERTEX_PROGRAM_ARB
, 0));
675 GL_EXTCALL(glDeleteProgramsARB(1, &prog
));
676 checkGLcall("GL_NV_vertex_program2_option result.clip[] test cleanup");
682 /* Context activation is done by the caller. */
683 static BOOL
match_fbo_tex_update(const struct wined3d_gl_info
*gl_info
, const char *gl_renderer
,
684 enum wined3d_gl_vendor gl_vendor
, enum wined3d_pci_vendor card_vendor
, enum wined3d_pci_device device
)
686 char data
[4 * 4 * 4];
690 if (wined3d_settings
.offscreen_rendering_mode
!= ORM_FBO
) return FALSE
;
692 memset(data
, 0xcc, sizeof(data
));
696 glGenTextures(1, &tex
);
697 glBindTexture(GL_TEXTURE_2D
, tex
);
698 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MIN_FILTER
, GL_NEAREST
);
699 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MAG_FILTER
, GL_NEAREST
);
700 glTexImage2D(GL_TEXTURE_2D
, 0, GL_RGBA8
, 4, 4, 0, GL_BGRA
, GL_UNSIGNED_INT_8_8_8_8_REV
, NULL
);
701 checkGLcall("glTexImage2D");
703 gl_info
->fbo_ops
.glGenFramebuffers(1, &fbo
);
704 gl_info
->fbo_ops
.glBindFramebuffer(GL_FRAMEBUFFER
, fbo
);
705 gl_info
->fbo_ops
.glFramebufferTexture2D(GL_FRAMEBUFFER
, GL_COLOR_ATTACHMENT0
, GL_TEXTURE_2D
, tex
, 0);
706 checkGLcall("glFramebufferTexture2D");
708 status
= gl_info
->fbo_ops
.glCheckFramebufferStatus(GL_FRAMEBUFFER
);
709 if (status
!= GL_FRAMEBUFFER_COMPLETE
) ERR("FBO status %#x\n", status
);
710 checkGLcall("glCheckFramebufferStatus");
712 memset(data
, 0x11, sizeof(data
));
713 glTexSubImage2D(GL_TEXTURE_2D
, 0, 0, 0, 4, 4, GL_BGRA
, GL_UNSIGNED_INT_8_8_8_8_REV
, data
);
714 checkGLcall("glTexSubImage2D");
716 glClearColor(0.996f
, 0.729f
, 0.745f
, 0.792f
);
717 glClear(GL_COLOR_BUFFER_BIT
);
718 checkGLcall("glClear");
720 glGetTexImage(GL_TEXTURE_2D
, 0, GL_BGRA
, GL_UNSIGNED_INT_8_8_8_8_REV
, data
);
721 checkGLcall("glGetTexImage");
723 gl_info
->fbo_ops
.glFramebufferTexture2D(GL_FRAMEBUFFER
, GL_COLOR_ATTACHMENT0
, GL_TEXTURE_2D
, 0, 0);
724 gl_info
->fbo_ops
.glBindFramebuffer(GL_FRAMEBUFFER
, 0);
725 glBindTexture(GL_TEXTURE_2D
, 0);
726 checkGLcall("glBindTexture");
728 gl_info
->fbo_ops
.glDeleteFramebuffers(1, &fbo
);
729 glDeleteTextures(1, &tex
);
730 checkGLcall("glDeleteTextures");
734 return *(DWORD
*)data
== 0x11111111;
737 static void quirk_arb_constants(struct wined3d_gl_info
*gl_info
)
739 TRACE_(d3d_caps
)("Using ARB vs constant limit(=%u) for GLSL.\n", gl_info
->limits
.arb_vs_native_constants
);
740 gl_info
->limits
.glsl_vs_float_constants
= gl_info
->limits
.arb_vs_native_constants
;
741 TRACE_(d3d_caps
)("Using ARB ps constant limit(=%u) for GLSL.\n", gl_info
->limits
.arb_ps_native_constants
);
742 gl_info
->limits
.glsl_ps_float_constants
= gl_info
->limits
.arb_ps_native_constants
;
745 static void quirk_apple_glsl_constants(struct wined3d_gl_info
*gl_info
)
747 quirk_arb_constants(gl_info
);
748 /* MacOS needs uniforms for relative addressing offsets. This can accumulate to quite a few uniforms.
749 * Beyond that the general uniform isn't optimal, so reserve a number of uniforms. 12 vec4's should
750 * allow 48 different offsets or other helper immediate values. */
751 TRACE_(d3d_caps
)("Reserving 12 GLSL constants for compiler private use.\n");
752 gl_info
->reserved_glsl_constants
= max(gl_info
->reserved_glsl_constants
, 12);
755 /* fglrx crashes with a very bad kernel panic if GL_POINT_SPRITE_ARB is set to GL_COORD_REPLACE_ARB
756 * on more than one texture unit. This means that the d3d9 visual point size test will cause a
757 * kernel panic on any machine running fglrx 9.3(latest that supports r300 to r500 cards). This
758 * quirk only enables point sprites on the first texture unit. This keeps point sprites working in
759 * most games, but avoids the crash
761 * A more sophisticated way would be to find all units that need texture coordinates and enable
762 * point sprites for one if only one is found, and software emulate point sprites in drawStridedSlow
763 * if more than one unit needs texture coordinates(This requires software ffp and vertex shaders though)
765 * Note that disabling the extension entirely does not gain predictability because there is no point
766 * sprite capability flag in d3d, so the potential rendering bugs are the same if we disable the extension. */
767 static void quirk_one_point_sprite(struct wined3d_gl_info
*gl_info
)
769 if (gl_info
->supported
[ARB_POINT_SPRITE
])
771 TRACE("Limiting point sprites to one texture unit.\n");
772 gl_info
->limits
.point_sprite_units
= 1;
776 static void quirk_ati_dx9(struct wined3d_gl_info
*gl_info
)
778 quirk_arb_constants(gl_info
);
780 /* MacOS advertises GL_ARB_texture_non_power_of_two on ATI r500 and earlier cards, although
781 * these cards only support GL_ARB_texture_rectangle(D3DPTEXTURECAPS_NONPOW2CONDITIONAL).
782 * If real NP2 textures are used, the driver falls back to software. We could just remove the
783 * extension and use GL_ARB_texture_rectangle instead, but texture_rectangle is inconventient
784 * due to the non-normalized texture coordinates. Thus set an internal extension flag,
785 * GL_WINE_normalized_texrect, which signals the code that it can use non power of two textures
786 * as per GL_ARB_texture_non_power_of_two, but has to stick to the texture_rectangle limits.
788 * fglrx doesn't advertise GL_ARB_texture_non_power_of_two, but it advertises opengl 2.0 which
789 * has this extension promoted to core. The extension loading code sets this extension supported
790 * due to that, so this code works on fglrx as well. */
791 if(gl_info
->supported
[ARB_TEXTURE_NON_POWER_OF_TWO
])
793 TRACE("GL_ARB_texture_non_power_of_two advertised on R500 or earlier card, removing.\n");
794 gl_info
->supported
[ARB_TEXTURE_NON_POWER_OF_TWO
] = FALSE
;
795 gl_info
->supported
[WINED3D_GL_NORMALIZED_TEXRECT
] = TRUE
;
798 /* fglrx has the same structural issues as the one described in quirk_apple_glsl_constants, although
799 * it is generally more efficient. Reserve just 8 constants. */
800 TRACE_(d3d_caps
)("Reserving 8 GLSL constants for compiler private use.\n");
801 gl_info
->reserved_glsl_constants
= max(gl_info
->reserved_glsl_constants
, 8);
804 static void quirk_no_np2(struct wined3d_gl_info
*gl_info
)
806 /* The nVidia GeForceFX series reports OpenGL 2.0 capabilities with the latest drivers versions, but
807 * doesn't explicitly advertise the ARB_tex_npot extension in the GL extension string.
808 * This usually means that ARB_tex_npot is supported in hardware as long as the application is staying
809 * within the limits enforced by the ARB_texture_rectangle extension. This however is not true for the
810 * FX series, which instantly falls back to a slower software path as soon as ARB_tex_npot is used.
811 * We therefore completely remove ARB_tex_npot from the list of supported extensions.
813 * Note that wine_normalized_texrect can't be used in this case because internally it uses ARB_tex_npot,
814 * triggering the software fallback. There is not much we can do here apart from disabling the
815 * software-emulated extension and reenable ARB_tex_rect (which was previously disabled
816 * in IWineD3DImpl_FillGLCaps).
817 * This fixup removes performance problems on both the FX 5900 and FX 5700 (e.g. for framebuffer
818 * post-processing effects in the game "Max Payne 2").
819 * The behaviour can be verified through a simple test app attached in bugreport #14724. */
820 TRACE("GL_ARB_texture_non_power_of_two advertised through OpenGL 2.0 on NV FX card, removing.\n");
821 gl_info
->supported
[ARB_TEXTURE_NON_POWER_OF_TWO
] = FALSE
;
822 gl_info
->supported
[ARB_TEXTURE_RECTANGLE
] = TRUE
;
825 static void quirk_texcoord_w(struct wined3d_gl_info
*gl_info
)
827 /* The Intel GPUs on MacOS set the .w register of texcoords to 0.0 by default, which causes problems
828 * with fixed function fragment processing. Ideally this flag should be detected with a test shader
829 * and OpenGL feedback mode, but some GL implementations (MacOS ATI at least, probably all MacOS ones)
830 * do not like vertex shaders in feedback mode and return an error, even though it should be valid
831 * according to the spec.
833 * We don't want to enable this on all cards, as it adds an extra instruction per texcoord used. This
834 * makes the shader slower and eats instruction slots which should be available to the d3d app.
836 * ATI Radeon HD 2xxx cards on MacOS have the issue. Instead of checking for the buggy cards, blacklist
837 * all radeon cards on Macs and whitelist the good ones. That way we're prepared for the future. If
838 * this workaround is activated on cards that do not need it, it won't break things, just affect
839 * performance negatively. */
840 TRACE("Enabling vertex texture coord fixes in vertex shaders.\n");
841 gl_info
->quirks
|= WINED3D_QUIRK_SET_TEXCOORD_W
;
844 static void quirk_clip_varying(struct wined3d_gl_info
*gl_info
)
846 gl_info
->quirks
|= WINED3D_QUIRK_GLSL_CLIP_VARYING
;
849 static void quirk_allows_specular_alpha(struct wined3d_gl_info
*gl_info
)
851 gl_info
->quirks
|= WINED3D_QUIRK_ALLOWS_SPECULAR_ALPHA
;
854 static void quirk_apple_nvts(struct wined3d_gl_info
*gl_info
)
856 gl_info
->supported
[NV_TEXTURE_SHADER
] = FALSE
;
857 gl_info
->supported
[NV_TEXTURE_SHADER2
] = FALSE
;
860 static void quirk_disable_nvvp_clip(struct wined3d_gl_info
*gl_info
)
862 gl_info
->quirks
|= WINED3D_QUIRK_NV_CLIP_BROKEN
;
865 static void quirk_fbo_tex_update(struct wined3d_gl_info
*gl_info
)
867 gl_info
->quirks
|= WINED3D_QUIRK_FBO_TEX_UPDATE
;
872 BOOL (*match
)(const struct wined3d_gl_info
*gl_info
, const char *gl_renderer
,
873 enum wined3d_gl_vendor gl_vendor
, enum wined3d_pci_vendor card_vendor
, enum wined3d_pci_device device
);
874 void (*apply
)(struct wined3d_gl_info
*gl_info
);
875 const char *description
;
878 static const struct driver_quirk quirk_table
[] =
881 match_ati_r300_to_500
,
883 "ATI GLSL constant and normalized texrect quirk"
885 /* MacOS advertises more GLSL vertex shader uniforms than supported by the hardware, and if more are
886 * used it falls back to software. While the compiler can detect if the shader uses all declared
887 * uniforms, the optimization fails if the shader uses relative addressing. So any GLSL shader
888 * using relative addressing falls back to software.
890 * ARB vp gives the correct amount of uniforms, so use it instead of GLSL. */
893 quirk_apple_glsl_constants
,
894 "Apple GLSL uniform override"
899 "Geforce 5 NP2 disable"
904 "Init texcoord .w for Apple Intel GPU driver"
907 match_apple_nonr500ati
,
909 "Init texcoord .w for Apple ATI >= r600 GPU driver"
913 quirk_one_point_sprite
,
914 "Fglrx point sprite crash workaround"
919 "Reserved varying for gl_ClipPos"
922 /* GL_EXT_secondary_color does not allow 4 component secondary colors, but most
923 * GL implementations accept it. The Mac GL is the only implementation known to
926 * If we can pass 4 component specular colors, do it, because (a) we don't have
927 * to screw around with the data, and (b) the D3D fixed function vertex pipeline
928 * passes specular alpha to the pixel shader if any is used. Otherwise the
929 * specular alpha is used to pass the fog coordinate, which we pass to opengl
930 * via GL_EXT_fog_coord.
932 match_allows_spec_alpha
,
933 quirk_allows_specular_alpha
,
934 "Allow specular alpha quirk"
937 /* The pixel formats provided by GL_NV_texture_shader are broken on OSX
942 "Apple NV_texture_shader disable"
945 match_broken_nv_clip
,
946 quirk_disable_nvvp_clip
,
947 "Apple NV_vertex_program clip bug quirk"
950 match_fbo_tex_update
,
951 quirk_fbo_tex_update
,
952 "FBO rebind for attachment updates"
956 /* Certain applications (Steam) complain if we report an outdated driver version. In general,
957 * reporting a driver version is moot because we are not the Windows driver, and we have different
958 * bugs, features, etc.
960 * The driver version has the form "x.y.z.w".
962 * "x" is the Windows version the driver is meant for:
969 * "y" is the Direct3D level the driver supports:
976 * "z" is unknown, possibly vendor specific.
978 * "w" is the vendor specific driver version.
980 struct driver_version_information
982 WORD vendor
; /* reported PCI card vendor ID */
983 WORD card
; /* reported PCI card device ID */
984 const char *description
; /* Description of the card e.g. NVIDIA RIVA TNT */
985 WORD d3d_level
; /* driver hiword to report */
986 WORD lopart_hi
, lopart_lo
; /* driver loword to report */
989 static const struct driver_version_information driver_version_table
[] =
991 /* Nvidia drivers. Geforce6 and newer cards are supported by the current driver (180.x)
992 * GeforceFX support is up to 173.x, - driver uses numbering x.y.11.7341 for 173.41 where x is the windows revision (6=2000/xp, 7=vista), y is unknown
993 * Geforce2MX/3/4 up to 96.x - driver uses numbering 9.6.8.9 for 96.89
994 * TNT/Geforce1/2 up to 71.x - driver uses numbering 7.1.8.6 for 71.86
996 * All version numbers used below are from the Linux nvidia drivers. */
997 {HW_VENDOR_NVIDIA
, CARD_NVIDIA_RIVA_TNT
, "NVIDIA RIVA TNT", 1, 8, 6 },
998 {HW_VENDOR_NVIDIA
, CARD_NVIDIA_RIVA_TNT2
, "NVIDIA RIVA TNT2/TNT2 Pro", 1, 8, 6 },
999 {HW_VENDOR_NVIDIA
, CARD_NVIDIA_GEFORCE
, "NVIDIA GeForce 256", 1, 8, 6 },
1000 {HW_VENDOR_NVIDIA
, CARD_NVIDIA_GEFORCE2_MX
, "NVIDIA GeForce2 MX/MX 400", 6, 4, 3 },
1001 {HW_VENDOR_NVIDIA
, CARD_NVIDIA_GEFORCE2
, "NVIDIA GeForce2 GTS/GeForce2 Pro", 1, 8, 6 },
1002 {HW_VENDOR_NVIDIA
, CARD_NVIDIA_GEFORCE3
, "NVIDIA GeForce3", 6, 10, 9371 },
1003 {HW_VENDOR_NVIDIA
, CARD_NVIDIA_GEFORCE4_MX
, "NVIDIA GeForce4 MX 460", 6, 10, 9371 },
1004 {HW_VENDOR_NVIDIA
, CARD_NVIDIA_GEFORCE4_TI4200
, "NVIDIA GeForce4 Ti 4200", 6, 10, 9371 },
1005 {HW_VENDOR_NVIDIA
, CARD_NVIDIA_GEFORCEFX_5200
, "NVIDIA GeForce FX 5200", 15, 11, 7516 },
1006 {HW_VENDOR_NVIDIA
, CARD_NVIDIA_GEFORCEFX_5600
, "NVIDIA GeForce FX 5600", 15, 11, 7516 },
1007 {HW_VENDOR_NVIDIA
, CARD_NVIDIA_GEFORCEFX_5800
, "NVIDIA GeForce FX 5800", 15, 11, 7516 },
1008 {HW_VENDOR_NVIDIA
, CARD_NVIDIA_GEFORCE_6200
, "NVIDIA GeForce 6200", 15, 11, 9745 },
1009 {HW_VENDOR_NVIDIA
, CARD_NVIDIA_GEFORCE_6600GT
, "NVIDIA GeForce 6600 GT", 15, 11, 9745 },
1010 {HW_VENDOR_NVIDIA
, CARD_NVIDIA_GEFORCE_6800
, "NVIDIA GeForce 6800", 15, 11, 9745 },
1011 {HW_VENDOR_NVIDIA
, CARD_NVIDIA_GEFORCE_7300
, "NVIDIA GeForce Go 7300", 15, 11, 9745 },
1012 {HW_VENDOR_NVIDIA
, CARD_NVIDIA_GEFORCE_7400
, "NVIDIA GeForce Go 7400", 15, 11, 9745 },
1013 {HW_VENDOR_NVIDIA
, CARD_NVIDIA_GEFORCE_7600
, "NVIDIA GeForce 7600 GT", 15, 11, 9745 },
1014 {HW_VENDOR_NVIDIA
, CARD_NVIDIA_GEFORCE_7800GT
, "NVIDIA GeForce 7800 GT", 15, 11, 9745 },
1015 {HW_VENDOR_NVIDIA
, CARD_NVIDIA_GEFORCE_8300GS
, "NVIDIA GeForce 8300 GS", 15, 11, 9745 },
1016 {HW_VENDOR_NVIDIA
, CARD_NVIDIA_GEFORCE_8400GS
, "NVIDIA GeForce 8400 GS", 15, 11, 9745 },
1017 {HW_VENDOR_NVIDIA
, CARD_NVIDIA_GEFORCE_8600GT
, "NVIDIA GeForce 8600 GT", 15, 11, 9745 },
1018 {HW_VENDOR_NVIDIA
, CARD_NVIDIA_GEFORCE_8600MGT
, "NVIDIA GeForce 8600M GT", 15, 11, 9745 },
1019 {HW_VENDOR_NVIDIA
, CARD_NVIDIA_GEFORCE_8800GTS
, "NVIDIA GeForce 8800 GTS", 15, 11, 9745 },
1020 {HW_VENDOR_NVIDIA
, CARD_NVIDIA_GEFORCE_8800GTX
, "NVIDIA GeForce 8800 GTX", 15, 11, 9745 },
1021 {HW_VENDOR_NVIDIA
, CARD_NVIDIA_GEFORCE_9200
, "NVIDIA GeForce 9200", 15, 11, 9745 },
1022 {HW_VENDOR_NVIDIA
, CARD_NVIDIA_GEFORCE_9400GT
, "NVIDIA GeForce 9400 GT", 15, 11, 9745 },
1023 {HW_VENDOR_NVIDIA
, CARD_NVIDIA_GEFORCE_9500GT
, "NVIDIA GeForce 9500 GT", 15, 11, 9745 },
1024 {HW_VENDOR_NVIDIA
, CARD_NVIDIA_GEFORCE_9600GT
, "NVIDIA GeForce 9600 GT", 15, 11, 9745 },
1025 {HW_VENDOR_NVIDIA
, CARD_NVIDIA_GEFORCE_9800GT
, "NVIDIA GeForce 9800 GT", 15, 11, 9745 },
1026 {HW_VENDOR_NVIDIA
, CARD_NVIDIA_GEFORCE_210
, "NVIDIA GeForce 210", 15, 11, 9745 },
1027 {HW_VENDOR_NVIDIA
, CARD_NVIDIA_GEFORCE_GT220
, "NVIDIA GeForce GT 220", 15, 11, 9745 },
1028 {HW_VENDOR_NVIDIA
, CARD_NVIDIA_GEFORCE_GT240
, "NVIDIA GeForce GT 240", 15, 11, 9745 },
1029 {HW_VENDOR_NVIDIA
, CARD_NVIDIA_GEFORCE_GTX260
, "NVIDIA GeForce GTX 260", 15, 11, 9745 },
1030 {HW_VENDOR_NVIDIA
, CARD_NVIDIA_GEFORCE_GTX275
, "NVIDIA GeForce GTX 275", 15, 11, 9745 },
1031 {HW_VENDOR_NVIDIA
, CARD_NVIDIA_GEFORCE_GTX280
, "NVIDIA GeForce GTX 280", 15, 11, 9745 },
1032 {HW_VENDOR_NVIDIA
, CARD_NVIDIA_GEFORCE_GT325M
, "NVIDIA GeForce GT 325M", 15, 11, 9745 },
1033 {HW_VENDOR_NVIDIA
, CARD_NVIDIA_GEFORCE_GTS350M
, "NVIDIA GeForce GTS 350M", 15, 11, 9745 },
1034 {HW_VENDOR_NVIDIA
, CARD_NVIDIA_GEFORCE_GTX470
, "NVIDIA GeForce GTX 470", 15, 11, 9775 },
1035 {HW_VENDOR_NVIDIA
, CARD_NVIDIA_GEFORCE_GTX480
, "NVIDIA GeForce GTX 480", 15, 11, 9775 },
1036 /* ATI cards. The driver versions are somewhat similar, but not quite the same. Let's hardcode. */
1037 {HW_VENDOR_ATI
, CARD_ATI_RADEON_9500
, "ATI Radeon 9500", 14, 10, 6764 },
1038 {HW_VENDOR_ATI
, CARD_ATI_RADEON_X700
, "ATI Radeon X700 SE", 14, 10, 6764 },
1039 {HW_VENDOR_ATI
, CARD_ATI_RADEON_X1600
, "ATI Radeon X1600 Series", 14, 10, 6764 },
1040 {HW_VENDOR_ATI
, CARD_ATI_RADEON_HD2350
, "ATI Mobility Radeon HD 2350", 14, 10, 6764 },
1041 {HW_VENDOR_ATI
, CARD_ATI_RADEON_HD2600
, "ATI Mobility Radeon HD 2600", 14, 10, 6764 },
1042 {HW_VENDOR_ATI
, CARD_ATI_RADEON_HD2900
, "ATI Radeon HD 2900 XT", 14, 10, 6764 },
1043 {HW_VENDOR_ATI
, CARD_ATI_RADEON_HD4350
, "ATI Radeon HD 4350", 14, 10, 6764 },
1044 {HW_VENDOR_ATI
, CARD_ATI_RADEON_HD4600
, "ATI Radeon HD 4600 Series", 14, 10, 6764 },
1045 {HW_VENDOR_ATI
, CARD_ATI_RADEON_HD4700
, "ATI Radeon HD 4700 Series", 14, 10, 6764 },
1046 {HW_VENDOR_ATI
, CARD_ATI_RADEON_HD4800
, "ATI Radeon HD 4800 Series", 14, 10, 6764 },
1047 {HW_VENDOR_ATI
, CARD_ATI_RADEON_HD5700
, "ATI Radeon HD 5700 Series", 14, 10, 8681 },
1048 {HW_VENDOR_ATI
, CARD_ATI_RADEON_HD5800
, "ATI Radeon HD 5800 Series", 14, 10, 8681 },
1050 /* TODO: Add information about legacy ATI hardware, Intel and other cards. */
1053 static void init_driver_info(struct wined3d_driver_info
*driver_info
,
1054 enum wined3d_pci_vendor vendor
, enum wined3d_pci_device device
)
1056 OSVERSIONINFOW os_version
;
1057 WORD driver_os_version
;
1060 if (wined3d_settings
.pci_vendor_id
!= PCI_VENDOR_NONE
)
1062 TRACE_(d3d_caps
)("Overriding PCI vendor ID with: %04x\n", wined3d_settings
.pci_vendor_id
);
1063 vendor
= wined3d_settings
.pci_vendor_id
;
1065 driver_info
->vendor
= vendor
;
1067 if (wined3d_settings
.pci_device_id
!= PCI_DEVICE_NONE
)
1069 TRACE_(d3d_caps
)("Overriding PCI device ID with: %04x\n", wined3d_settings
.pci_device_id
);
1070 device
= wined3d_settings
.pci_device_id
;
1072 driver_info
->device
= device
;
1077 driver_info
->name
= "ati2dvag.dll";
1080 case HW_VENDOR_NVIDIA
:
1081 driver_info
->name
= "nv4_disp.dll";
1084 case HW_VENDOR_INTEL
:
1086 FIXME_(d3d_caps
)("Unhandled vendor %04x.\n", vendor
);
1087 driver_info
->name
= "Display";
1091 memset(&os_version
, 0, sizeof(os_version
));
1092 os_version
.dwOSVersionInfoSize
= sizeof(os_version
);
1093 if (!GetVersionExW(&os_version
))
1095 ERR("Failed to get OS version, reporting 2000/XP.\n");
1096 driver_os_version
= 6;
1100 TRACE("OS version %u.%u.\n", os_version
.dwMajorVersion
, os_version
.dwMinorVersion
);
1101 switch (os_version
.dwMajorVersion
)
1104 driver_os_version
= 4;
1108 driver_os_version
= 6;
1112 if (os_version
.dwMinorVersion
== 0)
1114 driver_os_version
= 7;
1118 if (os_version
.dwMinorVersion
> 1)
1120 FIXME("Unhandled OS version %u.%u, reporting Win 7.\n",
1121 os_version
.dwMajorVersion
, os_version
.dwMinorVersion
);
1123 driver_os_version
= 8;
1128 FIXME("Unhandled OS version %u.%u, reporting 2000/XP.\n",
1129 os_version
.dwMajorVersion
, os_version
.dwMinorVersion
);
1130 driver_os_version
= 6;
1135 driver_info
->description
= "Direct3D HAL";
1136 driver_info
->version_high
= MAKEDWORD_VERSION(driver_os_version
, 15);
1137 driver_info
->version_low
= MAKEDWORD_VERSION(8, 6); /* Nvidia RIVA TNT, arbitrary */
1139 for (i
= 0; i
< (sizeof(driver_version_table
) / sizeof(driver_version_table
[0])); ++i
)
1141 if (vendor
== driver_version_table
[i
].vendor
&& device
== driver_version_table
[i
].card
)
1143 TRACE_(d3d_caps
)("Found card %04x:%04x in driver DB.\n", vendor
, device
);
1145 driver_info
->description
= driver_version_table
[i
].description
;
1146 driver_info
->version_high
= MAKEDWORD_VERSION(driver_os_version
, driver_version_table
[i
].d3d_level
);
1147 driver_info
->version_low
= MAKEDWORD_VERSION(driver_version_table
[i
].lopart_hi
,
1148 driver_version_table
[i
].lopart_lo
);
1153 TRACE_(d3d_caps
)("Reporting (fake) driver version 0x%08x-0x%08x.\n",
1154 driver_info
->version_high
, driver_info
->version_low
);
1157 /* Context activation is done by the caller. */
1158 static void fixup_extensions(struct wined3d_gl_info
*gl_info
, const char *gl_renderer
,
1159 enum wined3d_gl_vendor gl_vendor
, enum wined3d_pci_vendor card_vendor
, enum wined3d_pci_device device
)
1163 for (i
= 0; i
< (sizeof(quirk_table
) / sizeof(*quirk_table
)); ++i
)
1165 if (!quirk_table
[i
].match(gl_info
, gl_renderer
, gl_vendor
, card_vendor
, device
)) continue;
1166 TRACE_(d3d_caps
)("Applying driver quirk \"%s\".\n", quirk_table
[i
].description
);
1167 quirk_table
[i
].apply(gl_info
);
1170 /* Find out if PBOs work as they are supposed to. */
1171 test_pbo_functionality(gl_info
);
1174 static DWORD
wined3d_parse_gl_version(const char *gl_version
)
1176 const char *ptr
= gl_version
;
1180 if (major
<= 0) ERR_(d3d_caps
)("Invalid opengl major version: %d.\n", major
);
1182 while (isdigit(*ptr
)) ++ptr
;
1183 if (*ptr
++ != '.') ERR_(d3d_caps
)("Invalid opengl version string: %s.\n", debugstr_a(gl_version
));
1187 TRACE_(d3d_caps
)("Found OpenGL version: %d.%d.\n", major
, minor
);
1189 return MAKEDWORD_VERSION(major
, minor
);
1192 static enum wined3d_gl_vendor
wined3d_guess_gl_vendor(struct wined3d_gl_info
*gl_info
, const char *gl_vendor_string
, const char *gl_renderer
)
1195 /* MacOS has various specialities in the extensions it advertises. Some have to be loaded from
1196 * the opengl 1.2+ core, while other extensions are advertised, but software emulated. So try to
1197 * detect the Apple OpenGL implementation to apply some extension fixups afterwards.
1199 * Detecting this isn't really easy. The vendor string doesn't mention Apple. Compile-time checks
1200 * aren't sufficient either because a Linux binary may display on a macos X server via remote X11.
1201 * So try to detect the GL implementation by looking at certain Apple extensions. Some extensions
1202 * like client storage might be supported on other implementations too, but GL_APPLE_flush_render
1203 * is specific to the Mac OS X window management, and GL_APPLE_ycbcr_422 is QuickTime specific. So
1204 * the chance that other implementations support them is rather small since Win32 QuickTime uses
1205 * DirectDraw, not OpenGL. */
1206 if (gl_info
->supported
[APPLE_FENCE
]
1207 && gl_info
->supported
[APPLE_CLIENT_STORAGE
]
1208 && gl_info
->supported
[APPLE_FLUSH_RENDER
]
1209 && gl_info
->supported
[APPLE_YCBCR_422
])
1210 return GL_VENDOR_APPLE
;
1212 if (strstr(gl_vendor_string
, "NVIDIA"))
1213 return GL_VENDOR_NVIDIA
;
1215 if (strstr(gl_vendor_string
, "ATI"))
1216 return GL_VENDOR_FGLRX
;
1218 if (strstr(gl_vendor_string
, "Intel(R)")
1219 /* Intel switched from Intel(R) to Intel® recently, so just match Intel. */
1220 || strstr(gl_renderer
, "Intel")
1221 || strstr(gl_vendor_string
, "Intel Inc."))
1222 return GL_VENDOR_INTEL
;
1224 if (strstr(gl_vendor_string
, "Mesa")
1225 || strstr(gl_vendor_string
, "Advanced Micro Devices, Inc.")
1226 || strstr(gl_vendor_string
, "DRI R300 Project")
1227 || strstr(gl_vendor_string
, "X.Org R300 Project")
1228 || strstr(gl_vendor_string
, "Tungsten Graphics, Inc")
1229 || strstr(gl_vendor_string
, "VMware, Inc.")
1230 || strstr(gl_renderer
, "Mesa")
1231 || strstr(gl_renderer
, "Gallium"))
1232 return GL_VENDOR_MESA
;
1234 FIXME_(d3d_caps
)("Received unrecognized GL_VENDOR %s. Returning GL_VENDOR_UNKNOWN.\n",
1235 debugstr_a(gl_vendor_string
));
1237 return GL_VENDOR_UNKNOWN
;
1240 static enum wined3d_pci_vendor
wined3d_guess_card_vendor(const char *gl_vendor_string
, const char *gl_renderer
)
1242 if (strstr(gl_vendor_string
, "NVIDIA"))
1243 return HW_VENDOR_NVIDIA
;
1245 if (strstr(gl_vendor_string
, "ATI")
1246 || strstr(gl_vendor_string
, "Advanced Micro Devices, Inc.")
1247 || strstr(gl_vendor_string
, "X.Org R300 Project")
1248 || strstr(gl_vendor_string
, "DRI R300 Project"))
1249 return HW_VENDOR_ATI
;
1251 if (strstr(gl_vendor_string
, "Intel(R)")
1252 /* Intel switched from Intel(R) to Intel® recently, so just match Intel. */
1253 || strstr(gl_renderer
, "Intel")
1254 || strstr(gl_vendor_string
, "Intel Inc."))
1255 return HW_VENDOR_INTEL
;
1257 if (strstr(gl_vendor_string
, "Mesa")
1258 || strstr(gl_vendor_string
, "Tungsten Graphics, Inc")
1259 || strstr(gl_vendor_string
, "VMware, Inc."))
1260 return HW_VENDOR_SOFTWARE
;
1262 FIXME_(d3d_caps
)("Received unrecognized GL_VENDOR %s. Returning HW_VENDOR_NVIDIA.\n", debugstr_a(gl_vendor_string
));
1264 return HW_VENDOR_NVIDIA
;
1269 static enum wined3d_pci_device
select_card_nvidia_binary(const struct wined3d_gl_info
*gl_info
,
1270 const char *gl_renderer
, unsigned int *vidmem
)
1272 if (WINE_D3D10_CAPABLE(gl_info
))
1274 /* Geforce 400 - highend */
1275 if (strstr(gl_renderer
, "GTX 480"))
1278 return CARD_NVIDIA_GEFORCE_GTX480
;
1281 /* Geforce 400 - midend high */
1282 if (strstr(gl_renderer
, "GTX 470"))
1285 return CARD_NVIDIA_GEFORCE_GTX470
;
1288 /* Geforce 300 highend mobile */
1289 if (strstr(gl_renderer
, "GTS 350M")
1290 || strstr(gl_renderer
, "GTS 360M"))
1293 return CARD_NVIDIA_GEFORCE_GTS350M
;
1296 /* Geforce 300 midend mobile (Geforce GT 325M/330M use the same core) */
1297 if (strstr(gl_renderer
, "GT 325M")
1298 || strstr(gl_renderer
, "GT 330M"))
1301 return CARD_NVIDIA_GEFORCE_GT325M
;
1304 /* Geforce 200 - highend */
1305 if (strstr(gl_renderer
, "GTX 280")
1306 || strstr(gl_renderer
, "GTX 285")
1307 || strstr(gl_renderer
, "GTX 295"))
1310 return CARD_NVIDIA_GEFORCE_GTX280
;
1313 /* Geforce 200 - midend high */
1314 if (strstr(gl_renderer
, "GTX 275"))
1317 return CARD_NVIDIA_GEFORCE_GTX275
;
1320 /* Geforce 200 - midend */
1321 if (strstr(gl_renderer
, "GTX 260"))
1324 return CARD_NVIDIA_GEFORCE_GTX260
;
1326 /* Geforce 200 - midend */
1327 if (strstr(gl_renderer
, "GT 240"))
1330 return CARD_NVIDIA_GEFORCE_GT240
;
1333 /* Geforce 200 lowend */
1334 if (strstr(gl_renderer
, "GT 220"))
1336 *vidmem
= 512; /* The GT 220 has 512-1024MB */
1337 return CARD_NVIDIA_GEFORCE_GT220
;
1339 /* Geforce 200 lowend (Geforce 305/310 use the same core) */
1340 if (strstr(gl_renderer
, "Geforce 210")
1341 || strstr(gl_renderer
, "G 210")
1342 || strstr(gl_renderer
, "Geforce 305")
1343 || strstr(gl_renderer
, "Geforce 310"))
1346 return CARD_NVIDIA_GEFORCE_210
;
1349 /* Geforce9 - highend / Geforce 200 - midend (GTS 150/250 are based on the same core) */
1350 if (strstr(gl_renderer
, "9800")
1351 || strstr(gl_renderer
, "GTS 150")
1352 || strstr(gl_renderer
, "GTS 250"))
1355 return CARD_NVIDIA_GEFORCE_9800GT
;
1358 /* Geforce9 - midend (GT 140 uses the same core as the 9600GT) */
1359 if (strstr(gl_renderer
, "9600")
1360 || strstr(gl_renderer
, "GT 140"))
1362 *vidmem
= 384; /* The 9600GSO has 384MB, the 9600GT has 512-1024MB */
1363 return CARD_NVIDIA_GEFORCE_9600GT
;
1366 /* Geforce9 - midend low / Geforce 200 - low */
1367 if (strstr(gl_renderer
, "9500")
1368 || strstr(gl_renderer
, "GT 120")
1369 || strstr(gl_renderer
, "GT 130"))
1371 *vidmem
= 256; /* The 9500GT has 256-1024MB */
1372 return CARD_NVIDIA_GEFORCE_9500GT
;
1375 /* Geforce9 - lowend */
1376 if (strstr(gl_renderer
, "9400"))
1378 *vidmem
= 256; /* The 9400GT has 256-1024MB */
1379 return CARD_NVIDIA_GEFORCE_9400GT
;
1382 /* Geforce9 - lowend low */
1383 if (strstr(gl_renderer
, "9100")
1384 || strstr(gl_renderer
, "9200")
1385 || strstr(gl_renderer
, "9300")
1386 || strstr(gl_renderer
, "G 100"))
1388 *vidmem
= 256; /* The 9100-9300 cards have 256MB */
1389 return CARD_NVIDIA_GEFORCE_9200
;
1392 /* Geforce8 - highend high*/
1393 if (strstr(gl_renderer
, "8800 GTX"))
1396 return CARD_NVIDIA_GEFORCE_8800GTX
;
1399 /* Geforce8 - highend */
1400 if (strstr(gl_renderer
, "8800"))
1402 *vidmem
= 320; /* The 8800GTS uses 320MB, a 8800GTX can have 768MB */
1403 return CARD_NVIDIA_GEFORCE_8800GTS
;
1406 /* Geforce8 - midend mobile */
1407 if (strstr(gl_renderer
, "8600 M"))
1410 return CARD_NVIDIA_GEFORCE_8600MGT
;
1413 /* Geforce8 - midend */
1414 if (strstr(gl_renderer
, "8600")
1415 || strstr(gl_renderer
, "8700"))
1418 return CARD_NVIDIA_GEFORCE_8600GT
;
1421 /* Geforce8 - mid-lowend */
1422 if (strstr(gl_renderer
, "8400")
1423 || strstr(gl_renderer
, "8500"))
1425 *vidmem
= 128; /* 128-256MB for a 8400, 256-512MB for a 8500 */
1426 return CARD_NVIDIA_GEFORCE_8400GS
;
1429 /* Geforce8 - lowend */
1430 if (strstr(gl_renderer
, "8100")
1431 || strstr(gl_renderer
, "8200")
1432 || strstr(gl_renderer
, "8300"))
1434 *vidmem
= 128; /* 128-256MB for a 8300 */
1435 return CARD_NVIDIA_GEFORCE_8300GS
;
1438 /* Geforce8-compatible fall back if the GPU is not in the list yet */
1440 return CARD_NVIDIA_GEFORCE_8300GS
;
1443 /* Both the GeforceFX, 6xxx and 7xxx series support D3D9. The last two types have more
1444 * shader capabilities, so we use the shader capabilities to distinguish between FX and 6xxx/7xxx.
1446 if (WINE_D3D9_CAPABLE(gl_info
) && gl_info
->supported
[NV_VERTEX_PROGRAM3
])
1448 /* Geforce7 - highend */
1449 if (strstr(gl_renderer
, "7800")
1450 || strstr(gl_renderer
, "7900")
1451 || strstr(gl_renderer
, "7950")
1452 || strstr(gl_renderer
, "Quadro FX 4")
1453 || strstr(gl_renderer
, "Quadro FX 5"))
1455 *vidmem
= 256; /* A 7800GT uses 256MB while highend 7900 cards can use 512MB */
1456 return CARD_NVIDIA_GEFORCE_7800GT
;
1459 /* Geforce7 midend */
1460 if (strstr(gl_renderer
, "7600")
1461 || strstr(gl_renderer
, "7700"))
1463 *vidmem
= 256; /* The 7600 uses 256-512MB */
1464 return CARD_NVIDIA_GEFORCE_7600
;
1467 /* Geforce7 lower medium */
1468 if (strstr(gl_renderer
, "7400"))
1470 *vidmem
= 256; /* The 7400 uses 256-512MB */
1471 return CARD_NVIDIA_GEFORCE_7400
;
1474 /* Geforce7 lowend */
1475 if (strstr(gl_renderer
, "7300"))
1477 *vidmem
= 256; /* Mac Pros with this card have 256 MB */
1478 return CARD_NVIDIA_GEFORCE_7300
;
1481 /* Geforce6 highend */
1482 if (strstr(gl_renderer
, "6800"))
1484 *vidmem
= 128; /* The 6800 uses 128-256MB, the 7600 uses 256-512MB */
1485 return CARD_NVIDIA_GEFORCE_6800
;
1488 /* Geforce6 - midend */
1489 if (strstr(gl_renderer
, "6600")
1490 || strstr(gl_renderer
, "6610")
1491 || strstr(gl_renderer
, "6700"))
1493 *vidmem
= 128; /* A 6600GT has 128-256MB */
1494 return CARD_NVIDIA_GEFORCE_6600GT
;
1497 /* Geforce6/7 lowend */
1499 return CARD_NVIDIA_GEFORCE_6200
; /* Geforce 6100/6150/6200/7300/7400/7500 */
1502 if (WINE_D3D9_CAPABLE(gl_info
))
1504 /* GeforceFX - highend */
1505 if (strstr(gl_renderer
, "5800")
1506 || strstr(gl_renderer
, "5900")
1507 || strstr(gl_renderer
, "5950")
1508 || strstr(gl_renderer
, "Quadro FX"))
1510 *vidmem
= 256; /* 5800-5900 cards use 256MB */
1511 return CARD_NVIDIA_GEFORCEFX_5800
;
1514 /* GeforceFX - midend */
1515 if (strstr(gl_renderer
, "5600")
1516 || strstr(gl_renderer
, "5650")
1517 || strstr(gl_renderer
, "5700")
1518 || strstr(gl_renderer
, "5750"))
1520 *vidmem
= 128; /* A 5600 uses 128-256MB */
1521 return CARD_NVIDIA_GEFORCEFX_5600
;
1524 /* GeforceFX - lowend */
1525 *vidmem
= 64; /* Normal FX5200 cards use 64-256MB; laptop (non-standard) can have less */
1526 return CARD_NVIDIA_GEFORCEFX_5200
; /* GeforceFX 5100/5200/5250/5300/5500 */
1529 if (WINE_D3D8_CAPABLE(gl_info
))
1531 if (strstr(gl_renderer
, "GeForce4 Ti") || strstr(gl_renderer
, "Quadro4"))
1533 *vidmem
= 64; /* Geforce4 Ti cards have 64-128MB */
1534 return CARD_NVIDIA_GEFORCE4_TI4200
; /* Geforce4 Ti4200/Ti4400/Ti4600/Ti4800, Quadro4 */
1537 *vidmem
= 64; /* Geforce3 cards have 64-128MB */
1538 return CARD_NVIDIA_GEFORCE3
; /* Geforce3 standard/Ti200/Ti500, Quadro DCC */
1541 if (WINE_D3D7_CAPABLE(gl_info
))
1543 if (strstr(gl_renderer
, "GeForce4 MX"))
1545 /* Most Geforce4MX GPUs have at least 64MB of memory, some
1546 * early models had 32MB but most have 64MB or even 128MB. */
1548 return CARD_NVIDIA_GEFORCE4_MX
; /* MX420/MX440/MX460/MX4000 */
1551 if (strstr(gl_renderer
, "GeForce2 MX") || strstr(gl_renderer
, "Quadro2 MXR"))
1553 *vidmem
= 32; /* Geforce2MX GPUs have 32-64MB of video memory */
1554 return CARD_NVIDIA_GEFORCE2_MX
; /* Geforce2 standard/MX100/MX200/MX400, Quadro2 MXR */
1557 if (strstr(gl_renderer
, "GeForce2") || strstr(gl_renderer
, "Quadro2"))
1559 *vidmem
= 32; /* Geforce2 GPUs have 32-64MB of video memory */
1560 return CARD_NVIDIA_GEFORCE2
; /* Geforce2 GTS/Pro/Ti/Ultra, Quadro2 */
1563 /* Most Geforce1 cards have 32MB, there are also some rare 16
1564 * and 64MB (Dell) models. */
1566 return CARD_NVIDIA_GEFORCE
; /* Geforce 256/DDR, Quadro */
1569 if (strstr(gl_renderer
, "TNT2"))
1571 *vidmem
= 32; /* Most TNT2 boards have 32MB, though there are 16MB boards too */
1572 return CARD_NVIDIA_RIVA_TNT2
; /* Riva TNT2 standard/M64/Pro/Ultra */
1575 *vidmem
= 16; /* Most TNT boards have 16MB, some rare models have 8MB */
1576 return CARD_NVIDIA_RIVA_TNT
; /* Riva TNT, Vanta */
1580 static enum wined3d_pci_device
select_card_ati_binary(const struct wined3d_gl_info
*gl_info
,
1581 const char *gl_renderer
, unsigned int *vidmem
)
1583 /* See http://developer.amd.com/drivers/pc_vendor_id/Pages/default.aspx
1585 * Beware: renderer string do not match exact card model,
1586 * eg HD 4800 is returned for multiple cards, even for RV790 based ones. */
1587 if (WINE_D3D10_CAPABLE(gl_info
))
1589 /* Radeon EG CYPRESS XT / PRO HD5800 - highend */
1590 if (strstr(gl_renderer
, "HD 5800") /* Radeon EG CYPRESS HD58xx generic renderer string */
1591 || strstr(gl_renderer
, "HD 5850") /* Radeon EG CYPRESS XT */
1592 || strstr(gl_renderer
, "HD 5870")) /* Radeon EG CYPRESS PRO */
1594 *vidmem
= 1024; /* note: HD58xx cards use 1024MB */
1595 return CARD_ATI_RADEON_HD5800
;
1598 /* Radeon EG JUNIPER XT / LE HD5700 - midend */
1599 if (strstr(gl_renderer
, "HD 5700") /* Radeon EG JUNIPER HD57xx generic renderer string */
1600 || strstr(gl_renderer
, "HD 5750") /* Radeon EG JUNIPER LE */
1601 || strstr(gl_renderer
, "HD 5770")) /* Radeon EG JUNIPER XT */
1603 *vidmem
= 512; /* note: HD5770 cards use 1024MB and HD5750 cards use 512MB or 1024MB */
1604 return CARD_ATI_RADEON_HD5700
;
1607 /* Radeon R7xx HD4800 - highend */
1608 if (strstr(gl_renderer
, "HD 4800") /* Radeon RV7xx HD48xx generic renderer string */
1609 || strstr(gl_renderer
, "HD 4830") /* Radeon RV770 */
1610 || strstr(gl_renderer
, "HD 4850") /* Radeon RV770 */
1611 || strstr(gl_renderer
, "HD 4870") /* Radeon RV770 */
1612 || strstr(gl_renderer
, "HD 4890")) /* Radeon RV790 */
1614 *vidmem
= 512; /* note: HD4890 cards use 1024MB */
1615 return CARD_ATI_RADEON_HD4800
;
1618 /* Radeon R740 HD4700 - midend */
1619 if (strstr(gl_renderer
, "HD 4700") /* Radeon RV770 */
1620 || strstr(gl_renderer
, "HD 4770")) /* Radeon RV740 */
1623 return CARD_ATI_RADEON_HD4700
;
1626 /* Radeon R730 HD4600 - midend */
1627 if (strstr(gl_renderer
, "HD 4600") /* Radeon RV730 */
1628 || strstr(gl_renderer
, "HD 4650") /* Radeon RV730 */
1629 || strstr(gl_renderer
, "HD 4670")) /* Radeon RV730 */
1632 return CARD_ATI_RADEON_HD4600
;
1635 /* Radeon R710 HD4500/HD4350 - lowend */
1636 if (strstr(gl_renderer
, "HD 4350") /* Radeon RV710 */
1637 || strstr(gl_renderer
, "HD 4550")) /* Radeon RV710 */
1640 return CARD_ATI_RADEON_HD4350
;
1643 /* Radeon R6xx HD2900/HD3800 - highend */
1644 if (strstr(gl_renderer
, "HD 2900")
1645 || strstr(gl_renderer
, "HD 3870")
1646 || strstr(gl_renderer
, "HD 3850"))
1648 *vidmem
= 512; /* HD2900/HD3800 uses 256-1024MB */
1649 return CARD_ATI_RADEON_HD2900
;
1652 /* Radeon R6xx HD2600/HD3600 - midend; HD3830 is China-only midend */
1653 if (strstr(gl_renderer
, "HD 2600")
1654 || strstr(gl_renderer
, "HD 3830")
1655 || strstr(gl_renderer
, "HD 3690")
1656 || strstr(gl_renderer
, "HD 3650"))
1658 *vidmem
= 256; /* HD2600/HD3600 uses 256-512MB */
1659 return CARD_ATI_RADEON_HD2600
;
1662 /* Radeon R6xx HD2350/HD2400/HD3400 - lowend
1663 * Note HD2300=DX9, HD2350=DX10 */
1664 if (strstr(gl_renderer
, "HD 2350")
1665 || strstr(gl_renderer
, "HD 2400")
1666 || strstr(gl_renderer
, "HD 3470")
1667 || strstr(gl_renderer
, "HD 3450")
1668 || strstr(gl_renderer
, "HD 3430")
1669 || strstr(gl_renderer
, "HD 3400"))
1671 *vidmem
= 256; /* HD2350/2400 use 256MB, HD34xx use 256-512MB */
1672 return CARD_ATI_RADEON_HD2350
;
1675 /* Radeon R6xx/R7xx integrated */
1676 if (strstr(gl_renderer
, "HD 3100")
1677 || strstr(gl_renderer
, "HD 3200")
1678 || strstr(gl_renderer
, "HD 3300"))
1680 *vidmem
= 128; /* 128MB */
1681 return CARD_ATI_RADEON_HD3200
;
1684 /* Default for when no GPU has been found */
1685 *vidmem
= 128; /* 128MB */
1686 return CARD_ATI_RADEON_HD3200
;
1689 if (WINE_D3D8_CAPABLE(gl_info
))
1692 if (strstr(gl_renderer
, "X1600")
1693 || strstr(gl_renderer
, "X1650")
1694 || strstr(gl_renderer
, "X1800")
1695 || strstr(gl_renderer
, "X1900")
1696 || strstr(gl_renderer
, "X1950"))
1698 *vidmem
= 128; /* X1600 uses 128-256MB, >=X1800 uses 256MB */
1699 return CARD_ATI_RADEON_X1600
;
1702 /* Radeon R4xx + X1300/X1400/X1450/X1550/X2300/X2500/HD2300 (lowend R5xx)
1703 * Note X2300/X2500/HD2300 are R5xx GPUs with a 2xxx naming but they are still DX9-only */
1704 if (strstr(gl_renderer
, "X700")
1705 || strstr(gl_renderer
, "X800")
1706 || strstr(gl_renderer
, "X850")
1707 || strstr(gl_renderer
, "X1300")
1708 || strstr(gl_renderer
, "X1400")
1709 || strstr(gl_renderer
, "X1450")
1710 || strstr(gl_renderer
, "X1550")
1711 || strstr(gl_renderer
, "X2300")
1712 || strstr(gl_renderer
, "X2500")
1713 || strstr(gl_renderer
, "HD 2300")
1716 *vidmem
= 128; /* x700/x8*0 use 128-256MB, >=x1300 128-512MB */
1717 return CARD_ATI_RADEON_X700
;
1720 /* Radeon Xpress Series - onboard, DX9b, Shader 2.0, 300-400MHz */
1721 if (strstr(gl_renderer
, "Radeon Xpress"))
1723 *vidmem
= 64; /* Shared RAM, BIOS configurable, 64-256M */
1724 return CARD_ATI_RADEON_XPRESS_200M
;
1728 *vidmem
= 64; /* Radeon 9500 uses 64MB, higher models use up to 256MB */
1729 return CARD_ATI_RADEON_9500
; /* Radeon 9500/9550/9600/9700/9800/X300/X550/X600 */
1732 if (WINE_D3D8_CAPABLE(gl_info
))
1734 *vidmem
= 64; /* 8500/9000 cards use mostly 64MB, though there are 32MB and 128MB models */
1735 return CARD_ATI_RADEON_8500
; /* Radeon 8500/9000/9100/9200/9300 */
1738 if (WINE_D3D7_CAPABLE(gl_info
))
1740 *vidmem
= 32; /* There are models with up to 64MB */
1741 return CARD_ATI_RADEON_7200
; /* Radeon 7000/7100/7200/7500 */
1744 *vidmem
= 16; /* There are 16-32MB models */
1745 return CARD_ATI_RAGE_128PRO
;
1749 static enum wined3d_pci_device
select_card_intel_binary(const struct wined3d_gl_info
*gl_info
,
1750 const char *gl_renderer
, unsigned int *vidmem
)
1752 if (strstr(gl_renderer
, "X3100"))
1754 /* MacOS calls the card GMA X3100, otherwise known as GM965/GL960 */
1756 return CARD_INTEL_X3100
;
1759 if (strstr(gl_renderer
, "GMA 950") || strstr(gl_renderer
, "945GM"))
1761 /* MacOS calls the card GMA 950, but everywhere else the PCI ID is named 945GM */
1763 return CARD_INTEL_I945GM
;
1766 if (strstr(gl_renderer
, "915GM")) return CARD_INTEL_I915GM
;
1767 if (strstr(gl_renderer
, "915G")) return CARD_INTEL_I915G
;
1768 if (strstr(gl_renderer
, "865G")) return CARD_INTEL_I865G
;
1769 if (strstr(gl_renderer
, "855G")) return CARD_INTEL_I855G
;
1770 if (strstr(gl_renderer
, "830G")) return CARD_INTEL_I830G
;
1771 return CARD_INTEL_I915G
;
1775 static enum wined3d_pci_device
select_card_ati_mesa(const struct wined3d_gl_info
*gl_info
,
1776 const char *gl_renderer
, unsigned int *vidmem
)
1778 /* See http://developer.amd.com/drivers/pc_vendor_id/Pages/default.aspx
1780 * Beware: renderer string do not match exact card model,
1781 * eg HD 4800 is returned for multiple cards, even for RV790 based ones. */
1782 if (strstr(gl_renderer
, "Gallium"))
1784 /* Radeon R7xx HD4800 - highend */
1785 if (strstr(gl_renderer
, "R700") /* Radeon R7xx HD48xx generic renderer string */
1786 || strstr(gl_renderer
, "RV770") /* Radeon RV770 */
1787 || strstr(gl_renderer
, "RV790")) /* Radeon RV790 */
1789 *vidmem
= 512; /* note: HD4890 cards use 1024MB */
1790 return CARD_ATI_RADEON_HD4800
;
1793 /* Radeon R740 HD4700 - midend */
1794 if (strstr(gl_renderer
, "RV740")) /* Radeon RV740 */
1797 return CARD_ATI_RADEON_HD4700
;
1800 /* Radeon R730 HD4600 - midend */
1801 if (strstr(gl_renderer
, "RV730")) /* Radeon RV730 */
1804 return CARD_ATI_RADEON_HD4600
;
1807 /* Radeon R710 HD4500/HD4350 - lowend */
1808 if (strstr(gl_renderer
, "RV710")) /* Radeon RV710 */
1811 return CARD_ATI_RADEON_HD4350
;
1814 /* Radeon R6xx HD2900/HD3800 - highend */
1815 if (strstr(gl_renderer
, "R600")
1816 || strstr(gl_renderer
, "RV670")
1817 || strstr(gl_renderer
, "R680"))
1819 *vidmem
= 512; /* HD2900/HD3800 uses 256-1024MB */
1820 return CARD_ATI_RADEON_HD2900
;
1823 /* Radeon R6xx HD2600/HD3600 - midend; HD3830 is China-only midend */
1824 if (strstr(gl_renderer
, "RV630")
1825 || strstr(gl_renderer
, "RV635"))
1827 *vidmem
= 256; /* HD2600/HD3600 uses 256-512MB */
1828 return CARD_ATI_RADEON_HD2600
;
1831 /* Radeon R6xx HD2350/HD2400/HD3400 - lowend */
1832 if (strstr(gl_renderer
, "RV610")
1833 || strstr(gl_renderer
, "RV620"))
1835 *vidmem
= 256; /* HD2350/2400 use 256MB, HD34xx use 256-512MB */
1836 return CARD_ATI_RADEON_HD2350
;
1839 /* Radeon R6xx/R7xx integrated */
1840 if (strstr(gl_renderer
, "RS780")
1841 || strstr(gl_renderer
, "RS880"))
1843 *vidmem
= 128; /* 128MB */
1844 return CARD_ATI_RADEON_HD3200
;
1848 if (strstr(gl_renderer
, "RV530")
1849 || strstr(gl_renderer
, "RV535")
1850 || strstr(gl_renderer
, "RV560")
1851 || strstr(gl_renderer
, "R520")
1852 || strstr(gl_renderer
, "RV570")
1853 || strstr(gl_renderer
, "R580"))
1855 *vidmem
= 128; /* X1600 uses 128-256MB, >=X1800 uses 256MB */
1856 return CARD_ATI_RADEON_X1600
;
1859 /* Radeon R4xx + X1300/X1400/X1450/X1550/X2300 (lowend R5xx) */
1860 if (strstr(gl_renderer
, "R410")
1861 || strstr(gl_renderer
, "R420")
1862 || strstr(gl_renderer
, "R423")
1863 || strstr(gl_renderer
, "R430")
1864 || strstr(gl_renderer
, "R480")
1865 || strstr(gl_renderer
, "R481")
1866 || strstr(gl_renderer
, "RV410")
1867 || strstr(gl_renderer
, "RV515")
1868 || strstr(gl_renderer
, "RV516"))
1870 *vidmem
= 128; /* x700/x8*0 use 128-256MB, >=x1300 128-512MB */
1871 return CARD_ATI_RADEON_X700
;
1874 /* Radeon Xpress Series - onboard, DX9b, Shader 2.0, 300-400MHz */
1875 if (strstr(gl_renderer
, "RS400")
1876 || strstr(gl_renderer
, "RS480")
1877 || strstr(gl_renderer
, "RS482")
1878 || strstr(gl_renderer
, "RS485")
1879 || strstr(gl_renderer
, "RS600")
1880 || strstr(gl_renderer
, "RS690")
1881 || strstr(gl_renderer
, "RS740"))
1883 *vidmem
= 64; /* Shared RAM, BIOS configurable, 64-256M */
1884 return CARD_ATI_RADEON_XPRESS_200M
;
1888 if (strstr(gl_renderer
, "R300")
1889 || strstr(gl_renderer
, "RV350")
1890 || strstr(gl_renderer
, "RV351")
1891 || strstr(gl_renderer
, "RV360")
1892 || strstr(gl_renderer
, "RV370")
1893 || strstr(gl_renderer
, "R350")
1894 || strstr(gl_renderer
, "R360"))
1896 *vidmem
= 64; /* Radeon 9500 uses 64MB, higher models use up to 256MB */
1897 return CARD_ATI_RADEON_9500
; /* Radeon 9500/9550/9600/9700/9800/X300/X550/X600 */
1901 if (WINE_D3D9_CAPABLE(gl_info
))
1903 /* Radeon R7xx HD4800 - highend */
1904 if (strstr(gl_renderer
, "(R700") /* Radeon R7xx HD48xx generic renderer string */
1905 || strstr(gl_renderer
, "(RV770") /* Radeon RV770 */
1906 || strstr(gl_renderer
, "(RV790")) /* Radeon RV790 */
1908 *vidmem
= 512; /* note: HD4890 cards use 1024MB */
1909 return CARD_ATI_RADEON_HD4800
;
1912 /* Radeon R740 HD4700 - midend */
1913 if (strstr(gl_renderer
, "(RV740")) /* Radeon RV740 */
1916 return CARD_ATI_RADEON_HD4700
;
1919 /* Radeon R730 HD4600 - midend */
1920 if (strstr(gl_renderer
, "(RV730")) /* Radeon RV730 */
1923 return CARD_ATI_RADEON_HD4600
;
1926 /* Radeon R710 HD4500/HD4350 - lowend */
1927 if (strstr(gl_renderer
, "(RV710")) /* Radeon RV710 */
1930 return CARD_ATI_RADEON_HD4350
;
1933 /* Radeon R6xx HD2900/HD3800 - highend */
1934 if (strstr(gl_renderer
, "(R600")
1935 || strstr(gl_renderer
, "(RV670")
1936 || strstr(gl_renderer
, "(R680"))
1938 *vidmem
= 512; /* HD2900/HD3800 uses 256-1024MB */
1939 return CARD_ATI_RADEON_HD2900
;
1942 /* Radeon R6xx HD2600/HD3600 - midend; HD3830 is China-only midend */
1943 if (strstr(gl_renderer
, "(RV630")
1944 || strstr(gl_renderer
, "(RV635"))
1946 *vidmem
= 256; /* HD2600/HD3600 uses 256-512MB */
1947 return CARD_ATI_RADEON_HD2600
;
1950 /* Radeon R6xx HD2300/HD2400/HD3400 - lowend */
1951 if (strstr(gl_renderer
, "(RV610")
1952 || strstr(gl_renderer
, "(RV620"))
1954 *vidmem
= 256; /* HD2350/2400 use 256MB, HD34xx use 256-512MB */
1955 return CARD_ATI_RADEON_HD2350
;
1958 /* Radeon R6xx/R7xx integrated */
1959 if (strstr(gl_renderer
, "(RS780")
1960 || strstr(gl_renderer
, "(RS880"))
1962 *vidmem
= 128; /* 128MB */
1963 return CARD_ATI_RADEON_HD3200
;
1967 if (WINE_D3D8_CAPABLE(gl_info
))
1969 *vidmem
= 64; /* 8500/9000 cards use mostly 64MB, though there are 32MB and 128MB models */
1970 return CARD_ATI_RADEON_8500
; /* Radeon 8500/9000/9100/9200/9300 */
1973 if (WINE_D3D7_CAPABLE(gl_info
))
1975 *vidmem
= 32; /* There are models with up to 64MB */
1976 return CARD_ATI_RADEON_7200
; /* Radeon 7000/7100/7200/7500 */
1979 *vidmem
= 16; /* There are 16-32MB models */
1980 return CARD_ATI_RAGE_128PRO
;
1984 static enum wined3d_pci_device
select_card_nvidia_mesa(const struct wined3d_gl_info
*gl_info
,
1985 const char *gl_renderer
, unsigned int *vidmem
)
1987 FIXME_(d3d_caps
)("Card selection not handled for Mesa Nouveau driver\n");
1988 if (WINE_D3D9_CAPABLE(gl_info
)) return CARD_NVIDIA_GEFORCEFX_5600
;
1989 if (WINE_D3D8_CAPABLE(gl_info
)) return CARD_NVIDIA_GEFORCE3
;
1990 if (WINE_D3D7_CAPABLE(gl_info
)) return CARD_NVIDIA_GEFORCE
;
1991 if (WINE_D3D6_CAPABLE(gl_info
)) return CARD_NVIDIA_RIVA_TNT
;
1992 return CARD_NVIDIA_RIVA_128
;
1995 static enum wined3d_pci_device
select_card_intel_mesa(const struct wined3d_gl_info
*gl_info
,
1996 const char *gl_renderer
, unsigned int *vidmem
)
1998 FIXME_(d3d_caps
)("Card selection not handled for Mesa Intel driver\n");
1999 return CARD_INTEL_I915G
;
2003 struct vendor_card_selection
2005 enum wined3d_gl_vendor gl_vendor
;
2006 enum wined3d_pci_vendor card_vendor
;
2007 const char *description
; /* Description of the card selector i.e. Apple OS/X Intel */
2008 enum wined3d_pci_device (*select_card
)(const struct wined3d_gl_info
*gl_info
, const char *gl_renderer
,
2009 unsigned int *vidmem
);
2012 static const struct vendor_card_selection vendor_card_select_table
[] =
2014 {GL_VENDOR_NVIDIA
, HW_VENDOR_NVIDIA
, "Nvidia binary driver", select_card_nvidia_binary
},
2015 {GL_VENDOR_APPLE
, HW_VENDOR_NVIDIA
, "Apple OSX NVidia binary driver", select_card_nvidia_binary
},
2016 {GL_VENDOR_APPLE
, HW_VENDOR_ATI
, "Apple OSX AMD/ATI binary driver", select_card_ati_binary
},
2017 {GL_VENDOR_APPLE
, HW_VENDOR_INTEL
, "Apple OSX Intel binary driver", select_card_intel_binary
},
2018 {GL_VENDOR_FGLRX
, HW_VENDOR_ATI
, "AMD/ATI binary driver", select_card_ati_binary
},
2019 {GL_VENDOR_MESA
, HW_VENDOR_ATI
, "Mesa AMD/ATI driver", select_card_ati_mesa
},
2020 {GL_VENDOR_MESA
, HW_VENDOR_NVIDIA
, "Mesa Nouveau driver", select_card_nvidia_mesa
},
2021 {GL_VENDOR_MESA
, HW_VENDOR_INTEL
, "Mesa Intel driver", select_card_intel_mesa
},
2022 {GL_VENDOR_INTEL
, HW_VENDOR_INTEL
, "Mesa Intel driver", select_card_intel_mesa
}
2026 static enum wined3d_pci_device
wined3d_guess_card(const struct wined3d_gl_info
*gl_info
, const char *gl_renderer
,
2027 enum wined3d_gl_vendor
*gl_vendor
, enum wined3d_pci_vendor
*card_vendor
, unsigned int *vidmem
)
2029 /* Above is a list of Nvidia and ATI GPUs. Both vendors have dozens of
2030 * different GPUs with roughly the same features. In most cases GPUs from a
2031 * certain family differ in clockspeeds, the amount of video memory and the
2032 * number of shader pipelines.
2034 * A Direct3D device object contains the PCI id (vendor + device) of the
2035 * videocard which is used for rendering. Various applications use this
2036 * information to get a rough estimation of the features of the card and
2037 * some might use it for enabling 3d effects only on certain types of
2038 * videocards. In some cases games might even use it to work around bugs
2039 * which happen on certain videocards/driver combinations. The problem is
2040 * that OpenGL only exposes a rendering string containing the name of the
2041 * videocard and not the PCI id.
2043 * Various games depend on the PCI id, so somehow we need to provide one.
2044 * A simple option is to parse the renderer string and translate this to
2045 * the right PCI id. This is a lot of work because there are more than 200
2046 * GPUs just for Nvidia. Various cards share the same renderer string, so
2047 * the amount of code might be 'small' but there are quite a number of
2048 * exceptions which would make this a pain to maintain. Another way would
2049 * be to query the PCI id from the operating system (assuming this is the
2050 * videocard which is used for rendering which is not always the case).
2051 * This would work but it is not very portable. Second it would not work
2052 * well in, let's say, a remote X situation in which the amount of 3d
2053 * features which can be used is limited.
2055 * As said most games only use the PCI id to get an indication of the
2056 * capabilities of the card. It doesn't really matter if the given id is
2057 * the correct one if we return the id of a card with similar 3d features.
2059 * The code below checks the OpenGL capabilities of a videocard and matches
2060 * that to a certain level of Direct3D functionality. Once a card passes
2061 * the Direct3D9 check, we know that the card (in case of Nvidia) is at
2062 * least a GeforceFX. To give a better estimate we do a basic check on the
2063 * renderer string but if that won't pass we return a default card. This
2064 * way is better than maintaining a full card database as even without a
2065 * full database we can return a card with similar features. Second the
2066 * size of the database can be made quite small because when you know what
2067 * type of 3d functionality a card has, you know to which GPU family the
2068 * GPU must belong. Because of this you only have to check a small part of
2069 * the renderer string to distinguishes between different models from that
2072 * The code also selects a default amount of video memory which we will
2073 * use for an estimation of the amount of free texture memory. In case of
2074 * real D3D the amount of texture memory includes video memory and system
2075 * memory (to be specific AGP memory or in case of PCIE TurboCache /
2076 * HyperMemory). We don't know how much system memory can be addressed by
2077 * the system but we can make a reasonable estimation about the amount of
2078 * video memory. If the value is slightly wrong it doesn't matter as we
2079 * didn't include AGP-like memory which makes the amount of addressable
2080 * memory higher and second OpenGL isn't that critical it moves to system
2081 * memory behind our backs if really needed. Note that the amount of video
2082 * memory can be overruled using a registry setting. */
2086 for (i
= 0; i
< (sizeof(vendor_card_select_table
) / sizeof(*vendor_card_select_table
)); ++i
)
2088 if ((vendor_card_select_table
[i
].gl_vendor
!= *gl_vendor
)
2089 || (vendor_card_select_table
[i
].card_vendor
!= *card_vendor
))
2091 TRACE_(d3d_caps
)("Applying card_selector \"%s\".\n", vendor_card_select_table
[i
].description
);
2092 return vendor_card_select_table
[i
].select_card(gl_info
, gl_renderer
, vidmem
);
2095 FIXME_(d3d_caps
)("No card selector available for GL vendor %d and card vendor %04x.\n",
2096 *gl_vendor
, *card_vendor
);
2098 /* Default to generic Nvidia hardware based on the supported OpenGL extensions. The choice
2099 * for Nvidia was because the hardware and drivers they make are of good quality. This makes
2100 * them a good generic choice. */
2101 *card_vendor
= HW_VENDOR_NVIDIA
;
2102 if (WINE_D3D9_CAPABLE(gl_info
)) return CARD_NVIDIA_GEFORCEFX_5600
;
2103 if (WINE_D3D8_CAPABLE(gl_info
)) return CARD_NVIDIA_GEFORCE3
;
2104 if (WINE_D3D7_CAPABLE(gl_info
)) return CARD_NVIDIA_GEFORCE
;
2105 if (WINE_D3D6_CAPABLE(gl_info
)) return CARD_NVIDIA_RIVA_TNT
;
2106 return CARD_NVIDIA_RIVA_128
;
2109 static const struct fragment_pipeline
*select_fragment_implementation(struct wined3d_adapter
*adapter
)
2111 const struct wined3d_gl_info
*gl_info
= &adapter
->gl_info
;
2112 int vs_selected_mode
, ps_selected_mode
;
2114 select_shader_mode(gl_info
, &ps_selected_mode
, &vs_selected_mode
);
2115 if ((ps_selected_mode
== SHADER_ARB
|| ps_selected_mode
== SHADER_GLSL
)
2116 && gl_info
->supported
[ARB_FRAGMENT_PROGRAM
]) return &arbfp_fragment_pipeline
;
2117 else if (ps_selected_mode
== SHADER_ATI
) return &atifs_fragment_pipeline
;
2118 else if (gl_info
->supported
[NV_REGISTER_COMBINERS
]
2119 && gl_info
->supported
[NV_TEXTURE_SHADER2
]) return &nvts_fragment_pipeline
;
2120 else if (gl_info
->supported
[NV_REGISTER_COMBINERS
]) return &nvrc_fragment_pipeline
;
2121 else return &ffp_fragment_pipeline
;
2124 static const shader_backend_t
*select_shader_backend(struct wined3d_adapter
*adapter
)
2126 int vs_selected_mode
, ps_selected_mode
;
2128 select_shader_mode(&adapter
->gl_info
, &ps_selected_mode
, &vs_selected_mode
);
2129 if (vs_selected_mode
== SHADER_GLSL
|| ps_selected_mode
== SHADER_GLSL
) return &glsl_shader_backend
;
2130 if (vs_selected_mode
== SHADER_ARB
|| ps_selected_mode
== SHADER_ARB
) return &arb_program_shader_backend
;
2131 return &none_shader_backend
;
2134 static const struct blit_shader
*select_blit_implementation(struct wined3d_adapter
*adapter
)
2136 const struct wined3d_gl_info
*gl_info
= &adapter
->gl_info
;
2137 int vs_selected_mode
, ps_selected_mode
;
2139 select_shader_mode(gl_info
, &ps_selected_mode
, &vs_selected_mode
);
2140 if ((ps_selected_mode
== SHADER_ARB
|| ps_selected_mode
== SHADER_GLSL
)
2141 && gl_info
->supported
[ARB_FRAGMENT_PROGRAM
]) return &arbfp_blit
;
2142 else return &ffp_blit
;
2145 /* Context activation is done by the caller. */
2146 static BOOL
IWineD3DImpl_FillGLCaps(struct wined3d_adapter
*adapter
)
2148 struct wined3d_driver_info
*driver_info
= &adapter
->driver_info
;
2149 struct wined3d_gl_info
*gl_info
= &adapter
->gl_info
;
2150 const char *GL_Extensions
= NULL
;
2151 const char *WGL_Extensions
= NULL
;
2152 const char *gl_vendor_str
, *gl_renderer_str
, *gl_version_str
;
2153 struct fragment_caps fragment_caps
;
2154 enum wined3d_gl_vendor gl_vendor
;
2155 enum wined3d_pci_vendor card_vendor
;
2156 enum wined3d_pci_device device
;
2158 GLfloat gl_floatv
[2];
2161 unsigned int vidmem
=0;
2165 TRACE_(d3d_caps
)("(%p)\n", gl_info
);
2169 gl_renderer_str
= (const char *)glGetString(GL_RENDERER
);
2170 TRACE_(d3d_caps
)("GL_RENDERER: %s.\n", debugstr_a(gl_renderer_str
));
2171 if (!gl_renderer_str
)
2174 ERR_(d3d_caps
)("Received a NULL GL_RENDERER.\n");
2178 gl_vendor_str
= (const char *)glGetString(GL_VENDOR
);
2179 TRACE_(d3d_caps
)("GL_VENDOR: %s.\n", debugstr_a(gl_vendor_str
));
2183 ERR_(d3d_caps
)("Received a NULL GL_VENDOR.\n");
2187 /* Parse the GL_VERSION field into major and minor information */
2188 gl_version_str
= (const char *)glGetString(GL_VERSION
);
2189 TRACE_(d3d_caps
)("GL_VERSION: %s.\n", debugstr_a(gl_version_str
));
2190 if (!gl_version_str
)
2193 ERR_(d3d_caps
)("Received a NULL GL_VERSION.\n");
2196 gl_version
= wined3d_parse_gl_version(gl_version_str
);
2199 * Initialize openGL extension related variables
2200 * with Default values
2202 memset(gl_info
->supported
, 0, sizeof(gl_info
->supported
));
2203 gl_info
->limits
.blends
= 1;
2204 gl_info
->limits
.buffers
= 1;
2205 gl_info
->limits
.textures
= 1;
2206 gl_info
->limits
.fragment_samplers
= 1;
2207 gl_info
->limits
.vertex_samplers
= 0;
2208 gl_info
->limits
.combined_samplers
= gl_info
->limits
.fragment_samplers
+ gl_info
->limits
.vertex_samplers
;
2209 gl_info
->limits
.sampler_stages
= 1;
2210 gl_info
->limits
.glsl_vs_float_constants
= 0;
2211 gl_info
->limits
.glsl_ps_float_constants
= 0;
2212 gl_info
->limits
.arb_vs_float_constants
= 0;
2213 gl_info
->limits
.arb_vs_native_constants
= 0;
2214 gl_info
->limits
.arb_vs_instructions
= 0;
2215 gl_info
->limits
.arb_vs_temps
= 0;
2216 gl_info
->limits
.arb_ps_float_constants
= 0;
2217 gl_info
->limits
.arb_ps_local_constants
= 0;
2218 gl_info
->limits
.arb_ps_instructions
= 0;
2219 gl_info
->limits
.arb_ps_temps
= 0;
2221 /* Retrieve opengl defaults */
2222 glGetIntegerv(GL_MAX_CLIP_PLANES
, &gl_max
);
2223 gl_info
->limits
.clipplanes
= min(WINED3DMAXUSERCLIPPLANES
, gl_max
);
2224 TRACE_(d3d_caps
)("ClipPlanes support - num Planes=%d\n", gl_max
);
2226 glGetIntegerv(GL_MAX_LIGHTS
, &gl_max
);
2227 gl_info
->limits
.lights
= gl_max
;
2228 TRACE_(d3d_caps
)("Lights support - max lights=%d\n", gl_max
);
2230 glGetIntegerv(GL_MAX_TEXTURE_SIZE
, &gl_max
);
2231 gl_info
->limits
.texture_size
= gl_max
;
2232 TRACE_(d3d_caps
)("Maximum texture size support - max texture size=%d\n", gl_max
);
2234 glGetFloatv(GL_ALIASED_POINT_SIZE_RANGE
, gl_floatv
);
2235 gl_info
->limits
.pointsize_min
= gl_floatv
[0];
2236 gl_info
->limits
.pointsize_max
= gl_floatv
[1];
2237 TRACE_(d3d_caps
)("Maximum point size support - max point size=%f\n", gl_floatv
[1]);
2239 /* Parse the gl supported features, in theory enabling parts of our code appropriately. */
2240 GL_Extensions
= (const char *)glGetString(GL_EXTENSIONS
);
2244 ERR_(d3d_caps
)("Received a NULL GL_EXTENSIONS.\n");
2250 TRACE_(d3d_caps
)("GL_Extensions reported:\n");
2252 gl_info
->supported
[WINED3D_GL_EXT_NONE
] = TRUE
;
2254 while (*GL_Extensions
)
2257 char current_ext
[256];
2259 while (isspace(*GL_Extensions
)) ++GL_Extensions
;
2260 start
= GL_Extensions
;
2261 while (!isspace(*GL_Extensions
) && *GL_Extensions
) ++GL_Extensions
;
2263 len
= GL_Extensions
- start
;
2264 if (!len
|| len
>= sizeof(current_ext
)) continue;
2266 memcpy(current_ext
, start
, len
);
2267 current_ext
[len
] = '\0';
2268 TRACE_(d3d_caps
)("- %s\n", debugstr_a(current_ext
));
2270 for (i
= 0; i
< (sizeof(EXTENSION_MAP
) / sizeof(*EXTENSION_MAP
)); ++i
)
2272 if (!strcmp(current_ext
, EXTENSION_MAP
[i
].extension_string
))
2274 TRACE_(d3d_caps
)(" FOUND: %s support.\n", EXTENSION_MAP
[i
].extension_string
);
2275 gl_info
->supported
[EXTENSION_MAP
[i
].extension
] = TRUE
;
2281 /* Now work out what GL support this card really has */
2282 #define USE_GL_FUNC(type, pfn, ext, replace) \
2284 DWORD ver = ver_for_ext(ext); \
2285 if (gl_info->supported[ext]) gl_info->pfn = (type)pwglGetProcAddress(#pfn); \
2286 else if (ver && ver <= gl_version) gl_info->pfn = (type)pwglGetProcAddress(#replace); \
2287 else gl_info->pfn = NULL; \
2292 #define USE_GL_FUNC(type, pfn, ext, replace) gl_info->pfn = (type)pwglGetProcAddress(#pfn);
2298 /* Now mark all the extensions supported which are included in the opengl core version. Do this *after*
2299 * loading the functions, otherwise the code above will load the extension entry points instead of the
2300 * core functions, which may not work. */
2301 for (i
= 0; i
< (sizeof(EXTENSION_MAP
) / sizeof(*EXTENSION_MAP
)); ++i
)
2303 if (!gl_info
->supported
[EXTENSION_MAP
[i
].extension
]
2304 && EXTENSION_MAP
[i
].version
<= gl_version
&& EXTENSION_MAP
[i
].version
)
2306 TRACE_(d3d_caps
)(" GL CORE: %s support.\n", EXTENSION_MAP
[i
].extension_string
);
2307 gl_info
->supported
[EXTENSION_MAP
[i
].extension
] = TRUE
;
2311 if (gl_version
>= MAKEDWORD_VERSION(2, 0)) gl_info
->supported
[WINED3D_GL_VERSION_2_0
] = TRUE
;
2313 if (gl_info
->supported
[APPLE_FENCE
])
2315 /* GL_NV_fence and GL_APPLE_fence provide the same functionality basically.
2316 * The apple extension interacts with some other apple exts. Disable the NV
2317 * extension if the apple one is support to prevent confusion in other parts
2319 gl_info
->supported
[NV_FENCE
] = FALSE
;
2321 if (gl_info
->supported
[APPLE_FLOAT_PIXELS
])
2323 /* GL_APPLE_float_pixels == GL_ARB_texture_float + GL_ARB_half_float_pixel
2325 * The enums are the same:
2326 * GL_RGBA16F_ARB = GL_RGBA_FLOAT16_APPLE = 0x881A
2327 * GL_RGB16F_ARB = GL_RGB_FLOAT16_APPLE = 0x881B
2328 * GL_RGBA32F_ARB = GL_RGBA_FLOAT32_APPLE = 0x8814
2329 * GL_RGB32F_ARB = GL_RGB_FLOAT32_APPLE = 0x8815
2330 * GL_HALF_FLOAT_ARB = GL_HALF_APPLE = 0x140B
2332 if (!gl_info
->supported
[ARB_TEXTURE_FLOAT
])
2334 TRACE_(d3d_caps
)(" IMPLIED: GL_ARB_texture_float support(from GL_APPLE_float_pixels.\n");
2335 gl_info
->supported
[ARB_TEXTURE_FLOAT
] = TRUE
;
2337 if (!gl_info
->supported
[ARB_HALF_FLOAT_PIXEL
])
2339 TRACE_(d3d_caps
)(" IMPLIED: GL_ARB_half_float_pixel support(from GL_APPLE_float_pixels.\n");
2340 gl_info
->supported
[ARB_HALF_FLOAT_PIXEL
] = TRUE
;
2343 if (gl_info
->supported
[ARB_MAP_BUFFER_RANGE
])
2345 /* GL_ARB_map_buffer_range and GL_APPLE_flush_buffer_range provide the same
2346 * functionality. Prefer the ARB extension */
2347 gl_info
->supported
[APPLE_FLUSH_BUFFER_RANGE
] = FALSE
;
2349 if (gl_info
->supported
[ARB_TEXTURE_CUBE_MAP
])
2351 TRACE_(d3d_caps
)(" IMPLIED: NVIDIA (NV) Texture Gen Reflection support.\n");
2352 gl_info
->supported
[NV_TEXGEN_REFLECTION
] = TRUE
;
2354 if (!gl_info
->supported
[ARB_DEPTH_CLAMP
] && gl_info
->supported
[NV_DEPTH_CLAMP
])
2356 TRACE_(d3d_caps
)(" IMPLIED: ARB_depth_clamp support (by NV_depth_clamp).\n");
2357 gl_info
->supported
[ARB_DEPTH_CLAMP
] = TRUE
;
2359 if (!gl_info
->supported
[ARB_VERTEX_ARRAY_BGRA
] && gl_info
->supported
[EXT_VERTEX_ARRAY_BGRA
])
2361 TRACE_(d3d_caps
)(" IMPLIED: ARB_vertex_array_bgra support (by EXT_vertex_array_bgra).\n");
2362 gl_info
->supported
[ARB_VERTEX_ARRAY_BGRA
] = TRUE
;
2364 if (!gl_info
->supported
[ARB_TEXTURE_COMPRESSION_RGTC
&& gl_info
->supported
[EXT_TEXTURE_COMPRESSION_RGTC
]])
2366 TRACE_(d3d_caps
)(" IMPLIED: ARB_texture_compression_rgtc support (by EXT_texture_compression_rgtc).\n");
2367 gl_info
->supported
[ARB_TEXTURE_COMPRESSION_RGTC
] = TRUE
;
2369 if (gl_info
->supported
[NV_TEXTURE_SHADER2
])
2371 if (gl_info
->supported
[NV_REGISTER_COMBINERS
])
2373 /* Also disable ATI_FRAGMENT_SHADER if register combiners and texture_shader2
2374 * are supported. The nv extensions provide the same functionality as the
2375 * ATI one, and a bit more(signed pixelformats). */
2376 gl_info
->supported
[ATI_FRAGMENT_SHADER
] = FALSE
;
2380 if (gl_info
->supported
[NV_REGISTER_COMBINERS
])
2382 glGetIntegerv(GL_MAX_GENERAL_COMBINERS_NV
, &gl_max
);
2383 gl_info
->limits
.general_combiners
= gl_max
;
2384 TRACE_(d3d_caps
)("Max general combiners: %d.\n", gl_max
);
2386 if (gl_info
->supported
[ARB_DRAW_BUFFERS
])
2388 glGetIntegerv(GL_MAX_DRAW_BUFFERS_ARB
, &gl_max
);
2389 gl_info
->limits
.buffers
= gl_max
;
2390 TRACE_(d3d_caps
)("Max draw buffers: %u.\n", gl_max
);
2392 if (gl_info
->supported
[ARB_MULTITEXTURE
])
2394 glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB
, &gl_max
);
2395 gl_info
->limits
.textures
= min(MAX_TEXTURES
, gl_max
);
2396 TRACE_(d3d_caps
)("Max textures: %d.\n", gl_info
->limits
.textures
);
2398 if (gl_info
->supported
[ARB_FRAGMENT_PROGRAM
])
2401 glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS_ARB
, &tmp
);
2402 gl_info
->limits
.fragment_samplers
= min(MAX_FRAGMENT_SAMPLERS
, tmp
);
2406 gl_info
->limits
.fragment_samplers
= max(gl_info
->limits
.fragment_samplers
, gl_max
);
2408 TRACE_(d3d_caps
)("Max fragment samplers: %d.\n", gl_info
->limits
.fragment_samplers
);
2410 if (gl_info
->supported
[ARB_VERTEX_SHADER
])
2413 glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB
, &tmp
);
2414 gl_info
->limits
.vertex_samplers
= tmp
;
2415 glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB
, &tmp
);
2416 gl_info
->limits
.combined_samplers
= tmp
;
2418 /* Loading GLSL sampler uniforms is much simpler if we can assume that the sampler setup
2419 * is known at shader link time. In a vertex shader + pixel shader combination this isn't
2420 * an issue because then the sampler setup only depends on the two shaders. If a pixel
2421 * shader is used with fixed function vertex processing we're fine too because fixed function
2422 * vertex processing doesn't use any samplers. If fixed function fragment processing is
2423 * used we have to make sure that all vertex sampler setups are valid together with all
2424 * possible fixed function fragment processing setups. This is true if vsamplers + MAX_TEXTURES
2425 * <= max_samplers. This is true on all d3d9 cards that support vtf(gf 6 and gf7 cards).
2426 * dx9 radeon cards do not support vertex texture fetch. DX10 cards have 128 samplers, and
2427 * dx9 is limited to 8 fixed function texture stages and 4 vertex samplers. DX10 does not have
2428 * a fixed function pipeline anymore.
2430 * So this is just a check to check that our assumption holds true. If not, write a warning
2431 * and reduce the number of vertex samplers or probably disable vertex texture fetch. */
2432 if (gl_info
->limits
.vertex_samplers
&& gl_info
->limits
.combined_samplers
< 12
2433 && MAX_TEXTURES
+ gl_info
->limits
.vertex_samplers
> gl_info
->limits
.combined_samplers
)
2435 FIXME("OpenGL implementation supports %u vertex samplers and %u total samplers.\n",
2436 gl_info
->limits
.vertex_samplers
, gl_info
->limits
.combined_samplers
);
2437 FIXME("Expected vertex samplers + MAX_TEXTURES(=8) > combined_samplers.\n");
2438 if (gl_info
->limits
.combined_samplers
> MAX_TEXTURES
)
2439 gl_info
->limits
.vertex_samplers
= gl_info
->limits
.combined_samplers
- MAX_TEXTURES
;
2441 gl_info
->limits
.vertex_samplers
= 0;
2446 gl_info
->limits
.combined_samplers
= gl_info
->limits
.fragment_samplers
;
2448 TRACE_(d3d_caps
)("Max vertex samplers: %u.\n", gl_info
->limits
.vertex_samplers
);
2449 TRACE_(d3d_caps
)("Max combined samplers: %u.\n", gl_info
->limits
.combined_samplers
);
2451 if (gl_info
->supported
[ARB_VERTEX_BLEND
])
2453 glGetIntegerv(GL_MAX_VERTEX_UNITS_ARB
, &gl_max
);
2454 gl_info
->limits
.blends
= gl_max
;
2455 TRACE_(d3d_caps
)("Max blends: %u.\n", gl_info
->limits
.blends
);
2457 if (gl_info
->supported
[EXT_TEXTURE3D
])
2459 glGetIntegerv(GL_MAX_3D_TEXTURE_SIZE_EXT
, &gl_max
);
2460 gl_info
->limits
.texture3d_size
= gl_max
;
2461 TRACE_(d3d_caps
)("Max texture3D size: %d.\n", gl_info
->limits
.texture3d_size
);
2463 if (gl_info
->supported
[EXT_TEXTURE_FILTER_ANISOTROPIC
])
2465 glGetIntegerv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT
, &gl_max
);
2466 gl_info
->limits
.anisotropy
= gl_max
;
2467 TRACE_(d3d_caps
)("Max anisotropy: %d.\n", gl_info
->limits
.anisotropy
);
2469 if (gl_info
->supported
[ARB_FRAGMENT_PROGRAM
])
2471 GL_EXTCALL(glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB
, GL_MAX_PROGRAM_ENV_PARAMETERS_ARB
, &gl_max
));
2472 gl_info
->limits
.arb_ps_float_constants
= gl_max
;
2473 TRACE_(d3d_caps
)("Max ARB_FRAGMENT_PROGRAM float constants: %d.\n", gl_info
->limits
.arb_ps_float_constants
);
2474 GL_EXTCALL(glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB
, GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB
, &gl_max
));
2475 gl_info
->limits
.arb_ps_native_constants
= gl_max
;
2476 TRACE_(d3d_caps
)("Max ARB_FRAGMENT_PROGRAM native float constants: %d.\n",
2477 gl_info
->limits
.arb_ps_native_constants
);
2478 GL_EXTCALL(glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB
, GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB
, &gl_max
));
2479 gl_info
->limits
.arb_ps_temps
= gl_max
;
2480 TRACE_(d3d_caps
)("Max ARB_FRAGMENT_PROGRAM native temporaries: %d.\n", gl_info
->limits
.arb_ps_temps
);
2481 GL_EXTCALL(glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB
, GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB
, &gl_max
));
2482 gl_info
->limits
.arb_ps_instructions
= gl_max
;
2483 TRACE_(d3d_caps
)("Max ARB_FRAGMENT_PROGRAM native instructions: %d.\n", gl_info
->limits
.arb_ps_instructions
);
2484 GL_EXTCALL(glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB
, GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB
, &gl_max
));
2485 gl_info
->limits
.arb_ps_local_constants
= gl_max
;
2486 TRACE_(d3d_caps
)("Max ARB_FRAGMENT_PROGRAM local parameters: %d.\n", gl_info
->limits
.arb_ps_instructions
);
2488 if (gl_info
->supported
[ARB_VERTEX_PROGRAM
])
2490 GL_EXTCALL(glGetProgramivARB(GL_VERTEX_PROGRAM_ARB
, GL_MAX_PROGRAM_ENV_PARAMETERS_ARB
, &gl_max
));
2491 gl_info
->limits
.arb_vs_float_constants
= gl_max
;
2492 TRACE_(d3d_caps
)("Max ARB_VERTEX_PROGRAM float constants: %d.\n", gl_info
->limits
.arb_vs_float_constants
);
2493 GL_EXTCALL(glGetProgramivARB(GL_VERTEX_PROGRAM_ARB
, GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB
, &gl_max
));
2494 gl_info
->limits
.arb_vs_native_constants
= gl_max
;
2495 TRACE_(d3d_caps
)("Max ARB_VERTEX_PROGRAM native float constants: %d.\n",
2496 gl_info
->limits
.arb_vs_native_constants
);
2497 GL_EXTCALL(glGetProgramivARB(GL_VERTEX_PROGRAM_ARB
, GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB
, &gl_max
));
2498 gl_info
->limits
.arb_vs_temps
= gl_max
;
2499 TRACE_(d3d_caps
)("Max ARB_VERTEX_PROGRAM native temporaries: %d.\n", gl_info
->limits
.arb_vs_temps
);
2500 GL_EXTCALL(glGetProgramivARB(GL_VERTEX_PROGRAM_ARB
, GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB
, &gl_max
));
2501 gl_info
->limits
.arb_vs_instructions
= gl_max
;
2502 TRACE_(d3d_caps
)("Max ARB_VERTEX_PROGRAM native instructions: %d.\n", gl_info
->limits
.arb_vs_instructions
);
2504 if (test_arb_vs_offset_limit(gl_info
)) gl_info
->quirks
|= WINED3D_QUIRK_ARB_VS_OFFSET_LIMIT
;
2506 if (gl_info
->supported
[ARB_VERTEX_SHADER
])
2508 glGetIntegerv(GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB
, &gl_max
);
2509 gl_info
->limits
.glsl_vs_float_constants
= gl_max
/ 4;
2510 TRACE_(d3d_caps
)("Max ARB_VERTEX_SHADER float constants: %u.\n", gl_info
->limits
.glsl_vs_float_constants
);
2512 if (gl_info
->supported
[ARB_FRAGMENT_SHADER
])
2514 glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB
, &gl_max
);
2515 gl_info
->limits
.glsl_ps_float_constants
= gl_max
/ 4;
2516 TRACE_(d3d_caps
)("Max ARB_FRAGMENT_SHADER float constants: %u.\n", gl_info
->limits
.glsl_ps_float_constants
);
2517 glGetIntegerv(GL_MAX_VARYING_FLOATS_ARB
, &gl_max
);
2518 gl_info
->limits
.glsl_varyings
= gl_max
;
2519 TRACE_(d3d_caps
)("Max GLSL varyings: %u (%u 4 component varyings).\n", gl_max
, gl_max
/ 4);
2521 if (gl_info
->supported
[ARB_SHADING_LANGUAGE_100
])
2523 const char *str
= (const char *)glGetString(GL_SHADING_LANGUAGE_VERSION_ARB
);
2524 unsigned int major
, minor
;
2526 TRACE_(d3d_caps
)("GLSL version string: %s.\n", debugstr_a(str
));
2528 /* The format of the GLSL version string is "major.minor[.release] [vendor info]". */
2529 sscanf(str
, "%u.%u", &major
, &minor
);
2530 gl_info
->glsl_version
= MAKEDWORD_VERSION(major
, minor
);
2532 if (gl_info
->supported
[NV_LIGHT_MAX_EXPONENT
])
2534 glGetFloatv(GL_MAX_SHININESS_NV
, &gl_info
->limits
.shininess
);
2538 gl_info
->limits
.shininess
= 128.0f
;
2540 if (gl_info
->supported
[ARB_TEXTURE_NON_POWER_OF_TWO
])
2542 /* If we have full NP2 texture support, disable
2543 * GL_ARB_texture_rectangle because we will never use it.
2544 * This saves a few redundant glDisable calls. */
2545 gl_info
->supported
[ARB_TEXTURE_RECTANGLE
] = FALSE
;
2547 if (gl_info
->supported
[ATI_FRAGMENT_SHADER
])
2549 /* Disable NV_register_combiners and fragment shader if this is supported.
2550 * generally the NV extensions are preferred over the ATI ones, and this
2551 * extension is disabled if register_combiners and texture_shader2 are both
2552 * supported. So we reach this place only if we have incomplete NV dxlevel 8
2553 * fragment processing support. */
2554 gl_info
->supported
[NV_REGISTER_COMBINERS
] = FALSE
;
2555 gl_info
->supported
[NV_REGISTER_COMBINERS2
] = FALSE
;
2556 gl_info
->supported
[NV_TEXTURE_SHADER
] = FALSE
;
2557 gl_info
->supported
[NV_TEXTURE_SHADER2
] = FALSE
;
2559 if (gl_info
->supported
[NV_HALF_FLOAT
])
2561 /* GL_ARB_half_float_vertex is a subset of GL_NV_half_float. */
2562 gl_info
->supported
[ARB_HALF_FLOAT_VERTEX
] = TRUE
;
2564 if (gl_info
->supported
[ARB_POINT_SPRITE
])
2566 gl_info
->limits
.point_sprite_units
= gl_info
->limits
.textures
;
2570 gl_info
->limits
.point_sprite_units
= 0;
2572 checkGLcall("extension detection");
2576 adapter
->fragment_pipe
= select_fragment_implementation(adapter
);
2577 adapter
->shader_backend
= select_shader_backend(adapter
);
2578 adapter
->blitter
= select_blit_implementation(adapter
);
2580 adapter
->fragment_pipe
->get_caps(gl_info
, &fragment_caps
);
2581 gl_info
->limits
.texture_stages
= fragment_caps
.MaxTextureBlendStages
;
2582 TRACE_(d3d_caps
)("Max texture stages: %u.\n", gl_info
->limits
.texture_stages
);
2584 /* In some cases the number of texture stages can be larger than the number
2585 * of samplers. The GF4 for example can use only 2 samplers (no fragment
2586 * shaders), but 8 texture stages (register combiners). */
2587 gl_info
->limits
.sampler_stages
= max(gl_info
->limits
.fragment_samplers
, gl_info
->limits
.texture_stages
);
2589 if (gl_info
->supported
[ARB_FRAMEBUFFER_OBJECT
])
2591 gl_info
->fbo_ops
.glIsRenderbuffer
= gl_info
->glIsRenderbuffer
;
2592 gl_info
->fbo_ops
.glBindRenderbuffer
= gl_info
->glBindRenderbuffer
;
2593 gl_info
->fbo_ops
.glDeleteRenderbuffers
= gl_info
->glDeleteRenderbuffers
;
2594 gl_info
->fbo_ops
.glGenRenderbuffers
= gl_info
->glGenRenderbuffers
;
2595 gl_info
->fbo_ops
.glRenderbufferStorage
= gl_info
->glRenderbufferStorage
;
2596 gl_info
->fbo_ops
.glRenderbufferStorageMultisample
= gl_info
->glRenderbufferStorageMultisample
;
2597 gl_info
->fbo_ops
.glGetRenderbufferParameteriv
= gl_info
->glGetRenderbufferParameteriv
;
2598 gl_info
->fbo_ops
.glIsFramebuffer
= gl_info
->glIsFramebuffer
;
2599 gl_info
->fbo_ops
.glBindFramebuffer
= gl_info
->glBindFramebuffer
;
2600 gl_info
->fbo_ops
.glDeleteFramebuffers
= gl_info
->glDeleteFramebuffers
;
2601 gl_info
->fbo_ops
.glGenFramebuffers
= gl_info
->glGenFramebuffers
;
2602 gl_info
->fbo_ops
.glCheckFramebufferStatus
= gl_info
->glCheckFramebufferStatus
;
2603 gl_info
->fbo_ops
.glFramebufferTexture1D
= gl_info
->glFramebufferTexture1D
;
2604 gl_info
->fbo_ops
.glFramebufferTexture2D
= gl_info
->glFramebufferTexture2D
;
2605 gl_info
->fbo_ops
.glFramebufferTexture3D
= gl_info
->glFramebufferTexture3D
;
2606 gl_info
->fbo_ops
.glFramebufferRenderbuffer
= gl_info
->glFramebufferRenderbuffer
;
2607 gl_info
->fbo_ops
.glGetFramebufferAttachmentParameteriv
= gl_info
->glGetFramebufferAttachmentParameteriv
;
2608 gl_info
->fbo_ops
.glBlitFramebuffer
= gl_info
->glBlitFramebuffer
;
2609 gl_info
->fbo_ops
.glGenerateMipmap
= gl_info
->glGenerateMipmap
;
2613 if (gl_info
->supported
[EXT_FRAMEBUFFER_OBJECT
])
2615 gl_info
->fbo_ops
.glIsRenderbuffer
= gl_info
->glIsRenderbufferEXT
;
2616 gl_info
->fbo_ops
.glBindRenderbuffer
= gl_info
->glBindRenderbufferEXT
;
2617 gl_info
->fbo_ops
.glDeleteRenderbuffers
= gl_info
->glDeleteRenderbuffersEXT
;
2618 gl_info
->fbo_ops
.glGenRenderbuffers
= gl_info
->glGenRenderbuffersEXT
;
2619 gl_info
->fbo_ops
.glRenderbufferStorage
= gl_info
->glRenderbufferStorageEXT
;
2620 gl_info
->fbo_ops
.glGetRenderbufferParameteriv
= gl_info
->glGetRenderbufferParameterivEXT
;
2621 gl_info
->fbo_ops
.glIsFramebuffer
= gl_info
->glIsFramebufferEXT
;
2622 gl_info
->fbo_ops
.glBindFramebuffer
= gl_info
->glBindFramebufferEXT
;
2623 gl_info
->fbo_ops
.glDeleteFramebuffers
= gl_info
->glDeleteFramebuffersEXT
;
2624 gl_info
->fbo_ops
.glGenFramebuffers
= gl_info
->glGenFramebuffersEXT
;
2625 gl_info
->fbo_ops
.glCheckFramebufferStatus
= gl_info
->glCheckFramebufferStatusEXT
;
2626 gl_info
->fbo_ops
.glFramebufferTexture1D
= gl_info
->glFramebufferTexture1DEXT
;
2627 gl_info
->fbo_ops
.glFramebufferTexture2D
= gl_info
->glFramebufferTexture2DEXT
;
2628 gl_info
->fbo_ops
.glFramebufferTexture3D
= gl_info
->glFramebufferTexture3DEXT
;
2629 gl_info
->fbo_ops
.glFramebufferRenderbuffer
= gl_info
->glFramebufferRenderbufferEXT
;
2630 gl_info
->fbo_ops
.glGetFramebufferAttachmentParameteriv
= gl_info
->glGetFramebufferAttachmentParameterivEXT
;
2631 gl_info
->fbo_ops
.glGenerateMipmap
= gl_info
->glGenerateMipmapEXT
;
2633 else if (wined3d_settings
.offscreen_rendering_mode
== ORM_FBO
)
2635 WARN_(d3d_caps
)("Framebuffer objects not supported, falling back to backbuffer offscreen rendering mode.\n");
2636 wined3d_settings
.offscreen_rendering_mode
= ORM_BACKBUFFER
;
2638 if (gl_info
->supported
[EXT_FRAMEBUFFER_BLIT
])
2640 gl_info
->fbo_ops
.glBlitFramebuffer
= gl_info
->glBlitFramebufferEXT
;
2642 if (gl_info
->supported
[EXT_FRAMEBUFFER_MULTISAMPLE
])
2644 gl_info
->fbo_ops
.glRenderbufferStorageMultisample
= gl_info
->glRenderbufferStorageMultisampleEXT
;
2648 /* MRTs are currently only supported when FBOs are used. */
2649 if (wined3d_settings
.offscreen_rendering_mode
!= ORM_FBO
)
2651 gl_info
->limits
.buffers
= 1;
2654 gl_vendor
= wined3d_guess_gl_vendor(gl_info
, gl_vendor_str
, gl_renderer_str
);
2655 card_vendor
= wined3d_guess_card_vendor(gl_vendor_str
, gl_renderer_str
);
2656 TRACE_(d3d_caps
)("found GL_VENDOR (%s)->(0x%04x/0x%04x)\n", debugstr_a(gl_vendor_str
), gl_vendor
, card_vendor
);
2658 device
= wined3d_guess_card(gl_info
, gl_renderer_str
, &gl_vendor
, &card_vendor
, &vidmem
);
2659 TRACE_(d3d_caps
)("FOUND (fake) card: 0x%x (vendor id), 0x%x (device id)\n", card_vendor
, device
);
2661 /* If we have an estimate use it, else default to 64MB; */
2663 gl_info
->vidmem
= vidmem
*1024*1024; /* convert from MBs to bytes */
2665 gl_info
->vidmem
= WINE_DEFAULT_VIDMEM
;
2667 gl_info
->wrap_lookup
[WINED3DTADDRESS_WRAP
- WINED3DTADDRESS_WRAP
] = GL_REPEAT
;
2668 gl_info
->wrap_lookup
[WINED3DTADDRESS_MIRROR
- WINED3DTADDRESS_WRAP
] =
2669 gl_info
->supported
[ARB_TEXTURE_MIRRORED_REPEAT
] ? GL_MIRRORED_REPEAT_ARB
: GL_REPEAT
;
2670 gl_info
->wrap_lookup
[WINED3DTADDRESS_CLAMP
- WINED3DTADDRESS_WRAP
] = GL_CLAMP_TO_EDGE
;
2671 gl_info
->wrap_lookup
[WINED3DTADDRESS_BORDER
- WINED3DTADDRESS_WRAP
] =
2672 gl_info
->supported
[ARB_TEXTURE_BORDER_CLAMP
] ? GL_CLAMP_TO_BORDER_ARB
: GL_REPEAT
;
2673 gl_info
->wrap_lookup
[WINED3DTADDRESS_MIRRORONCE
- WINED3DTADDRESS_WRAP
] =
2674 gl_info
->supported
[ATI_TEXTURE_MIRROR_ONCE
] ? GL_MIRROR_CLAMP_TO_EDGE_ATI
: GL_REPEAT
;
2676 /* Make sure there's an active HDC else the WGL extensions will fail */
2677 hdc
= pwglGetCurrentDC();
2679 /* Not all GL drivers might offer WGL extensions e.g. VirtualBox */
2680 if(GL_EXTCALL(wglGetExtensionsStringARB
))
2681 WGL_Extensions
= GL_EXTCALL(wglGetExtensionsStringARB(hdc
));
2683 if (NULL
== WGL_Extensions
) {
2684 ERR(" WGL_Extensions returns NULL\n");
2686 TRACE_(d3d_caps
)("WGL_Extensions reported:\n");
2687 while (*WGL_Extensions
!= 0x00) {
2691 while (isspace(*WGL_Extensions
)) WGL_Extensions
++;
2692 Start
= WGL_Extensions
;
2693 while (!isspace(*WGL_Extensions
) && *WGL_Extensions
!= 0x00) {
2697 len
= WGL_Extensions
- Start
;
2698 if (len
== 0 || len
>= sizeof(ThisExtn
))
2701 memcpy(ThisExtn
, Start
, len
);
2702 ThisExtn
[len
] = '\0';
2703 TRACE_(d3d_caps
)("- %s\n", debugstr_a(ThisExtn
));
2705 if (!strcmp(ThisExtn
, "WGL_ARB_pixel_format")) {
2706 gl_info
->supported
[WGL_ARB_PIXEL_FORMAT
] = TRUE
;
2707 TRACE_(d3d_caps
)("FOUND: WGL_ARB_pixel_format support\n");
2709 if (!strcmp(ThisExtn
, "WGL_WINE_pixel_format_passthrough")) {
2710 gl_info
->supported
[WGL_WINE_PIXEL_FORMAT_PASSTHROUGH
] = TRUE
;
2711 TRACE_(d3d_caps
)("FOUND: WGL_WINE_pixel_format_passthrough support\n");
2717 fixup_extensions(gl_info
, gl_renderer_str
, gl_vendor
, card_vendor
, device
);
2718 init_driver_info(driver_info
, card_vendor
, device
);
2719 add_gl_compat_wrappers(gl_info
);
2724 /**********************************************************
2725 * IWineD3D implementation follows
2726 **********************************************************/
2728 static UINT WINAPI
IWineD3DImpl_GetAdapterCount (IWineD3D
*iface
) {
2729 IWineD3DImpl
*This
= (IWineD3DImpl
*)iface
;
2731 TRACE_(d3d_caps
)("(%p): Reporting %u adapters\n", This
, This
->adapter_count
);
2733 return This
->adapter_count
;
2736 static HRESULT WINAPI
IWineD3DImpl_RegisterSoftwareDevice(IWineD3D
*iface
, void *init_function
)
2738 FIXME("iface %p, init_function %p stub!\n", iface
, init_function
);
2743 static HMONITOR WINAPI
IWineD3DImpl_GetAdapterMonitor(IWineD3D
*iface
, UINT Adapter
) {
2744 IWineD3DImpl
*This
= (IWineD3DImpl
*)iface
;
2746 TRACE_(d3d_caps
)("(%p)->(%d)\n", This
, Adapter
);
2748 if (Adapter
>= IWineD3DImpl_GetAdapterCount(iface
)) {
2752 return MonitorFromPoint(This
->adapters
[Adapter
].monitorPoint
, MONITOR_DEFAULTTOPRIMARY
);
2755 /* FIXME: GetAdapterModeCount and EnumAdapterModes currently only returns modes
2756 of the same bpp but different resolutions */
2758 /* Note: dx9 supplies a format. Calls from d3d8 supply WINED3DFMT_UNKNOWN */
2759 static UINT WINAPI
IWineD3DImpl_GetAdapterModeCount(IWineD3D
*iface
, UINT Adapter
, enum wined3d_format_id format_id
)
2761 IWineD3DImpl
*This
= (IWineD3DImpl
*)iface
;
2763 TRACE_(d3d_caps
)("iface %p, adapter %u, format_id: %s.\n", iface
, Adapter
, debug_d3dformat(format_id
));
2765 if (Adapter
>= IWineD3D_GetAdapterCount(iface
)) {
2769 /* TODO: Store modes per adapter and read it from the adapter structure */
2770 if (Adapter
== 0) { /* Display */
2771 const struct wined3d_format_desc
*format_desc
= getFormatDescEntry(format_id
, &This
->adapters
[Adapter
].gl_info
);
2772 UINT format_bits
= format_desc
->byte_count
* CHAR_BIT
;
2777 memset(&mode
, 0, sizeof(mode
));
2778 mode
.dmSize
= sizeof(mode
);
2780 while (EnumDisplaySettingsExW(NULL
, j
, &mode
, 0))
2784 if (format_id
== WINED3DFMT_UNKNOWN
)
2786 /* This is for D3D8, do not enumerate P8 here */
2787 if (mode
.dmBitsPerPel
== 32 || mode
.dmBitsPerPel
== 16) ++i
;
2789 else if (mode
.dmBitsPerPel
== format_bits
)
2795 TRACE_(d3d_caps
)("(%p}->(Adapter: %d) => %d (out of %d)\n", This
, Adapter
, i
, j
);
2798 FIXME_(d3d_caps
)("Adapter not primary display\n");
2803 /* Note: dx9 supplies a format. Calls from d3d8 supply WINED3DFMT_UNKNOWN */
2804 static HRESULT WINAPI
IWineD3DImpl_EnumAdapterModes(IWineD3D
*iface
, UINT Adapter
,
2805 enum wined3d_format_id format_id
, UINT Mode
, WINED3DDISPLAYMODE
*pMode
)
2807 IWineD3DImpl
*This
= (IWineD3DImpl
*)iface
;
2809 TRACE_(d3d_caps
)("iface %p, adapter_idx %u, format %s, mode_idx %u, mode %p.\n",
2810 iface
, Adapter
, debug_d3dformat(format_id
), Mode
, pMode
);
2812 /* Validate the parameters as much as possible */
2813 if (!pMode
|| Adapter
>= IWineD3DImpl_GetAdapterCount(iface
)
2814 || Mode
>= IWineD3DImpl_GetAdapterModeCount(iface
, Adapter
, format_id
))
2816 return WINED3DERR_INVALIDCALL
;
2819 /* TODO: Store modes per adapter and read it from the adapter structure */
2822 const struct wined3d_format_desc
*format_desc
= getFormatDescEntry(format_id
, &This
->adapters
[Adapter
].gl_info
);
2823 UINT format_bits
= format_desc
->byte_count
* CHAR_BIT
;
2829 ZeroMemory(&DevModeW
, sizeof(DevModeW
));
2830 DevModeW
.dmSize
= sizeof(DevModeW
);
2832 /* If we are filtering to a specific format (D3D9), then need to skip
2833 all unrelated modes, but if mode is irrelevant (D3D8), then we can
2834 just count through the ones with valid bit depths */
2835 while ((i
<=Mode
) && EnumDisplaySettingsExW(NULL
, j
++, &DevModeW
, 0))
2837 if (format_id
== WINED3DFMT_UNKNOWN
)
2839 /* This is for D3D8, do not enumerate P8 here */
2840 if (DevModeW
.dmBitsPerPel
== 32 || DevModeW
.dmBitsPerPel
== 16) ++i
;
2842 else if (DevModeW
.dmBitsPerPel
== format_bits
)
2850 TRACE_(d3d_caps
)("No modes found for format (%x - %s)\n", format_id
, debug_d3dformat(format_id
));
2851 return WINED3DERR_INVALIDCALL
;
2855 /* Now get the display mode via the calculated index */
2856 if (EnumDisplaySettingsExW(NULL
, ModeIdx
, &DevModeW
, 0)) {
2857 pMode
->Width
= DevModeW
.dmPelsWidth
;
2858 pMode
->Height
= DevModeW
.dmPelsHeight
;
2859 pMode
->RefreshRate
= DEFAULT_REFRESH_RATE
;
2860 if (DevModeW
.dmFields
& DM_DISPLAYFREQUENCY
)
2861 pMode
->RefreshRate
= DevModeW
.dmDisplayFrequency
;
2863 if (format_id
== WINED3DFMT_UNKNOWN
)
2864 pMode
->Format
= pixelformat_for_depth(DevModeW
.dmBitsPerPel
);
2866 pMode
->Format
= format_id
;
2870 TRACE_(d3d_caps
)("Requested mode out of range %d\n", Mode
);
2871 return WINED3DERR_INVALIDCALL
;
2874 TRACE_(d3d_caps
)("W %d H %d rr %d fmt (%x - %s) bpp %u\n", pMode
->Width
, pMode
->Height
,
2875 pMode
->RefreshRate
, pMode
->Format
, debug_d3dformat(pMode
->Format
),
2876 DevModeW
.dmBitsPerPel
);
2881 FIXME_(d3d_caps
)("Adapter not primary display\n");
2887 static HRESULT WINAPI
IWineD3DImpl_GetAdapterDisplayMode(IWineD3D
*iface
, UINT Adapter
, WINED3DDISPLAYMODE
*pMode
)
2889 TRACE("iface %p, adapter_idx %u, display_mode %p.\n", iface
, Adapter
, pMode
);
2891 if (NULL
== pMode
||
2892 Adapter
>= IWineD3D_GetAdapterCount(iface
)) {
2893 return WINED3DERR_INVALIDCALL
;
2896 if (Adapter
== 0) { /* Display */
2900 ZeroMemory(&DevModeW
, sizeof(DevModeW
));
2901 DevModeW
.dmSize
= sizeof(DevModeW
);
2903 EnumDisplaySettingsExW(NULL
, ENUM_CURRENT_SETTINGS
, &DevModeW
, 0);
2904 pMode
->Width
= DevModeW
.dmPelsWidth
;
2905 pMode
->Height
= DevModeW
.dmPelsHeight
;
2906 bpp
= DevModeW
.dmBitsPerPel
;
2907 pMode
->RefreshRate
= DEFAULT_REFRESH_RATE
;
2908 if (DevModeW
.dmFields
&DM_DISPLAYFREQUENCY
)
2910 pMode
->RefreshRate
= DevModeW
.dmDisplayFrequency
;
2913 pMode
->Format
= pixelformat_for_depth(bpp
);
2915 FIXME_(d3d_caps
)("Adapter not primary display\n");
2918 TRACE_(d3d_caps
)("returning w:%d, h:%d, ref:%d, fmt:%s\n", pMode
->Width
,
2919 pMode
->Height
, pMode
->RefreshRate
, debug_d3dformat(pMode
->Format
));
2923 /* NOTE: due to structure differences between dx8 and dx9 D3DADAPTER_IDENTIFIER,
2924 and fields being inserted in the middle, a new structure is used in place */
2925 static HRESULT WINAPI
IWineD3DImpl_GetAdapterIdentifier(IWineD3D
*iface
, UINT Adapter
, DWORD Flags
,
2926 WINED3DADAPTER_IDENTIFIER
* pIdentifier
) {
2927 IWineD3DImpl
*This
= (IWineD3DImpl
*)iface
;
2928 struct wined3d_adapter
*adapter
;
2931 TRACE_(d3d_caps
)("(%p}->(Adapter: %d, Flags: %x, pId=%p)\n", This
, Adapter
, Flags
, pIdentifier
);
2933 if (Adapter
>= IWineD3D_GetAdapterCount(iface
)) {
2934 return WINED3DERR_INVALIDCALL
;
2937 adapter
= &This
->adapters
[Adapter
];
2939 /* Return the information requested */
2940 TRACE_(d3d_caps
)("device/Vendor Name and Version detection using FillGLCaps\n");
2942 if (pIdentifier
->driver_size
)
2944 const char *name
= adapter
->driver_info
.name
;
2945 len
= min(strlen(name
), pIdentifier
->driver_size
- 1);
2946 memcpy(pIdentifier
->driver
, name
, len
);
2947 pIdentifier
->driver
[len
] = '\0';
2950 if (pIdentifier
->description_size
)
2952 const char *description
= adapter
->driver_info
.description
;
2953 len
= min(strlen(description
), pIdentifier
->description_size
- 1);
2954 memcpy(pIdentifier
->description
, description
, len
);
2955 pIdentifier
->description
[len
] = '\0';
2958 /* Note that d3d8 doesn't supply a device name. */
2959 if (pIdentifier
->device_name_size
)
2961 static const char *device_name
= "\\\\.\\DISPLAY1"; /* FIXME: May depend on desktop? */
2963 len
= strlen(device_name
);
2964 if (len
>= pIdentifier
->device_name_size
)
2966 ERR("Device name size too small.\n");
2967 return WINED3DERR_INVALIDCALL
;
2970 memcpy(pIdentifier
->device_name
, device_name
, len
);
2971 pIdentifier
->device_name
[len
] = '\0';
2974 pIdentifier
->driver_version
.u
.HighPart
= adapter
->driver_info
.version_high
;
2975 pIdentifier
->driver_version
.u
.LowPart
= adapter
->driver_info
.version_low
;
2976 pIdentifier
->vendor_id
= adapter
->driver_info
.vendor
;
2977 pIdentifier
->device_id
= adapter
->driver_info
.device
;
2978 pIdentifier
->subsystem_id
= 0;
2979 pIdentifier
->revision
= 0;
2980 memcpy(&pIdentifier
->device_identifier
, &IID_D3DDEVICE_D3DUID
, sizeof(pIdentifier
->device_identifier
));
2981 pIdentifier
->whql_level
= (Flags
& WINED3DENUM_NO_WHQL_LEVEL
) ? 0 : 1;
2982 memcpy(&pIdentifier
->adapter_luid
, &adapter
->luid
, sizeof(pIdentifier
->adapter_luid
));
2983 pIdentifier
->video_memory
= adapter
->TextureRam
;
2988 static BOOL
IWineD3DImpl_IsPixelFormatCompatibleWithRenderFmt(const struct wined3d_gl_info
*gl_info
,
2989 const WineD3D_PixelFormat
*cfg
, const struct wined3d_format_desc
*format_desc
)
2991 short redSize
, greenSize
, blueSize
, alphaSize
, colorBits
;
2996 /* Float formats need FBOs. If FBOs are used this function isn't called */
2997 if (format_desc
->Flags
& WINED3DFMT_FLAG_FLOAT
) return FALSE
;
2999 if(cfg
->iPixelType
== WGL_TYPE_RGBA_ARB
) { /* Integer RGBA formats */
3000 if (!getColorBits(format_desc
, &redSize
, &greenSize
, &blueSize
, &alphaSize
, &colorBits
))
3002 ERR("Unable to check compatibility for format %s.\n", debug_d3dformat(format_desc
->id
));
3006 if(cfg
->redSize
< redSize
)
3009 if(cfg
->greenSize
< greenSize
)
3012 if(cfg
->blueSize
< blueSize
)
3015 if(cfg
->alphaSize
< alphaSize
)
3021 /* Probably a RGBA_float or color index mode */
3025 static BOOL
IWineD3DImpl_IsPixelFormatCompatibleWithDepthFmt(const struct wined3d_gl_info
*gl_info
,
3026 const WineD3D_PixelFormat
*cfg
, const struct wined3d_format_desc
*format_desc
)
3028 short depthSize
, stencilSize
;
3029 BOOL lockable
= FALSE
;
3034 if (!getDepthStencilBits(format_desc
, &depthSize
, &stencilSize
))
3036 ERR("Unable to check compatibility for format %s.\n", debug_d3dformat(format_desc
->id
));
3040 /* Float formats need FBOs. If FBOs are used this function isn't called */
3041 if (format_desc
->Flags
& WINED3DFMT_FLAG_FLOAT
) return FALSE
;
3043 if ((format_desc
->id
== WINED3DFMT_D16_LOCKABLE
) || (format_desc
->id
== WINED3DFMT_D32_FLOAT
))
3046 /* On some modern cards like the Geforce8/9 GLX doesn't offer some dephthstencil formats which D3D9 reports.
3047 * We can safely report 'compatible' formats (e.g. D24 can be used for D16) as long as we aren't dealing with
3048 * a lockable format. This also helps D3D <= 7 as they expect D16 which isn't offered without this on Geforce8 cards. */
3049 if(!(cfg
->depthSize
== depthSize
|| (!lockable
&& cfg
->depthSize
> depthSize
)))
3052 /* Some cards like Intel i915 ones only offer D24S8 but lots of games also need a format without stencil, so
3053 * allow more stencil bits than requested. */
3054 if(cfg
->stencilSize
< stencilSize
)
3060 static HRESULT WINAPI
IWineD3DImpl_CheckDepthStencilMatch(IWineD3D
*iface
,
3061 UINT Adapter
, WINED3DDEVTYPE DeviceType
, enum wined3d_format_id AdapterFormat
,
3062 enum wined3d_format_id RenderTargetFormat
, enum wined3d_format_id DepthStencilFormat
)
3064 IWineD3DImpl
*This
= (IWineD3DImpl
*)iface
;
3066 const WineD3D_PixelFormat
*cfgs
;
3067 const struct wined3d_adapter
*adapter
;
3068 const struct wined3d_format_desc
*rt_format_desc
;
3069 const struct wined3d_format_desc
*ds_format_desc
;
3072 WARN_(d3d_caps
)("(%p)-> (STUB) (Adptr:%d, DevType:(%x,%s), AdptFmt:(%x,%s), RendrTgtFmt:(%x,%s), DepthStencilFmt:(%x,%s))\n",
3074 DeviceType
, debug_d3ddevicetype(DeviceType
),
3075 AdapterFormat
, debug_d3dformat(AdapterFormat
),
3076 RenderTargetFormat
, debug_d3dformat(RenderTargetFormat
),
3077 DepthStencilFormat
, debug_d3dformat(DepthStencilFormat
));
3079 if (Adapter
>= IWineD3D_GetAdapterCount(iface
)) {
3080 TRACE("(%p) Failed: Atapter (%u) higher than supported adapters (%u) returning WINED3DERR_INVALIDCALL\n", This
, Adapter
, IWineD3D_GetAdapterCount(iface
));
3081 return WINED3DERR_INVALIDCALL
;
3084 adapter
= &This
->adapters
[Adapter
];
3085 rt_format_desc
= getFormatDescEntry(RenderTargetFormat
, &adapter
->gl_info
);
3086 ds_format_desc
= getFormatDescEntry(DepthStencilFormat
, &adapter
->gl_info
);
3087 if (wined3d_settings
.offscreen_rendering_mode
== ORM_FBO
)
3089 if ((rt_format_desc
->Flags
& WINED3DFMT_FLAG_RENDERTARGET
) &&
3090 (ds_format_desc
->Flags
& (WINED3DFMT_FLAG_DEPTH
| WINED3DFMT_FLAG_STENCIL
))) {
3091 TRACE_(d3d_caps
)("(%p) : Formats matched\n", This
);
3097 cfgs
= adapter
->cfgs
;
3098 nCfgs
= adapter
->nCfgs
;
3099 for (it
= 0; it
< nCfgs
; ++it
) {
3100 if (IWineD3DImpl_IsPixelFormatCompatibleWithRenderFmt(&adapter
->gl_info
, &cfgs
[it
], rt_format_desc
))
3102 if (IWineD3DImpl_IsPixelFormatCompatibleWithDepthFmt(&adapter
->gl_info
, &cfgs
[it
], ds_format_desc
))
3104 TRACE_(d3d_caps
)("(%p) : Formats matched\n", This
);
3110 WARN_(d3d_caps
)("unsupported format pair: %s and %s\n", debug_d3dformat(RenderTargetFormat
), debug_d3dformat(DepthStencilFormat
));
3112 return WINED3DERR_NOTAVAILABLE
;
3115 static HRESULT WINAPI
IWineD3DImpl_CheckDeviceMultiSampleType(IWineD3D
*iface
, UINT Adapter
,
3116 WINED3DDEVTYPE DeviceType
, enum wined3d_format_id SurfaceFormat
, BOOL Windowed
,
3117 WINED3DMULTISAMPLE_TYPE MultiSampleType
, DWORD
*pQualityLevels
)
3119 IWineD3DImpl
*This
= (IWineD3DImpl
*)iface
;
3120 const struct wined3d_format_desc
*glDesc
;
3121 const struct wined3d_adapter
*adapter
;
3123 TRACE_(d3d_caps
)("(%p)-> (Adptr:%d, DevType:(%x,%s), SurfFmt:(%x,%s), Win?%d, MultiSamp:%x, pQual:%p)\n",
3126 DeviceType
, debug_d3ddevicetype(DeviceType
),
3127 SurfaceFormat
, debug_d3dformat(SurfaceFormat
),
3132 if (Adapter
>= IWineD3D_GetAdapterCount(iface
)) {
3133 return WINED3DERR_INVALIDCALL
;
3136 /* TODO: handle Windowed, add more quality levels */
3138 if (WINED3DMULTISAMPLE_NONE
== MultiSampleType
) {
3139 if(pQualityLevels
) *pQualityLevels
= 1;
3143 /* By default multisampling is disabled right now as it causes issues
3144 * on some Nvidia driver versions and it doesn't work well in combination
3146 if(!wined3d_settings
.allow_multisampling
)
3147 return WINED3DERR_NOTAVAILABLE
;
3149 adapter
= &This
->adapters
[Adapter
];
3150 glDesc
= getFormatDescEntry(SurfaceFormat
, &adapter
->gl_info
);
3151 if (!glDesc
) return WINED3DERR_INVALIDCALL
;
3153 if(glDesc
->Flags
& (WINED3DFMT_FLAG_DEPTH
| WINED3DFMT_FLAG_STENCIL
)) {
3155 const WineD3D_PixelFormat
*cfgs
;
3157 cfgs
= adapter
->cfgs
;
3158 nCfgs
= adapter
->nCfgs
;
3159 for(i
=0; i
<nCfgs
; i
++) {
3160 if(cfgs
[i
].numSamples
!= MultiSampleType
)
3163 if (!IWineD3DImpl_IsPixelFormatCompatibleWithDepthFmt(&adapter
->gl_info
, &cfgs
[i
], glDesc
))
3166 TRACE("Found iPixelFormat=%d to support MultiSampleType=%d for format %s\n", cfgs
[i
].iPixelFormat
, MultiSampleType
, debug_d3dformat(SurfaceFormat
));
3169 *pQualityLevels
= 1; /* Guess at a value! */
3173 else if(glDesc
->Flags
& WINED3DFMT_FLAG_RENDERTARGET
) {
3174 short redSize
, greenSize
, blueSize
, alphaSize
, colorBits
;
3176 const WineD3D_PixelFormat
*cfgs
;
3178 if (!getColorBits(glDesc
, &redSize
, &greenSize
, &blueSize
, &alphaSize
, &colorBits
))
3180 ERR("Unable to color bits for format %#x, can't check multisampling capability!\n", SurfaceFormat
);
3181 return WINED3DERR_NOTAVAILABLE
;
3184 cfgs
= adapter
->cfgs
;
3185 nCfgs
= adapter
->nCfgs
;
3186 for(i
=0; i
<nCfgs
; i
++) {
3187 if(cfgs
[i
].numSamples
!= MultiSampleType
)
3189 if(cfgs
[i
].redSize
!= redSize
)
3191 if(cfgs
[i
].greenSize
!= greenSize
)
3193 if(cfgs
[i
].blueSize
!= blueSize
)
3195 /* Not all drivers report alpha-less formats since they use 32-bit anyway, so accept alpha even if we didn't ask for it. */
3196 if(alphaSize
&& cfgs
[i
].alphaSize
!= alphaSize
)
3198 if(cfgs
[i
].colorSize
!= (glDesc
->byte_count
<< 3))
3201 TRACE("Found iPixelFormat=%d to support MultiSampleType=%d for format %s\n", cfgs
[i
].iPixelFormat
, MultiSampleType
, debug_d3dformat(SurfaceFormat
));
3204 *pQualityLevels
= 1; /* Guess at a value! */
3208 return WINED3DERR_NOTAVAILABLE
;
3211 static HRESULT WINAPI
IWineD3DImpl_CheckDeviceType(IWineD3D
*iface
, UINT Adapter
, WINED3DDEVTYPE DeviceType
,
3212 enum wined3d_format_id DisplayFormat
, enum wined3d_format_id BackBufferFormat
, BOOL Windowed
)
3214 HRESULT hr
= WINED3DERR_NOTAVAILABLE
;
3217 TRACE("iface %p, adapter_idx %u, device_type %s, display_format %s, backbuffer_format %s, windowed %#x.\n",
3218 iface
, Adapter
, debug_d3ddevicetype(DeviceType
), debug_d3dformat(DisplayFormat
),
3219 debug_d3dformat(BackBufferFormat
), Windowed
);
3221 if (Adapter
>= IWineD3D_GetAdapterCount(iface
)) {
3222 WARN_(d3d_caps
)("Adapter >= IWineD3D_GetAdapterCount(iface), returning WINED3DERR_INVALIDCALL\n");
3223 return WINED3DERR_INVALIDCALL
;
3226 /* The task of this function is to check whether a certain display / backbuffer format
3227 * combination is available on the given adapter. In fullscreen mode microsoft specified
3228 * that the display format shouldn't provide alpha and that ignoring alpha the backbuffer
3229 * and display format should match exactly.
3230 * In windowed mode format conversion can occur and this depends on the driver. When format
3231 * conversion is done, this function should nevertheless fail and applications need to use
3232 * CheckDeviceFormatConversion.
3233 * At the moment we assume that fullscreen and windowed have the same capabilities */
3235 /* There are only 4 display formats */
3236 if (!(DisplayFormat
== WINED3DFMT_B5G6R5_UNORM
3237 || DisplayFormat
== WINED3DFMT_B5G5R5X1_UNORM
3238 || DisplayFormat
== WINED3DFMT_B8G8R8X8_UNORM
3239 || DisplayFormat
== WINED3DFMT_B10G10R10A2_UNORM
))
3241 TRACE_(d3d_caps
)("Format %s unsupported as display format\n", debug_d3dformat(DisplayFormat
));
3242 return WINED3DERR_NOTAVAILABLE
;
3245 /* If the requested DisplayFormat is not available, don't continue */
3246 nmodes
= IWineD3DImpl_GetAdapterModeCount(iface
, Adapter
, DisplayFormat
);
3248 TRACE_(d3d_caps
)("No available modes for display format %s\n", debug_d3dformat(DisplayFormat
));
3249 return WINED3DERR_NOTAVAILABLE
;
3252 /* Windowed mode allows you to specify WINED3DFMT_UNKNOWN for the backbufferformat, it means 'reuse' the display format for the backbuffer */
3253 if(!Windowed
&& BackBufferFormat
== WINED3DFMT_UNKNOWN
) {
3254 TRACE_(d3d_caps
)("BackBufferFormat WINED3FMT_UNKNOWN not available in Windowed mode\n");
3255 return WINED3DERR_NOTAVAILABLE
;
3258 /* In FULLSCREEN mode R5G6B5 can only be mixed with backbuffer format R5G6B5 */
3259 if (DisplayFormat
== WINED3DFMT_B5G6R5_UNORM
&& BackBufferFormat
!= WINED3DFMT_B5G6R5_UNORM
)
3261 TRACE_(d3d_caps
)("Unsupported display/backbuffer format combination %s/%s\n", debug_d3dformat(DisplayFormat
), debug_d3dformat(BackBufferFormat
));
3262 return WINED3DERR_NOTAVAILABLE
;
3265 /* In FULLSCREEN mode X1R5G5B5 can only be mixed with backbuffer format *1R5G5B5 */
3266 if (DisplayFormat
== WINED3DFMT_B5G5R5X1_UNORM
3267 && !(BackBufferFormat
== WINED3DFMT_B5G5R5X1_UNORM
|| BackBufferFormat
== WINED3DFMT_B5G5R5A1_UNORM
))
3269 TRACE_(d3d_caps
)("Unsupported display/backbuffer format combination %s/%s\n", debug_d3dformat(DisplayFormat
), debug_d3dformat(BackBufferFormat
));
3270 return WINED3DERR_NOTAVAILABLE
;
3273 /* In FULLSCREEN mode X8R8G8B8 can only be mixed with backbuffer format *8R8G8B8 */
3274 if (DisplayFormat
== WINED3DFMT_B8G8R8X8_UNORM
3275 && !(BackBufferFormat
== WINED3DFMT_B8G8R8X8_UNORM
|| BackBufferFormat
== WINED3DFMT_B8G8R8A8_UNORM
))
3277 TRACE_(d3d_caps
)("Unsupported display/backbuffer format combination %s/%s\n", debug_d3dformat(DisplayFormat
), debug_d3dformat(BackBufferFormat
));
3278 return WINED3DERR_NOTAVAILABLE
;
3281 /* A2R10G10B10 is only allowed in fullscreen mode and it can only be mixed with backbuffer format A2R10G10B10 */
3282 if (DisplayFormat
== WINED3DFMT_B10G10R10A2_UNORM
3283 && (BackBufferFormat
!= WINED3DFMT_B10G10R10A2_UNORM
|| Windowed
))
3285 TRACE_(d3d_caps
)("Unsupported display/backbuffer format combination %s/%s\n", debug_d3dformat(DisplayFormat
), debug_d3dformat(BackBufferFormat
));
3286 return WINED3DERR_NOTAVAILABLE
;
3289 /* Use CheckDeviceFormat to see if the BackBufferFormat is usable with the given DisplayFormat */
3290 hr
= IWineD3DImpl_CheckDeviceFormat(iface
, Adapter
, DeviceType
, DisplayFormat
, WINED3DUSAGE_RENDERTARGET
, WINED3DRTYPE_SURFACE
, BackBufferFormat
, SURFACE_OPENGL
);
3292 TRACE_(d3d_caps
)("Unsupported display/backbuffer format combination %s/%s\n", debug_d3dformat(DisplayFormat
), debug_d3dformat(BackBufferFormat
));
3298 /* Check if we support bumpmapping for a format */
3299 static BOOL
CheckBumpMapCapability(struct wined3d_adapter
*adapter
, const struct wined3d_format_desc
*format_desc
)
3301 /* Ask the fixed function pipeline implementation if it can deal
3302 * with the conversion. If we've got a GL extension giving native
3303 * support this will be an identity conversion. */
3304 return (format_desc
->Flags
& WINED3DFMT_FLAG_BUMPMAP
)
3305 && adapter
->fragment_pipe
->color_fixup_supported(format_desc
->color_fixup
);
3308 /* Check if the given DisplayFormat + DepthStencilFormat combination is valid for the Adapter */
3309 static BOOL
CheckDepthStencilCapability(struct wined3d_adapter
*adapter
,
3310 const struct wined3d_format_desc
*display_format_desc
, const struct wined3d_format_desc
*ds_format_desc
)
3314 /* Only allow depth/stencil formats */
3315 if (!(ds_format_desc
->depth_size
|| ds_format_desc
->stencil_size
)) return FALSE
;
3317 if (wined3d_settings
.offscreen_rendering_mode
== ORM_FBO
)
3319 /* With FBOs WGL limitations do not apply, but the format needs to be FBO attachable */
3320 if (ds_format_desc
->Flags
& (WINED3DFMT_FLAG_DEPTH
| WINED3DFMT_FLAG_STENCIL
)) return TRUE
;
3324 /* Walk through all WGL pixel formats to find a match */
3325 for (it
= 0; it
< adapter
->nCfgs
; ++it
)
3327 WineD3D_PixelFormat
*cfg
= &adapter
->cfgs
[it
];
3328 if (IWineD3DImpl_IsPixelFormatCompatibleWithRenderFmt(&adapter
->gl_info
, cfg
, display_format_desc
))
3330 if (IWineD3DImpl_IsPixelFormatCompatibleWithDepthFmt(&adapter
->gl_info
, cfg
, ds_format_desc
))
3341 static BOOL
CheckFilterCapability(struct wined3d_adapter
*adapter
, const struct wined3d_format_desc
*format_desc
)
3343 /* The flags entry of a format contains the filtering capability */
3344 if (format_desc
->Flags
& WINED3DFMT_FLAG_FILTERING
) return TRUE
;
3349 /* Check the render target capabilities of a format */
3350 static BOOL
CheckRenderTargetCapability(struct wined3d_adapter
*adapter
,
3351 const struct wined3d_format_desc
*adapter_format_desc
, const struct wined3d_format_desc
*check_format_desc
)
3353 /* Filter out non-RT formats */
3354 if (!(check_format_desc
->Flags
& WINED3DFMT_FLAG_RENDERTARGET
)) return FALSE
;
3355 if(wined3d_settings
.offscreen_rendering_mode
== ORM_BACKBUFFER
) {
3356 WineD3D_PixelFormat
*cfgs
= adapter
->cfgs
;
3358 short AdapterRed
, AdapterGreen
, AdapterBlue
, AdapterAlpha
, AdapterTotalSize
;
3359 short CheckRed
, CheckGreen
, CheckBlue
, CheckAlpha
, CheckTotalSize
;
3361 getColorBits(adapter_format_desc
, &AdapterRed
, &AdapterGreen
, &AdapterBlue
, &AdapterAlpha
, &AdapterTotalSize
);
3362 getColorBits(check_format_desc
, &CheckRed
, &CheckGreen
, &CheckBlue
, &CheckAlpha
, &CheckTotalSize
);
3364 /* In backbuffer mode the front and backbuffer share the same WGL pixelformat.
3365 * The format must match in RGB, alpha is allowed to be different. (Only the backbuffer can have alpha) */
3366 if(!((AdapterRed
== CheckRed
) && (AdapterGreen
== CheckGreen
) && (AdapterBlue
== CheckBlue
))) {
3367 TRACE_(d3d_caps
)("[FAILED]\n");
3371 /* Check if there is a WGL pixel format matching the requirements, the format should also be window
3372 * drawable (not offscreen; e.g. Nvidia offers R5G6B5 for pbuffers even when X is running at 24bit) */
3373 for (it
= 0; it
< adapter
->nCfgs
; ++it
)
3375 if (cfgs
[it
].windowDrawable
&& IWineD3DImpl_IsPixelFormatCompatibleWithRenderFmt(&adapter
->gl_info
,
3376 &cfgs
[it
], check_format_desc
))
3378 TRACE_(d3d_caps
)("Pixel format %d is compatible with format %s.\n",
3379 cfgs
[it
].iPixelFormat
, debug_d3dformat(check_format_desc
->id
));
3384 else if(wined3d_settings
.offscreen_rendering_mode
== ORM_FBO
)
3386 /* For now return TRUE for FBOs until we have some proper checks.
3387 * Note that this function will only be called when the format is around for texturing. */
3393 static BOOL
CheckSrgbReadCapability(struct wined3d_adapter
*adapter
, const struct wined3d_format_desc
*format_desc
)
3395 return adapter
->gl_info
.supported
[EXT_TEXTURE_SRGB
]
3396 && (format_desc
->Flags
& WINED3DFMT_FLAG_SRGB_READ
);
3399 static BOOL
CheckSrgbWriteCapability(struct wined3d_adapter
*adapter
, const struct wined3d_format_desc
*format_desc
)
3401 /* Only offer SRGB writing on X8R8G8B8/A8R8G8B8 when we use ARB or GLSL shaders as we are
3402 * doing the color fixup in shaders.
3403 * Note Windows drivers (at least on the Geforce 8800) also offer this on R5G6B5. */
3404 if (format_desc
->Flags
& WINED3DFMT_FLAG_SRGB_WRITE
)
3406 int vs_selected_mode
;
3407 int ps_selected_mode
;
3408 select_shader_mode(&adapter
->gl_info
, &ps_selected_mode
, &vs_selected_mode
);
3410 if((ps_selected_mode
== SHADER_ARB
) || (ps_selected_mode
== SHADER_GLSL
)) {
3411 TRACE_(d3d_caps
)("[OK]\n");
3416 TRACE_(d3d_caps
)("[FAILED] - sRGB writes not supported by format %s.\n", debug_d3dformat(format_desc
->id
));
3420 /* Check if a format support blending in combination with pixel shaders */
3421 static BOOL
CheckPostPixelShaderBlendingCapability(struct wined3d_adapter
*adapter
,
3422 const struct wined3d_format_desc
*format_desc
)
3424 /* The flags entry of a format contains the post pixel shader blending capability */
3425 if (format_desc
->Flags
& WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING
) return TRUE
;
3430 static BOOL
CheckWrapAndMipCapability(struct wined3d_adapter
*adapter
, const struct wined3d_format_desc
*format_desc
)
3432 /* OpenGL supports mipmapping on all formats basically. Wrapping is unsupported,
3433 * but we have to report mipmapping so we cannot reject this flag. Tests show that
3434 * windows reports WRAPANDMIP on unfilterable surfaces as well, apparently to show
3435 * that wrapping is supported. The lack of filtering will sort out the mipmapping
3436 * capability anyway.
3438 * For now lets report this on all formats, but in the future we may want to
3439 * restrict it to some should games need that
3444 /* Check if a texture format is supported on the given adapter */
3445 static BOOL
CheckTextureCapability(struct wined3d_adapter
*adapter
, const struct wined3d_format_desc
*format_desc
)
3447 const struct wined3d_gl_info
*gl_info
= &adapter
->gl_info
;
3449 switch (format_desc
->id
)
3452 * supported: RGB(A) formats
3454 case WINED3DFMT_B8G8R8_UNORM
: /* Enable for dx7, blacklisted for 8 and 9 above */
3455 case WINED3DFMT_B8G8R8A8_UNORM
:
3456 case WINED3DFMT_B8G8R8X8_UNORM
:
3457 case WINED3DFMT_B5G6R5_UNORM
:
3458 case WINED3DFMT_B5G5R5X1_UNORM
:
3459 case WINED3DFMT_B5G5R5A1_UNORM
:
3460 case WINED3DFMT_B4G4R4A4_UNORM
:
3461 case WINED3DFMT_A8_UNORM
:
3462 case WINED3DFMT_B4G4R4X4_UNORM
:
3463 case WINED3DFMT_R8G8B8A8_UNORM
:
3464 case WINED3DFMT_R8G8B8X8_UNORM
:
3465 case WINED3DFMT_B10G10R10A2_UNORM
:
3466 case WINED3DFMT_R10G10B10A2_UNORM
:
3467 case WINED3DFMT_R16G16_UNORM
:
3468 TRACE_(d3d_caps
)("[OK]\n");
3471 case WINED3DFMT_B2G3R3_UNORM
:
3472 TRACE_(d3d_caps
)("[FAILED] - Not supported on Windows\n");
3476 * Not supported: Palettized
3477 * Only some Geforce/Voodoo3/G400 cards offer 8-bit textures in case of <=Direct3D7.
3478 * Since it is not widely available, don't offer it. Further no Windows driver offers
3479 * WINED3DFMT_P8_UINT_A8_NORM, so don't offer it either.
3481 case WINED3DFMT_P8_UINT
:
3482 case WINED3DFMT_P8_UINT_A8_UNORM
:
3486 * Supported: (Alpha)-Luminance
3488 case WINED3DFMT_L8_UNORM
:
3489 case WINED3DFMT_L8A8_UNORM
:
3490 case WINED3DFMT_L16_UNORM
:
3491 TRACE_(d3d_caps
)("[OK]\n");
3494 /* Not supported on Windows, thus disabled */
3495 case WINED3DFMT_L4A4_UNORM
:
3496 TRACE_(d3d_caps
)("[FAILED] - not supported on windows\n");
3500 * Supported: Depth/Stencil formats
3502 case WINED3DFMT_D16_LOCKABLE
:
3503 case WINED3DFMT_D16_UNORM
:
3504 case WINED3DFMT_S1_UINT_D15_UNORM
:
3505 case WINED3DFMT_X8D24_UNORM
:
3506 case WINED3DFMT_S4X4_UINT_D24_UNORM
:
3507 case WINED3DFMT_D24_UNORM_S8_UINT
:
3508 case WINED3DFMT_S8_UINT_D24_FLOAT
:
3509 case WINED3DFMT_D32_UNORM
:
3510 case WINED3DFMT_D32_FLOAT
:
3514 * Not supported everywhere(depends on GL_ATI_envmap_bumpmap or
3515 * GL_NV_texture_shader). Emulated by shaders
3517 case WINED3DFMT_R8G8_SNORM
:
3518 case WINED3DFMT_R8G8_SNORM_L8X8_UNORM
:
3519 case WINED3DFMT_R5G5_SNORM_L6_UNORM
:
3520 case WINED3DFMT_R8G8B8A8_SNORM
:
3521 case WINED3DFMT_R16G16_SNORM
:
3522 /* Ask the shader backend if it can deal with the conversion. If
3523 * we've got a GL extension giving native support this will be an
3524 * identity conversion. */
3525 if (adapter
->shader_backend
->shader_color_fixup_supported(format_desc
->color_fixup
))
3527 TRACE_(d3d_caps
)("[OK]\n");
3530 TRACE_(d3d_caps
)("[FAILED]\n");
3533 case WINED3DFMT_DXT1
:
3534 case WINED3DFMT_DXT2
:
3535 case WINED3DFMT_DXT3
:
3536 case WINED3DFMT_DXT4
:
3537 case WINED3DFMT_DXT5
:
3538 if (gl_info
->supported
[EXT_TEXTURE_COMPRESSION_S3TC
])
3540 TRACE_(d3d_caps
)("[OK]\n");
3543 TRACE_(d3d_caps
)("[FAILED]\n");
3548 * Odd formats - not supported
3550 case WINED3DFMT_VERTEXDATA
:
3551 case WINED3DFMT_R16_UINT
:
3552 case WINED3DFMT_R32_UINT
:
3553 case WINED3DFMT_R16G16B16A16_SNORM
:
3554 case WINED3DFMT_R10G10B10_SNORM_A2_UNORM
:
3555 case WINED3DFMT_R10G11B11_SNORM
:
3556 TRACE_(d3d_caps
)("[FAILED]\n"); /* Enable when implemented */
3560 * WINED3DFMT_R8G8_SNORM_Cx: Not supported right now
3562 case WINED3DFMT_R8G8_SNORM_Cx
:
3563 TRACE_(d3d_caps
)("[FAILED]\n"); /* Enable when implemented */
3567 case WINED3DFMT_UYVY
:
3568 case WINED3DFMT_YUY2
:
3569 if (gl_info
->supported
[APPLE_YCBCR_422
])
3571 TRACE_(d3d_caps
)("[OK]\n");
3574 TRACE_(d3d_caps
)("[FAILED]\n");
3576 case WINED3DFMT_YV12
:
3577 TRACE_(d3d_caps
)("[FAILED]\n");
3581 case WINED3DFMT_R16G16B16A16_UNORM
:
3582 case WINED3DFMT_B2G3R3A8_UNORM
:
3583 TRACE_(d3d_caps
)("[FAILED]\n"); /* Enable when implemented */
3586 /* Floating point formats */
3587 case WINED3DFMT_R16_FLOAT
:
3588 case WINED3DFMT_R16G16_FLOAT
:
3589 case WINED3DFMT_R16G16B16A16_FLOAT
:
3590 if (gl_info
->supported
[ARB_TEXTURE_FLOAT
] && gl_info
->supported
[ARB_HALF_FLOAT_PIXEL
])
3592 TRACE_(d3d_caps
)("[OK]\n");
3595 TRACE_(d3d_caps
)("[FAILED]\n");
3598 case WINED3DFMT_R32_FLOAT
:
3599 case WINED3DFMT_R32G32_FLOAT
:
3600 case WINED3DFMT_R32G32B32A32_FLOAT
:
3601 if (gl_info
->supported
[ARB_TEXTURE_FLOAT
])
3603 TRACE_(d3d_caps
)("[OK]\n");
3606 TRACE_(d3d_caps
)("[FAILED]\n");
3609 /* ATI instancing hack: Although ATI cards do not support Shader Model 3.0, they support
3610 * instancing. To query if the card supports instancing CheckDeviceFormat with the special format
3611 * MAKEFOURCC('I','N','S','T') is used. Should a (broken) app check for this provide a proper return value.
3612 * We can do instancing with all shader versions, but we need vertex shaders.
3614 * Additionally applications have to set the D3DRS_POINTSIZE render state to MAKEFOURCC('I','N','S','T') once
3615 * to enable instancing. WineD3D doesn't need that and just ignores it.
3617 * With Shader Model 3.0 capable cards Instancing 'just works' in Windows.
3619 case WINED3DFMT_INST
:
3620 TRACE("ATI Instancing check hack\n");
3621 if (gl_info
->supported
[ARB_VERTEX_PROGRAM
] || gl_info
->supported
[ARB_VERTEX_SHADER
])
3623 TRACE_(d3d_caps
)("[OK]\n");
3626 TRACE_(d3d_caps
)("[FAILED]\n");
3629 /* Some weird FOURCC formats */
3630 case WINED3DFMT_R8G8_B8G8
:
3631 case WINED3DFMT_G8R8_G8B8
:
3632 case WINED3DFMT_MULTI2_ARGB8
:
3633 TRACE_(d3d_caps
)("[FAILED]\n");
3636 /* Vendor specific formats */
3637 case WINED3DFMT_ATI2N
:
3638 if (gl_info
->supported
[ATI_TEXTURE_COMPRESSION_3DC
]
3639 || gl_info
->supported
[ARB_TEXTURE_COMPRESSION_RGTC
])
3641 if (adapter
->shader_backend
->shader_color_fixup_supported(format_desc
->color_fixup
)
3642 && adapter
->fragment_pipe
->color_fixup_supported(format_desc
->color_fixup
))
3644 TRACE_(d3d_caps
)("[OK]\n");
3648 TRACE_(d3d_caps
)("[OK]\n");
3651 TRACE_(d3d_caps
)("[FAILED]\n");
3654 case WINED3DFMT_NVHU
:
3655 case WINED3DFMT_NVHS
:
3656 /* These formats seem to be similar to the HILO formats in GL_NV_texture_shader. NVHU
3657 * is said to be GL_UNSIGNED_HILO16, NVHS GL_SIGNED_HILO16. Rumours say that d3d computes
3658 * a 3rd channel similarly to D3DFMT_CxV8U8(So NVHS could be called D3DFMT_CxV16U16).
3659 * ATI refused to support formats which can easilly be emulated with pixel shaders, so
3660 * Applications have to deal with not having NVHS and NVHU.
3662 TRACE_(d3d_caps
)("[FAILED]\n");
3665 case WINED3DFMT_UNKNOWN
:
3669 ERR("Unhandled format %s.\n", debug_d3dformat(format_desc
->id
));
3675 static BOOL
CheckSurfaceCapability(struct wined3d_adapter
*adapter
,
3676 const struct wined3d_format_desc
*adapter_format_desc
,
3677 const struct wined3d_format_desc
*check_format_desc
,
3678 WINED3DSURFTYPE SurfaceType
)
3680 if (SurfaceType
== SURFACE_GDI
)
3682 switch (check_format_desc
->id
)
3684 case WINED3DFMT_B8G8R8_UNORM
:
3685 case WINED3DFMT_B8G8R8A8_UNORM
:
3686 case WINED3DFMT_B8G8R8X8_UNORM
:
3687 case WINED3DFMT_B5G6R5_UNORM
:
3688 case WINED3DFMT_B5G5R5X1_UNORM
:
3689 case WINED3DFMT_B5G5R5A1_UNORM
:
3690 case WINED3DFMT_B4G4R4A4_UNORM
:
3691 case WINED3DFMT_B2G3R3_UNORM
:
3692 case WINED3DFMT_A8_UNORM
:
3693 case WINED3DFMT_B2G3R3A8_UNORM
:
3694 case WINED3DFMT_B4G4R4X4_UNORM
:
3695 case WINED3DFMT_R10G10B10A2_UNORM
:
3696 case WINED3DFMT_R8G8B8A8_UNORM
:
3697 case WINED3DFMT_R8G8B8X8_UNORM
:
3698 case WINED3DFMT_R16G16_UNORM
:
3699 case WINED3DFMT_B10G10R10A2_UNORM
:
3700 case WINED3DFMT_R16G16B16A16_UNORM
:
3701 case WINED3DFMT_P8_UINT
:
3702 TRACE_(d3d_caps
)("[OK]\n");
3705 TRACE_(d3d_caps
)("[FAILED] - not available on GDI surfaces\n");
3710 /* All format that are supported for textures are supported for surfaces as well */
3711 if (CheckTextureCapability(adapter
, check_format_desc
)) return TRUE
;
3712 /* All depth stencil formats are supported on surfaces */
3713 if (CheckDepthStencilCapability(adapter
, adapter_format_desc
, check_format_desc
)) return TRUE
;
3715 /* If opengl can't process the format natively, the blitter may be able to convert it */
3716 if (adapter
->blitter
->blit_supported(&adapter
->gl_info
, BLIT_OP_BLIT
,
3717 NULL
, WINED3DPOOL_DEFAULT
, 0, check_format_desc
,
3718 NULL
, WINED3DPOOL_DEFAULT
, 0, adapter_format_desc
))
3720 TRACE_(d3d_caps
)("[OK]\n");
3724 /* Reject other formats */
3725 TRACE_(d3d_caps
)("[FAILED]\n");
3729 static BOOL
CheckVertexTextureCapability(struct wined3d_adapter
*adapter
,
3730 const struct wined3d_format_desc
*format_desc
)
3732 return adapter
->gl_info
.limits
.vertex_samplers
3733 && (format_desc
->Flags
& WINED3DFMT_FLAG_VTF
);
3736 static HRESULT WINAPI
IWineD3DImpl_CheckDeviceFormat(IWineD3D
*iface
, UINT Adapter
, WINED3DDEVTYPE DeviceType
,
3737 enum wined3d_format_id AdapterFormat
, DWORD Usage
, WINED3DRESOURCETYPE RType
,
3738 enum wined3d_format_id CheckFormat
, WINED3DSURFTYPE SurfaceType
)
3740 IWineD3DImpl
*This
= (IWineD3DImpl
*)iface
;
3741 struct wined3d_adapter
*adapter
= &This
->adapters
[Adapter
];
3742 const struct wined3d_gl_info
*gl_info
= &adapter
->gl_info
;
3743 const struct wined3d_format_desc
*format_desc
= getFormatDescEntry(CheckFormat
, gl_info
);
3744 const struct wined3d_format_desc
*adapter_format_desc
= getFormatDescEntry(AdapterFormat
, gl_info
);
3745 DWORD UsageCaps
= 0;
3747 TRACE_(d3d_caps
)("(%p)-> (STUB) (Adptr:%d, DevType:(%u,%s), AdptFmt:(%u,%s), Use:(%u,%s,%s), ResTyp:(%x,%s), CheckFmt:(%u,%s))\n",
3750 DeviceType
, debug_d3ddevicetype(DeviceType
),
3751 AdapterFormat
, debug_d3dformat(AdapterFormat
),
3752 Usage
, debug_d3dusage(Usage
), debug_d3dusagequery(Usage
),
3753 RType
, debug_d3dresourcetype(RType
),
3754 CheckFormat
, debug_d3dformat(CheckFormat
));
3756 if (Adapter
>= IWineD3D_GetAdapterCount(iface
)) {
3757 return WINED3DERR_INVALIDCALL
;
3762 case WINED3DRTYPE_CUBETEXTURE
:
3763 /* Cubetexture allows:
3764 * - WINED3DUSAGE_AUTOGENMIPMAP
3765 * - WINED3DUSAGE_DEPTHSTENCIL
3766 * - WINED3DUSAGE_DYNAMIC
3767 * - WINED3DUSAGE_NONSECURE (d3d9ex)
3768 * - WINED3DUSAGE_RENDERTARGET
3769 * - WINED3DUSAGE_SOFTWAREPROCESSING
3770 * - WINED3DUSAGE_QUERY_WRAPANDMIP
3772 if (SurfaceType
!= SURFACE_OPENGL
)
3774 TRACE_(d3d_caps
)("[FAILED]\n");
3775 return WINED3DERR_NOTAVAILABLE
;
3778 if (!gl_info
->supported
[ARB_TEXTURE_CUBE_MAP
])
3780 TRACE_(d3d_caps
)("[FAILED] - No cube texture support\n");
3781 return WINED3DERR_NOTAVAILABLE
;
3784 if (!CheckTextureCapability(adapter
, format_desc
))
3786 TRACE_(d3d_caps
)("[FAILED] - Cube texture format not supported\n");
3787 return WINED3DERR_NOTAVAILABLE
;
3790 if (Usage
& WINED3DUSAGE_AUTOGENMIPMAP
)
3792 if (!gl_info
->supported
[SGIS_GENERATE_MIPMAP
])
3793 /* When autogenmipmap isn't around continue and return
3794 * WINED3DOK_NOAUTOGEN instead of D3D_OK. */
3795 TRACE_(d3d_caps
)("[FAILED] - No autogenmipmap support, but continuing\n");
3797 UsageCaps
|= WINED3DUSAGE_AUTOGENMIPMAP
;
3800 /* Always report dynamic locking. */
3801 if (Usage
& WINED3DUSAGE_DYNAMIC
)
3802 UsageCaps
|= WINED3DUSAGE_DYNAMIC
;
3804 if (Usage
& WINED3DUSAGE_RENDERTARGET
)
3806 if (!CheckRenderTargetCapability(adapter
, adapter_format_desc
, format_desc
))
3808 TRACE_(d3d_caps
)("[FAILED] - No rendertarget support\n");
3809 return WINED3DERR_NOTAVAILABLE
;
3811 UsageCaps
|= WINED3DUSAGE_RENDERTARGET
;
3814 /* Always report software processing. */
3815 if (Usage
& WINED3DUSAGE_SOFTWAREPROCESSING
)
3816 UsageCaps
|= WINED3DUSAGE_SOFTWAREPROCESSING
;
3818 if (Usage
& WINED3DUSAGE_QUERY_FILTER
)
3820 if (!CheckFilterCapability(adapter
, format_desc
))
3822 TRACE_(d3d_caps
)("[FAILED] - No query filter support\n");
3823 return WINED3DERR_NOTAVAILABLE
;
3825 UsageCaps
|= WINED3DUSAGE_QUERY_FILTER
;
3828 if (Usage
& WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING
)
3830 if (!CheckPostPixelShaderBlendingCapability(adapter
, format_desc
))
3832 TRACE_(d3d_caps
)("[FAILED] - No query post pixelshader blending support\n");
3833 return WINED3DERR_NOTAVAILABLE
;
3835 UsageCaps
|= WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING
;
3838 if (Usage
& WINED3DUSAGE_QUERY_SRGBREAD
)
3840 if (!CheckSrgbReadCapability(adapter
, format_desc
))
3842 TRACE_(d3d_caps
)("[FAILED] - No query srgbread support\n");
3843 return WINED3DERR_NOTAVAILABLE
;
3845 UsageCaps
|= WINED3DUSAGE_QUERY_SRGBREAD
;
3848 if (Usage
& WINED3DUSAGE_QUERY_SRGBWRITE
)
3850 if (!CheckSrgbWriteCapability(adapter
, format_desc
))
3852 TRACE_(d3d_caps
)("[FAILED] - No query srgbwrite support\n");
3853 return WINED3DERR_NOTAVAILABLE
;
3855 UsageCaps
|= WINED3DUSAGE_QUERY_SRGBWRITE
;
3858 if (Usage
& WINED3DUSAGE_QUERY_VERTEXTEXTURE
)
3860 if (!CheckVertexTextureCapability(adapter
, format_desc
))
3862 TRACE_(d3d_caps
)("[FAILED] - No query vertextexture support\n");
3863 return WINED3DERR_NOTAVAILABLE
;
3865 UsageCaps
|= WINED3DUSAGE_QUERY_VERTEXTEXTURE
;
3868 if (Usage
& WINED3DUSAGE_QUERY_WRAPANDMIP
)
3870 if (!CheckWrapAndMipCapability(adapter
, format_desc
))
3872 TRACE_(d3d_caps
)("[FAILED] - No wrapping and mipmapping support\n");
3873 return WINED3DERR_NOTAVAILABLE
;
3875 UsageCaps
|= WINED3DUSAGE_QUERY_WRAPANDMIP
;
3879 case WINED3DRTYPE_SURFACE
:
3881 * - WINED3DUSAGE_DEPTHSTENCIL
3882 * - WINED3DUSAGE_NONSECURE (d3d9ex)
3883 * - WINED3DUSAGE_RENDERTARGET
3885 if (!CheckSurfaceCapability(adapter
, adapter_format_desc
, format_desc
, SurfaceType
))
3887 TRACE_(d3d_caps
)("[FAILED] - Not supported for plain surfaces\n");
3888 return WINED3DERR_NOTAVAILABLE
;
3891 if (Usage
& WINED3DUSAGE_DEPTHSTENCIL
)
3893 if (!CheckDepthStencilCapability(adapter
, adapter_format_desc
, format_desc
))
3895 TRACE_(d3d_caps
)("[FAILED] - No depthstencil support\n");
3896 return WINED3DERR_NOTAVAILABLE
;
3898 UsageCaps
|= WINED3DUSAGE_DEPTHSTENCIL
;
3901 if (Usage
& WINED3DUSAGE_RENDERTARGET
)
3903 if (!CheckRenderTargetCapability(adapter
, adapter_format_desc
, format_desc
))
3905 TRACE_(d3d_caps
)("[FAILED] - No rendertarget support\n");
3906 return WINED3DERR_NOTAVAILABLE
;
3908 UsageCaps
|= WINED3DUSAGE_RENDERTARGET
;
3911 if (Usage
& WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING
)
3913 if (!CheckPostPixelShaderBlendingCapability(adapter
, format_desc
))
3915 TRACE_(d3d_caps
)("[FAILED] - No query post pixelshader blending support\n");
3916 return WINED3DERR_NOTAVAILABLE
;
3918 UsageCaps
|= WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING
;
3922 case WINED3DRTYPE_TEXTURE
:
3924 * - WINED3DUSAGE_AUTOGENMIPMAP
3925 * - WINED3DUSAGE_DEPTHSTENCIL
3926 * - WINED3DUSAGE_DMAP
3927 * - WINED3DUSAGE_DYNAMIC
3928 * - WINED3DUSAGE_NONSECURE (d3d9ex)
3929 * - WINED3DUSAGE_RENDERTARGET
3930 * - WINED3DUSAGE_SOFTWAREPROCESSING
3931 * - WINED3DUSAGE_TEXTAPI (d3d9ex)
3932 * - WINED3DUSAGE_QUERY_WRAPANDMIP
3934 if (SurfaceType
!= SURFACE_OPENGL
)
3936 TRACE_(d3d_caps
)("[FAILED]\n");
3937 return WINED3DERR_NOTAVAILABLE
;
3940 if (!CheckTextureCapability(adapter
, format_desc
))
3942 TRACE_(d3d_caps
)("[FAILED] - Texture format not supported\n");
3943 return WINED3DERR_NOTAVAILABLE
;
3946 if (Usage
& WINED3DUSAGE_AUTOGENMIPMAP
)
3948 if (!gl_info
->supported
[SGIS_GENERATE_MIPMAP
])
3949 /* When autogenmipmap isn't around continue and return
3950 * WINED3DOK_NOAUTOGEN instead of D3D_OK. */
3951 TRACE_(d3d_caps
)("[FAILED] - No autogenmipmap support, but continuing\n");
3953 UsageCaps
|= WINED3DUSAGE_AUTOGENMIPMAP
;
3956 /* Always report dynamic locking. */
3957 if (Usage
& WINED3DUSAGE_DYNAMIC
)
3958 UsageCaps
|= WINED3DUSAGE_DYNAMIC
;
3960 if (Usage
& WINED3DUSAGE_RENDERTARGET
)
3962 if (!CheckRenderTargetCapability(adapter
, adapter_format_desc
, format_desc
))
3964 TRACE_(d3d_caps
)("[FAILED] - No rendertarget support\n");
3965 return WINED3DERR_NOTAVAILABLE
;
3967 UsageCaps
|= WINED3DUSAGE_RENDERTARGET
;
3970 /* Always report software processing. */
3971 if (Usage
& WINED3DUSAGE_SOFTWAREPROCESSING
)
3972 UsageCaps
|= WINED3DUSAGE_SOFTWAREPROCESSING
;
3974 if (Usage
& WINED3DUSAGE_QUERY_FILTER
)
3976 if (!CheckFilterCapability(adapter
, format_desc
))
3978 TRACE_(d3d_caps
)("[FAILED] - No query filter support\n");
3979 return WINED3DERR_NOTAVAILABLE
;
3981 UsageCaps
|= WINED3DUSAGE_QUERY_FILTER
;
3984 if (Usage
& WINED3DUSAGE_QUERY_LEGACYBUMPMAP
)
3986 if (!CheckBumpMapCapability(adapter
, format_desc
))
3988 TRACE_(d3d_caps
)("[FAILED] - No legacy bumpmap support\n");
3989 return WINED3DERR_NOTAVAILABLE
;
3991 UsageCaps
|= WINED3DUSAGE_QUERY_LEGACYBUMPMAP
;
3994 if (Usage
& WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING
)
3996 if (!CheckPostPixelShaderBlendingCapability(adapter
, format_desc
))
3998 TRACE_(d3d_caps
)("[FAILED] - No query post pixelshader blending support\n");
3999 return WINED3DERR_NOTAVAILABLE
;
4001 UsageCaps
|= WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING
;
4004 if (Usage
& WINED3DUSAGE_QUERY_SRGBREAD
)
4006 if (!CheckSrgbReadCapability(adapter
, format_desc
))
4008 TRACE_(d3d_caps
)("[FAILED] - No query srgbread support\n");
4009 return WINED3DERR_NOTAVAILABLE
;
4011 UsageCaps
|= WINED3DUSAGE_QUERY_SRGBREAD
;
4014 if (Usage
& WINED3DUSAGE_QUERY_SRGBWRITE
)
4016 if (!CheckSrgbWriteCapability(adapter
, format_desc
))
4018 TRACE_(d3d_caps
)("[FAILED] - No query srgbwrite support\n");
4019 return WINED3DERR_NOTAVAILABLE
;
4021 UsageCaps
|= WINED3DUSAGE_QUERY_SRGBWRITE
;
4024 if (Usage
& WINED3DUSAGE_QUERY_VERTEXTEXTURE
)
4026 if (!CheckVertexTextureCapability(adapter
, format_desc
))
4028 TRACE_(d3d_caps
)("[FAILED] - No query vertextexture support\n");
4029 return WINED3DERR_NOTAVAILABLE
;
4031 UsageCaps
|= WINED3DUSAGE_QUERY_VERTEXTEXTURE
;
4034 if (Usage
& WINED3DUSAGE_QUERY_WRAPANDMIP
)
4036 if (!CheckWrapAndMipCapability(adapter
, format_desc
))
4038 TRACE_(d3d_caps
)("[FAILED] - No wrapping and mipmapping support\n");
4039 return WINED3DERR_NOTAVAILABLE
;
4041 UsageCaps
|= WINED3DUSAGE_QUERY_WRAPANDMIP
;
4044 if (Usage
& WINED3DUSAGE_DEPTHSTENCIL
)
4046 if (!CheckDepthStencilCapability(adapter
, adapter_format_desc
, format_desc
))
4048 TRACE_(d3d_caps
)("[FAILED] - No depth stencil support\n");
4049 return WINED3DERR_NOTAVAILABLE
;
4051 if ((format_desc
->Flags
& WINED3DFMT_FLAG_SHADOW
) && !gl_info
->supported
[ARB_SHADOW
])
4053 TRACE_(d3d_caps
)("[FAILED] - No shadow sampler support.\n");
4054 return WINED3DERR_NOTAVAILABLE
;
4056 UsageCaps
|= WINED3DUSAGE_DEPTHSTENCIL
;
4060 case WINED3DRTYPE_VOLUMETEXTURE
:
4061 case WINED3DRTYPE_VOLUME
:
4062 /* Volume is to VolumeTexture what Surface is to Texture, but its
4063 * usage caps are not documented. Most driver seem to offer
4064 * (nearly) the same on Volume and VolumeTexture, so do that too.
4066 * Volumetexture allows:
4067 * - D3DUSAGE_DYNAMIC
4068 * - D3DUSAGE_NONSECURE (d3d9ex)
4069 * - D3DUSAGE_SOFTWAREPROCESSING
4070 * - D3DUSAGE_QUERY_WRAPANDMIP
4072 if (SurfaceType
!= SURFACE_OPENGL
)
4074 TRACE_(d3d_caps
)("[FAILED]\n");
4075 return WINED3DERR_NOTAVAILABLE
;
4078 if (!gl_info
->supported
[EXT_TEXTURE3D
])
4080 TRACE_(d3d_caps
)("[FAILED] - No volume texture support\n");
4081 return WINED3DERR_NOTAVAILABLE
;
4084 if (!CheckTextureCapability(adapter
, format_desc
))
4086 TRACE_(d3d_caps
)("[FAILED] - Format not supported\n");
4087 return WINED3DERR_NOTAVAILABLE
;
4090 /* Filter formats that need conversion; For one part, this
4091 * conversion is unimplemented, and volume textures are huge, so
4092 * it would be a big performance hit. Unless we hit an application
4093 * needing one of those formats, don't advertize them to avoid
4094 * leading applications into temptation. The windows drivers don't
4095 * support most of those formats on volumes anyway, except for
4096 * WINED3DFMT_R32_FLOAT. */
4097 switch (CheckFormat
)
4099 case WINED3DFMT_P8_UINT
:
4100 case WINED3DFMT_L4A4_UNORM
:
4101 case WINED3DFMT_R32_FLOAT
:
4102 case WINED3DFMT_R16_FLOAT
:
4103 case WINED3DFMT_R8G8_SNORM_L8X8_UNORM
:
4104 case WINED3DFMT_R5G5_SNORM_L6_UNORM
:
4105 case WINED3DFMT_R16G16_UNORM
:
4106 TRACE_(d3d_caps
)("[FAILED] - No converted formats on volumes\n");
4107 return WINED3DERR_NOTAVAILABLE
;
4109 case WINED3DFMT_R8G8B8A8_SNORM
:
4110 case WINED3DFMT_R16G16_SNORM
:
4111 if (!gl_info
->supported
[NV_TEXTURE_SHADER
])
4113 TRACE_(d3d_caps
)("[FAILED] - No converted formats on volumes\n");
4114 return WINED3DERR_NOTAVAILABLE
;
4118 case WINED3DFMT_R8G8_SNORM
:
4119 if (!gl_info
->supported
[NV_TEXTURE_SHADER
])
4121 TRACE_(d3d_caps
)("[FAILED] - No converted formats on volumes\n");
4122 return WINED3DERR_NOTAVAILABLE
;
4126 case WINED3DFMT_DXT1
:
4127 case WINED3DFMT_DXT2
:
4128 case WINED3DFMT_DXT3
:
4129 case WINED3DFMT_DXT4
:
4130 case WINED3DFMT_DXT5
:
4131 /* The GL_EXT_texture_compression_s3tc spec requires that
4132 * loading an s3tc compressed texture results in an error.
4133 * While the D3D refrast does support s3tc volumes, at
4134 * least the nvidia windows driver does not, so we're free
4135 * not to support this format. */
4136 TRACE_(d3d_caps
)("[FAILED] - DXTn does not support 3D textures\n");
4137 return WINED3DERR_NOTAVAILABLE
;
4140 /* Do nothing, continue with checking the format below */
4144 /* Always report dynamic locking. */
4145 if (Usage
& WINED3DUSAGE_DYNAMIC
)
4146 UsageCaps
|= WINED3DUSAGE_DYNAMIC
;
4148 /* Always report software processing. */
4149 if (Usage
& WINED3DUSAGE_SOFTWAREPROCESSING
)
4150 UsageCaps
|= WINED3DUSAGE_SOFTWAREPROCESSING
;
4152 if (Usage
& WINED3DUSAGE_QUERY_FILTER
)
4154 if (!CheckFilterCapability(adapter
, format_desc
))
4156 TRACE_(d3d_caps
)("[FAILED] - No query filter support\n");
4157 return WINED3DERR_NOTAVAILABLE
;
4159 UsageCaps
|= WINED3DUSAGE_QUERY_FILTER
;
4162 if (Usage
& WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING
)
4164 if (!CheckPostPixelShaderBlendingCapability(adapter
, format_desc
))
4166 TRACE_(d3d_caps
)("[FAILED] - No query post pixelshader blending support\n");
4167 return WINED3DERR_NOTAVAILABLE
;
4169 UsageCaps
|= WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING
;
4172 if (Usage
& WINED3DUSAGE_QUERY_SRGBREAD
)
4174 if (!CheckSrgbReadCapability(adapter
, format_desc
))
4176 TRACE_(d3d_caps
)("[FAILED] - No query srgbread support\n");
4177 return WINED3DERR_NOTAVAILABLE
;
4179 UsageCaps
|= WINED3DUSAGE_QUERY_SRGBREAD
;
4182 if (Usage
& WINED3DUSAGE_QUERY_SRGBWRITE
)
4184 if (!CheckSrgbWriteCapability(adapter
, format_desc
))
4186 TRACE_(d3d_caps
)("[FAILED] - No query srgbwrite support\n");
4187 return WINED3DERR_NOTAVAILABLE
;
4189 UsageCaps
|= WINED3DUSAGE_QUERY_SRGBWRITE
;
4192 if (Usage
& WINED3DUSAGE_QUERY_VERTEXTEXTURE
)
4194 if (!CheckVertexTextureCapability(adapter
, format_desc
))
4196 TRACE_(d3d_caps
)("[FAILED] - No query vertextexture support\n");
4197 return WINED3DERR_NOTAVAILABLE
;
4199 UsageCaps
|= WINED3DUSAGE_QUERY_VERTEXTEXTURE
;
4202 if (Usage
& WINED3DUSAGE_QUERY_WRAPANDMIP
)
4204 if (!CheckWrapAndMipCapability(adapter
, format_desc
))
4206 TRACE_(d3d_caps
)("[FAILED] - No wrapping and mipmapping support\n");
4207 return WINED3DERR_NOTAVAILABLE
;
4209 UsageCaps
|= WINED3DUSAGE_QUERY_WRAPANDMIP
;
4214 FIXME_(d3d_caps
)("Unhandled resource type %s.\n", debug_d3dresourcetype(RType
));
4215 return WINED3DERR_NOTAVAILABLE
;
4218 /* When the UsageCaps exactly matches Usage return WINED3D_OK except for
4219 * the situation in which WINED3DUSAGE_AUTOGENMIPMAP isn't around, then
4220 * WINED3DOK_NOAUTOGEN is returned if all the other usage flags match. */
4221 if (UsageCaps
== Usage
)
4223 if (UsageCaps
== (Usage
& ~WINED3DUSAGE_AUTOGENMIPMAP
))
4224 return WINED3DOK_NOAUTOGEN
;
4226 TRACE_(d3d_caps
)("[FAILED] - Usage %#x requested for CheckFormat %s and RType %s but only %#x is available\n",
4227 Usage
, debug_d3dformat(CheckFormat
), debug_d3dresourcetype(RType
), UsageCaps
);
4229 return WINED3DERR_NOTAVAILABLE
;
4232 static HRESULT WINAPI
IWineD3DImpl_CheckDeviceFormatConversion(IWineD3D
*iface
, UINT adapter_idx
,
4233 WINED3DDEVTYPE device_type
, enum wined3d_format_id src_format
, enum wined3d_format_id dst_format
)
4235 FIXME("iface %p, adapter_idx %u, device_type %s, src_format %s, dst_format %s stub!\n",
4236 iface
, adapter_idx
, debug_d3ddevicetype(device_type
), debug_d3dformat(src_format
),
4237 debug_d3dformat(dst_format
));
4242 /* Note: d3d8 passes in a pointer to a D3DCAPS8 structure, which is a true
4243 subset of a D3DCAPS9 structure. However, it has to come via a void *
4244 as the d3d8 interface cannot import the d3d9 header */
4245 static HRESULT WINAPI
IWineD3DImpl_GetDeviceCaps(IWineD3D
*iface
, UINT Adapter
, WINED3DDEVTYPE DeviceType
, WINED3DCAPS
* pCaps
) {
4247 IWineD3DImpl
*This
= (IWineD3DImpl
*)iface
;
4248 struct wined3d_adapter
*adapter
= &This
->adapters
[Adapter
];
4249 const struct wined3d_gl_info
*gl_info
= &adapter
->gl_info
;
4250 int vs_selected_mode
;
4251 int ps_selected_mode
;
4252 struct shader_caps shader_caps
;
4253 struct fragment_caps fragment_caps
;
4254 DWORD ckey_caps
, blit_caps
, fx_caps
;
4256 TRACE_(d3d_caps
)("(%p)->(Adptr:%d, DevType: %x, pCaps: %p)\n", This
, Adapter
, DeviceType
, pCaps
);
4258 if (Adapter
>= IWineD3D_GetAdapterCount(iface
)) {
4259 return WINED3DERR_INVALIDCALL
;
4262 select_shader_mode(&adapter
->gl_info
, &ps_selected_mode
, &vs_selected_mode
);
4264 /* ------------------------------------------------
4265 The following fields apply to both d3d8 and d3d9
4266 ------------------------------------------------ */
4267 pCaps
->DeviceType
= (DeviceType
== WINED3DDEVTYPE_HAL
) ? WINED3DDEVTYPE_HAL
: WINED3DDEVTYPE_REF
; /* Not quite true, but use h/w supported by opengl I suppose */
4268 pCaps
->AdapterOrdinal
= Adapter
;
4271 pCaps
->Caps2
= WINED3DCAPS2_CANRENDERWINDOWED
|
4272 WINED3DCAPS2_FULLSCREENGAMMA
|
4273 WINED3DCAPS2_DYNAMICTEXTURES
;
4274 if (gl_info
->supported
[SGIS_GENERATE_MIPMAP
])
4276 pCaps
->Caps2
|= WINED3DCAPS2_CANAUTOGENMIPMAP
;
4279 pCaps
->Caps3
= WINED3DCAPS3_ALPHA_FULLSCREEN_FLIP_OR_DISCARD
|
4280 WINED3DCAPS3_COPY_TO_VIDMEM
|
4281 WINED3DCAPS3_COPY_TO_SYSTEMMEM
;
4283 pCaps
->PresentationIntervals
= WINED3DPRESENT_INTERVAL_IMMEDIATE
|
4284 WINED3DPRESENT_INTERVAL_ONE
;
4286 pCaps
->CursorCaps
= WINED3DCURSORCAPS_COLOR
|
4287 WINED3DCURSORCAPS_LOWRES
;
4289 pCaps
->DevCaps
= WINED3DDEVCAPS_FLOATTLVERTEX
|
4290 WINED3DDEVCAPS_EXECUTESYSTEMMEMORY
|
4291 WINED3DDEVCAPS_TLVERTEXSYSTEMMEMORY
|
4292 WINED3DDEVCAPS_TLVERTEXVIDEOMEMORY
|
4293 WINED3DDEVCAPS_DRAWPRIMTLVERTEX
|
4294 WINED3DDEVCAPS_HWTRANSFORMANDLIGHT
|
4295 WINED3DDEVCAPS_EXECUTEVIDEOMEMORY
|
4296 WINED3DDEVCAPS_PUREDEVICE
|
4297 WINED3DDEVCAPS_HWRASTERIZATION
|
4298 WINED3DDEVCAPS_TEXTUREVIDEOMEMORY
|
4299 WINED3DDEVCAPS_TEXTURESYSTEMMEMORY
|
4300 WINED3DDEVCAPS_CANRENDERAFTERFLIP
|
4301 WINED3DDEVCAPS_DRAWPRIMITIVES2
|
4302 WINED3DDEVCAPS_DRAWPRIMITIVES2EX
|
4303 WINED3DDEVCAPS_RTPATCHES
;
4305 pCaps
->PrimitiveMiscCaps
= WINED3DPMISCCAPS_CULLNONE
|
4306 WINED3DPMISCCAPS_CULLCCW
|
4307 WINED3DPMISCCAPS_CULLCW
|
4308 WINED3DPMISCCAPS_COLORWRITEENABLE
|
4309 WINED3DPMISCCAPS_CLIPTLVERTS
|
4310 WINED3DPMISCCAPS_CLIPPLANESCALEDPOINTS
|
4311 WINED3DPMISCCAPS_MASKZ
|
4312 WINED3DPMISCCAPS_BLENDOP
|
4313 WINED3DPMISCCAPS_MRTPOSTPIXELSHADERBLENDING
;
4315 WINED3DPMISCCAPS_NULLREFERENCE
4316 WINED3DPMISCCAPS_FOGANDSPECULARALPHA
4317 WINED3DPMISCCAPS_MRTINDEPENDENTBITDEPTHS
4318 WINED3DPMISCCAPS_FOGVERTEXCLAMPED */
4320 if (gl_info
->supported
[EXT_BLEND_EQUATION_SEPARATE
] && gl_info
->supported
[EXT_BLEND_FUNC_SEPARATE
])
4321 pCaps
->PrimitiveMiscCaps
|= WINED3DPMISCCAPS_SEPARATEALPHABLEND
;
4322 if (gl_info
->supported
[EXT_DRAW_BUFFERS2
])
4323 pCaps
->PrimitiveMiscCaps
|= WINED3DPMISCCAPS_INDEPENDENTWRITEMASKS
;
4325 pCaps
->RasterCaps
= WINED3DPRASTERCAPS_DITHER
|
4326 WINED3DPRASTERCAPS_PAT
|
4327 WINED3DPRASTERCAPS_WFOG
|
4328 WINED3DPRASTERCAPS_ZFOG
|
4329 WINED3DPRASTERCAPS_FOGVERTEX
|
4330 WINED3DPRASTERCAPS_FOGTABLE
|
4331 WINED3DPRASTERCAPS_STIPPLE
|
4332 WINED3DPRASTERCAPS_SUBPIXEL
|
4333 WINED3DPRASTERCAPS_ZTEST
|
4334 WINED3DPRASTERCAPS_SCISSORTEST
|
4335 WINED3DPRASTERCAPS_SLOPESCALEDEPTHBIAS
|
4336 WINED3DPRASTERCAPS_DEPTHBIAS
;
4338 if (gl_info
->supported
[EXT_TEXTURE_FILTER_ANISOTROPIC
])
4340 pCaps
->RasterCaps
|= WINED3DPRASTERCAPS_ANISOTROPY
|
4341 WINED3DPRASTERCAPS_ZBIAS
|
4342 WINED3DPRASTERCAPS_MIPMAPLODBIAS
;
4344 if (gl_info
->supported
[NV_FOG_DISTANCE
])
4346 pCaps
->RasterCaps
|= WINED3DPRASTERCAPS_FOGRANGE
;
4349 WINED3DPRASTERCAPS_COLORPERSPECTIVE
4350 WINED3DPRASTERCAPS_STRETCHBLTMULTISAMPLE
4351 WINED3DPRASTERCAPS_ANTIALIASEDGES
4352 WINED3DPRASTERCAPS_ZBUFFERLESSHSR
4353 WINED3DPRASTERCAPS_WBUFFER */
4355 pCaps
->ZCmpCaps
= WINED3DPCMPCAPS_ALWAYS
|
4356 WINED3DPCMPCAPS_EQUAL
|
4357 WINED3DPCMPCAPS_GREATER
|
4358 WINED3DPCMPCAPS_GREATEREQUAL
|
4359 WINED3DPCMPCAPS_LESS
|
4360 WINED3DPCMPCAPS_LESSEQUAL
|
4361 WINED3DPCMPCAPS_NEVER
|
4362 WINED3DPCMPCAPS_NOTEQUAL
;
4364 pCaps
->SrcBlendCaps
= WINED3DPBLENDCAPS_BOTHINVSRCALPHA
|
4365 WINED3DPBLENDCAPS_BOTHSRCALPHA
|
4366 WINED3DPBLENDCAPS_DESTALPHA
|
4367 WINED3DPBLENDCAPS_DESTCOLOR
|
4368 WINED3DPBLENDCAPS_INVDESTALPHA
|
4369 WINED3DPBLENDCAPS_INVDESTCOLOR
|
4370 WINED3DPBLENDCAPS_INVSRCALPHA
|
4371 WINED3DPBLENDCAPS_INVSRCCOLOR
|
4372 WINED3DPBLENDCAPS_ONE
|
4373 WINED3DPBLENDCAPS_SRCALPHA
|
4374 WINED3DPBLENDCAPS_SRCALPHASAT
|
4375 WINED3DPBLENDCAPS_SRCCOLOR
|
4376 WINED3DPBLENDCAPS_ZERO
;
4378 pCaps
->DestBlendCaps
= WINED3DPBLENDCAPS_DESTALPHA
|
4379 WINED3DPBLENDCAPS_DESTCOLOR
|
4380 WINED3DPBLENDCAPS_INVDESTALPHA
|
4381 WINED3DPBLENDCAPS_INVDESTCOLOR
|
4382 WINED3DPBLENDCAPS_INVSRCALPHA
|
4383 WINED3DPBLENDCAPS_INVSRCCOLOR
|
4384 WINED3DPBLENDCAPS_ONE
|
4385 WINED3DPBLENDCAPS_SRCALPHA
|
4386 WINED3DPBLENDCAPS_SRCCOLOR
|
4387 WINED3DPBLENDCAPS_ZERO
;
4388 /* NOTE: WINED3DPBLENDCAPS_SRCALPHASAT is not supported as dest blend factor,
4389 * according to the glBlendFunc manpage
4391 * WINED3DPBLENDCAPS_BOTHINVSRCALPHA and WINED3DPBLENDCAPS_BOTHSRCALPHA are
4392 * legacy settings for srcblend only
4395 if (gl_info
->supported
[EXT_BLEND_COLOR
])
4397 pCaps
->SrcBlendCaps
|= WINED3DPBLENDCAPS_BLENDFACTOR
;
4398 pCaps
->DestBlendCaps
|= WINED3DPBLENDCAPS_BLENDFACTOR
;
4402 pCaps
->AlphaCmpCaps
= WINED3DPCMPCAPS_ALWAYS
|
4403 WINED3DPCMPCAPS_EQUAL
|
4404 WINED3DPCMPCAPS_GREATER
|
4405 WINED3DPCMPCAPS_GREATEREQUAL
|
4406 WINED3DPCMPCAPS_LESS
|
4407 WINED3DPCMPCAPS_LESSEQUAL
|
4408 WINED3DPCMPCAPS_NEVER
|
4409 WINED3DPCMPCAPS_NOTEQUAL
;
4411 pCaps
->ShadeCaps
= WINED3DPSHADECAPS_SPECULARGOURAUDRGB
|
4412 WINED3DPSHADECAPS_COLORGOURAUDRGB
|
4413 WINED3DPSHADECAPS_ALPHAFLATBLEND
|
4414 WINED3DPSHADECAPS_ALPHAGOURAUDBLEND
|
4415 WINED3DPSHADECAPS_COLORFLATRGB
|
4416 WINED3DPSHADECAPS_FOGFLAT
|
4417 WINED3DPSHADECAPS_FOGGOURAUD
|
4418 WINED3DPSHADECAPS_SPECULARFLATRGB
;
4420 pCaps
->TextureCaps
= WINED3DPTEXTURECAPS_ALPHA
|
4421 WINED3DPTEXTURECAPS_ALPHAPALETTE
|
4422 WINED3DPTEXTURECAPS_TRANSPARENCY
|
4423 WINED3DPTEXTURECAPS_BORDER
|
4424 WINED3DPTEXTURECAPS_MIPMAP
|
4425 WINED3DPTEXTURECAPS_PROJECTED
|
4426 WINED3DPTEXTURECAPS_PERSPECTIVE
;
4428 if (!gl_info
->supported
[ARB_TEXTURE_NON_POWER_OF_TWO
])
4430 pCaps
->TextureCaps
|= WINED3DPTEXTURECAPS_POW2
|
4431 WINED3DPTEXTURECAPS_NONPOW2CONDITIONAL
;
4434 if (gl_info
->supported
[EXT_TEXTURE3D
])
4436 pCaps
->TextureCaps
|= WINED3DPTEXTURECAPS_VOLUMEMAP
|
4437 WINED3DPTEXTURECAPS_MIPVOLUMEMAP
|
4438 WINED3DPTEXTURECAPS_VOLUMEMAP_POW2
;
4441 if (gl_info
->supported
[ARB_TEXTURE_CUBE_MAP
])
4443 pCaps
->TextureCaps
|= WINED3DPTEXTURECAPS_CUBEMAP
|
4444 WINED3DPTEXTURECAPS_MIPCUBEMAP
|
4445 WINED3DPTEXTURECAPS_CUBEMAP_POW2
;
4449 pCaps
->TextureFilterCaps
= WINED3DPTFILTERCAPS_MAGFLINEAR
|
4450 WINED3DPTFILTERCAPS_MAGFPOINT
|
4451 WINED3DPTFILTERCAPS_MINFLINEAR
|
4452 WINED3DPTFILTERCAPS_MINFPOINT
|
4453 WINED3DPTFILTERCAPS_MIPFLINEAR
|
4454 WINED3DPTFILTERCAPS_MIPFPOINT
|
4455 WINED3DPTFILTERCAPS_LINEAR
|
4456 WINED3DPTFILTERCAPS_LINEARMIPLINEAR
|
4457 WINED3DPTFILTERCAPS_LINEARMIPNEAREST
|
4458 WINED3DPTFILTERCAPS_MIPLINEAR
|
4459 WINED3DPTFILTERCAPS_MIPNEAREST
|
4460 WINED3DPTFILTERCAPS_NEAREST
;
4462 if (gl_info
->supported
[EXT_TEXTURE_FILTER_ANISOTROPIC
])
4464 pCaps
->TextureFilterCaps
|= WINED3DPTFILTERCAPS_MAGFANISOTROPIC
|
4465 WINED3DPTFILTERCAPS_MINFANISOTROPIC
;
4468 if (gl_info
->supported
[ARB_TEXTURE_CUBE_MAP
])
4470 pCaps
->CubeTextureFilterCaps
= WINED3DPTFILTERCAPS_MAGFLINEAR
|
4471 WINED3DPTFILTERCAPS_MAGFPOINT
|
4472 WINED3DPTFILTERCAPS_MINFLINEAR
|
4473 WINED3DPTFILTERCAPS_MINFPOINT
|
4474 WINED3DPTFILTERCAPS_MIPFLINEAR
|
4475 WINED3DPTFILTERCAPS_MIPFPOINT
|
4476 WINED3DPTFILTERCAPS_LINEAR
|
4477 WINED3DPTFILTERCAPS_LINEARMIPLINEAR
|
4478 WINED3DPTFILTERCAPS_LINEARMIPNEAREST
|
4479 WINED3DPTFILTERCAPS_MIPLINEAR
|
4480 WINED3DPTFILTERCAPS_MIPNEAREST
|
4481 WINED3DPTFILTERCAPS_NEAREST
;
4483 if (gl_info
->supported
[EXT_TEXTURE_FILTER_ANISOTROPIC
])
4485 pCaps
->CubeTextureFilterCaps
|= WINED3DPTFILTERCAPS_MAGFANISOTROPIC
|
4486 WINED3DPTFILTERCAPS_MINFANISOTROPIC
;
4489 pCaps
->CubeTextureFilterCaps
= 0;
4491 if (gl_info
->supported
[EXT_TEXTURE3D
])
4493 pCaps
->VolumeTextureFilterCaps
= WINED3DPTFILTERCAPS_MAGFLINEAR
|
4494 WINED3DPTFILTERCAPS_MAGFPOINT
|
4495 WINED3DPTFILTERCAPS_MINFLINEAR
|
4496 WINED3DPTFILTERCAPS_MINFPOINT
|
4497 WINED3DPTFILTERCAPS_MIPFLINEAR
|
4498 WINED3DPTFILTERCAPS_MIPFPOINT
|
4499 WINED3DPTFILTERCAPS_LINEAR
|
4500 WINED3DPTFILTERCAPS_LINEARMIPLINEAR
|
4501 WINED3DPTFILTERCAPS_LINEARMIPNEAREST
|
4502 WINED3DPTFILTERCAPS_MIPLINEAR
|
4503 WINED3DPTFILTERCAPS_MIPNEAREST
|
4504 WINED3DPTFILTERCAPS_NEAREST
;
4506 pCaps
->VolumeTextureFilterCaps
= 0;
4508 pCaps
->TextureAddressCaps
= WINED3DPTADDRESSCAPS_INDEPENDENTUV
|
4509 WINED3DPTADDRESSCAPS_CLAMP
|
4510 WINED3DPTADDRESSCAPS_WRAP
;
4512 if (gl_info
->supported
[ARB_TEXTURE_BORDER_CLAMP
])
4514 pCaps
->TextureAddressCaps
|= WINED3DPTADDRESSCAPS_BORDER
;
4516 if (gl_info
->supported
[ARB_TEXTURE_MIRRORED_REPEAT
])
4518 pCaps
->TextureAddressCaps
|= WINED3DPTADDRESSCAPS_MIRROR
;
4520 if (gl_info
->supported
[ATI_TEXTURE_MIRROR_ONCE
])
4522 pCaps
->TextureAddressCaps
|= WINED3DPTADDRESSCAPS_MIRRORONCE
;
4525 if (gl_info
->supported
[EXT_TEXTURE3D
])
4527 pCaps
->VolumeTextureAddressCaps
= WINED3DPTADDRESSCAPS_INDEPENDENTUV
|
4528 WINED3DPTADDRESSCAPS_CLAMP
|
4529 WINED3DPTADDRESSCAPS_WRAP
;
4530 if (gl_info
->supported
[ARB_TEXTURE_BORDER_CLAMP
])
4532 pCaps
->VolumeTextureAddressCaps
|= WINED3DPTADDRESSCAPS_BORDER
;
4534 if (gl_info
->supported
[ARB_TEXTURE_MIRRORED_REPEAT
])
4536 pCaps
->VolumeTextureAddressCaps
|= WINED3DPTADDRESSCAPS_MIRROR
;
4538 if (gl_info
->supported
[ATI_TEXTURE_MIRROR_ONCE
])
4540 pCaps
->VolumeTextureAddressCaps
|= WINED3DPTADDRESSCAPS_MIRRORONCE
;
4543 pCaps
->VolumeTextureAddressCaps
= 0;
4545 pCaps
->LineCaps
= WINED3DLINECAPS_TEXTURE
|
4546 WINED3DLINECAPS_ZTEST
|
4547 WINED3DLINECAPS_BLEND
|
4548 WINED3DLINECAPS_ALPHACMP
|
4549 WINED3DLINECAPS_FOG
;
4550 /* WINED3DLINECAPS_ANTIALIAS is not supported on Windows, and dx and gl seem to have a different
4551 * idea how generating the smoothing alpha values works; the result is different
4554 pCaps
->MaxTextureWidth
= gl_info
->limits
.texture_size
;
4555 pCaps
->MaxTextureHeight
= gl_info
->limits
.texture_size
;
4557 if (gl_info
->supported
[EXT_TEXTURE3D
])
4558 pCaps
->MaxVolumeExtent
= gl_info
->limits
.texture3d_size
;
4560 pCaps
->MaxVolumeExtent
= 0;
4562 pCaps
->MaxTextureRepeat
= 32768;
4563 pCaps
->MaxTextureAspectRatio
= gl_info
->limits
.texture_size
;
4564 pCaps
->MaxVertexW
= 1.0f
;
4566 pCaps
->GuardBandLeft
= 0.0f
;
4567 pCaps
->GuardBandTop
= 0.0f
;
4568 pCaps
->GuardBandRight
= 0.0f
;
4569 pCaps
->GuardBandBottom
= 0.0f
;
4571 pCaps
->ExtentsAdjust
= 0.0f
;
4573 pCaps
->StencilCaps
= WINED3DSTENCILCAPS_DECRSAT
|
4574 WINED3DSTENCILCAPS_INCRSAT
|
4575 WINED3DSTENCILCAPS_INVERT
|
4576 WINED3DSTENCILCAPS_KEEP
|
4577 WINED3DSTENCILCAPS_REPLACE
|
4578 WINED3DSTENCILCAPS_ZERO
;
4579 if (gl_info
->supported
[EXT_STENCIL_WRAP
])
4581 pCaps
->StencilCaps
|= WINED3DSTENCILCAPS_DECR
|
4582 WINED3DSTENCILCAPS_INCR
;
4584 if (gl_info
->supported
[EXT_STENCIL_TWO_SIDE
] || gl_info
->supported
[ATI_SEPARATE_STENCIL
])
4586 pCaps
->StencilCaps
|= WINED3DSTENCILCAPS_TWOSIDED
;
4589 pCaps
->FVFCaps
= WINED3DFVFCAPS_PSIZE
| 0x0008; /* 8 texture coords */
4591 pCaps
->MaxUserClipPlanes
= gl_info
->limits
.clipplanes
;
4592 pCaps
->MaxActiveLights
= gl_info
->limits
.lights
;
4594 pCaps
->MaxVertexBlendMatrices
= gl_info
->limits
.blends
;
4595 pCaps
->MaxVertexBlendMatrixIndex
= 0;
4597 pCaps
->MaxAnisotropy
= gl_info
->limits
.anisotropy
;
4598 pCaps
->MaxPointSize
= gl_info
->limits
.pointsize_max
;
4601 /* FIXME: Add D3DVTXPCAPS_TWEENING, D3DVTXPCAPS_TEXGEN_SPHEREMAP */
4602 pCaps
->VertexProcessingCaps
= WINED3DVTXPCAPS_DIRECTIONALLIGHTS
|
4603 WINED3DVTXPCAPS_MATERIALSOURCE7
|
4604 WINED3DVTXPCAPS_POSITIONALLIGHTS
|
4605 WINED3DVTXPCAPS_LOCALVIEWER
|
4606 WINED3DVTXPCAPS_VERTEXFOG
|
4607 WINED3DVTXPCAPS_TEXGEN
;
4609 pCaps
->MaxPrimitiveCount
= 0xFFFFF; /* For now set 2^20-1 which is used by most >=Geforce3/Radeon8500 cards */
4610 pCaps
->MaxVertexIndex
= 0xFFFFF;
4611 pCaps
->MaxStreams
= MAX_STREAMS
;
4612 pCaps
->MaxStreamStride
= 1024;
4614 /* d3d9.dll sets D3DDEVCAPS2_CAN_STRETCHRECT_FROM_TEXTURES here because StretchRects is implemented in d3d9 */
4615 pCaps
->DevCaps2
= WINED3DDEVCAPS2_STREAMOFFSET
|
4616 WINED3DDEVCAPS2_VERTEXELEMENTSCANSHARESTREAMOFFSET
;
4617 pCaps
->MaxNpatchTessellationLevel
= 0;
4618 pCaps
->MasterAdapterOrdinal
= 0;
4619 pCaps
->AdapterOrdinalInGroup
= 0;
4620 pCaps
->NumberOfAdaptersInGroup
= 1;
4622 pCaps
->NumSimultaneousRTs
= gl_info
->limits
.buffers
;
4624 pCaps
->StretchRectFilterCaps
= WINED3DPTFILTERCAPS_MINFPOINT
|
4625 WINED3DPTFILTERCAPS_MAGFPOINT
|
4626 WINED3DPTFILTERCAPS_MINFLINEAR
|
4627 WINED3DPTFILTERCAPS_MAGFLINEAR
;
4628 pCaps
->VertexTextureFilterCaps
= 0;
4630 adapter
->shader_backend
->shader_get_caps(&adapter
->gl_info
, &shader_caps
);
4631 adapter
->fragment_pipe
->get_caps(&adapter
->gl_info
, &fragment_caps
);
4633 /* Add shader misc caps. Only some of them belong to the shader parts of the pipeline */
4634 pCaps
->PrimitiveMiscCaps
|= fragment_caps
.PrimitiveMiscCaps
;
4636 /* This takes care for disabling vertex shader or pixel shader caps while leaving the other one enabled.
4637 * Ignore shader model capabilities if disabled in config
4639 if(vs_selected_mode
== SHADER_NONE
) {
4640 TRACE_(d3d_caps
)("Vertex shader disabled in config, reporting version 0.0\n");
4641 pCaps
->VertexShaderVersion
= WINED3DVS_VERSION(0,0);
4642 pCaps
->MaxVertexShaderConst
= 0;
4644 pCaps
->VertexShaderVersion
= shader_caps
.VertexShaderVersion
;
4645 pCaps
->MaxVertexShaderConst
= shader_caps
.MaxVertexShaderConst
;
4648 if(ps_selected_mode
== SHADER_NONE
) {
4649 TRACE_(d3d_caps
)("Pixel shader disabled in config, reporting version 0.0\n");
4650 pCaps
->PixelShaderVersion
= WINED3DPS_VERSION(0,0);
4651 pCaps
->PixelShader1xMaxValue
= 0.0f
;
4653 pCaps
->PixelShaderVersion
= shader_caps
.PixelShaderVersion
;
4654 pCaps
->PixelShader1xMaxValue
= shader_caps
.PixelShader1xMaxValue
;
4657 pCaps
->TextureOpCaps
= fragment_caps
.TextureOpCaps
;
4658 pCaps
->MaxTextureBlendStages
= fragment_caps
.MaxTextureBlendStages
;
4659 pCaps
->MaxSimultaneousTextures
= fragment_caps
.MaxSimultaneousTextures
;
4661 /* The following caps are shader specific, but they are things we cannot detect, or which
4662 * are the same among all shader models. So to avoid code duplication set the shader version
4663 * specific, but otherwise constant caps here
4665 if(pCaps
->VertexShaderVersion
== WINED3DVS_VERSION(3,0)) {
4666 /* Where possible set the caps based on OpenGL extensions and if they aren't set (in case of software rendering)
4667 use the VS 3.0 from MSDN or else if there's OpenGL spec use a hardcoded value minimum VS3.0 value. */
4668 pCaps
->VS20Caps
.Caps
= WINED3DVS20CAPS_PREDICATION
;
4669 pCaps
->VS20Caps
.DynamicFlowControlDepth
= WINED3DVS20_MAX_DYNAMICFLOWCONTROLDEPTH
; /* VS 3.0 requires MAX_DYNAMICFLOWCONTROLDEPTH (24) */
4670 pCaps
->VS20Caps
.NumTemps
= max(32, adapter
->gl_info
.limits
.arb_vs_temps
);
4671 pCaps
->VS20Caps
.StaticFlowControlDepth
= WINED3DVS20_MAX_STATICFLOWCONTROLDEPTH
; /* level of nesting in loops / if-statements; VS 3.0 requires MAX (4) */
4673 pCaps
->MaxVShaderInstructionsExecuted
= 65535; /* VS 3.0 needs at least 65535, some cards even use 2^32-1 */
4674 pCaps
->MaxVertexShader30InstructionSlots
= max(512, adapter
->gl_info
.limits
.arb_vs_instructions
);
4676 else if (pCaps
->VertexShaderVersion
== WINED3DVS_VERSION(2,0))
4678 pCaps
->VS20Caps
.Caps
= 0;
4679 pCaps
->VS20Caps
.DynamicFlowControlDepth
= WINED3DVS20_MIN_DYNAMICFLOWCONTROLDEPTH
;
4680 pCaps
->VS20Caps
.NumTemps
= max(12, adapter
->gl_info
.limits
.arb_vs_temps
);
4681 pCaps
->VS20Caps
.StaticFlowControlDepth
= 1;
4683 pCaps
->MaxVShaderInstructionsExecuted
= 65535;
4684 pCaps
->MaxVertexShader30InstructionSlots
= 0;
4685 } else { /* VS 1.x */
4686 pCaps
->VS20Caps
.Caps
= 0;
4687 pCaps
->VS20Caps
.DynamicFlowControlDepth
= 0;
4688 pCaps
->VS20Caps
.NumTemps
= 0;
4689 pCaps
->VS20Caps
.StaticFlowControlDepth
= 0;
4691 pCaps
->MaxVShaderInstructionsExecuted
= 0;
4692 pCaps
->MaxVertexShader30InstructionSlots
= 0;
4695 if(pCaps
->PixelShaderVersion
== WINED3DPS_VERSION(3,0)) {
4696 /* Where possible set the caps based on OpenGL extensions and if they aren't set (in case of software rendering)
4697 use the PS 3.0 from MSDN or else if there's OpenGL spec use a hardcoded value minimum PS 3.0 value. */
4699 /* Caps is more or less undocumented on MSDN but it appears to be used for PS20Caps based on results from R9600/FX5900/Geforce6800 cards from Windows */
4700 pCaps
->PS20Caps
.Caps
= WINED3DPS20CAPS_ARBITRARYSWIZZLE
|
4701 WINED3DPS20CAPS_GRADIENTINSTRUCTIONS
|
4702 WINED3DPS20CAPS_PREDICATION
|
4703 WINED3DPS20CAPS_NODEPENDENTREADLIMIT
|
4704 WINED3DPS20CAPS_NOTEXINSTRUCTIONLIMIT
;
4705 pCaps
->PS20Caps
.DynamicFlowControlDepth
= WINED3DPS20_MAX_DYNAMICFLOWCONTROLDEPTH
; /* PS 3.0 requires MAX_DYNAMICFLOWCONTROLDEPTH (24) */
4706 pCaps
->PS20Caps
.NumTemps
= max(32, adapter
->gl_info
.limits
.arb_ps_temps
);
4707 pCaps
->PS20Caps
.StaticFlowControlDepth
= WINED3DPS20_MAX_STATICFLOWCONTROLDEPTH
; /* PS 3.0 requires MAX_STATICFLOWCONTROLDEPTH (4) */
4708 pCaps
->PS20Caps
.NumInstructionSlots
= WINED3DPS20_MAX_NUMINSTRUCTIONSLOTS
; /* PS 3.0 requires MAX_NUMINSTRUCTIONSLOTS (512) */
4710 pCaps
->MaxPShaderInstructionsExecuted
= 65535;
4711 pCaps
->MaxPixelShader30InstructionSlots
= max(WINED3DMIN30SHADERINSTRUCTIONS
,
4712 adapter
->gl_info
.limits
.arb_ps_instructions
);
4714 else if(pCaps
->PixelShaderVersion
== WINED3DPS_VERSION(2,0))
4716 /* Below we assume PS2.0 specs, not extended 2.0a(GeforceFX)/2.0b(Radeon R3xx) ones */
4717 pCaps
->PS20Caps
.Caps
= 0;
4718 pCaps
->PS20Caps
.DynamicFlowControlDepth
= 0; /* WINED3DVS20_MIN_DYNAMICFLOWCONTROLDEPTH = 0 */
4719 pCaps
->PS20Caps
.NumTemps
= max(12, adapter
->gl_info
.limits
.arb_ps_temps
);
4720 pCaps
->PS20Caps
.StaticFlowControlDepth
= WINED3DPS20_MIN_STATICFLOWCONTROLDEPTH
; /* Minimum: 1 */
4721 pCaps
->PS20Caps
.NumInstructionSlots
= WINED3DPS20_MIN_NUMINSTRUCTIONSLOTS
; /* Minimum number (64 ALU + 32 Texture), a GeforceFX uses 512 */
4723 pCaps
->MaxPShaderInstructionsExecuted
= 512; /* Minimum value, a GeforceFX uses 1024 */
4724 pCaps
->MaxPixelShader30InstructionSlots
= 0;
4725 } else { /* PS 1.x */
4726 pCaps
->PS20Caps
.Caps
= 0;
4727 pCaps
->PS20Caps
.DynamicFlowControlDepth
= 0;
4728 pCaps
->PS20Caps
.NumTemps
= 0;
4729 pCaps
->PS20Caps
.StaticFlowControlDepth
= 0;
4730 pCaps
->PS20Caps
.NumInstructionSlots
= 0;
4732 pCaps
->MaxPShaderInstructionsExecuted
= 0;
4733 pCaps
->MaxPixelShader30InstructionSlots
= 0;
4736 if(pCaps
->VertexShaderVersion
>= WINED3DVS_VERSION(2,0)) {
4737 /* OpenGL supports all the formats below, perhaps not always
4738 * without conversion, but it supports them.
4739 * Further GLSL doesn't seem to have an official unsigned type so
4740 * don't advertise it yet as I'm not sure how we handle it.
4741 * We might need to add some clamping in the shader engine to
4743 * TODO: WINED3DDTCAPS_USHORT2N, WINED3DDTCAPS_USHORT4N, WINED3DDTCAPS_UDEC3, WINED3DDTCAPS_DEC3N */
4744 pCaps
->DeclTypes
= WINED3DDTCAPS_UBYTE4
|
4745 WINED3DDTCAPS_UBYTE4N
|
4746 WINED3DDTCAPS_SHORT2N
|
4747 WINED3DDTCAPS_SHORT4N
;
4748 if (gl_info
->supported
[ARB_HALF_FLOAT_VERTEX
])
4750 pCaps
->DeclTypes
|= WINED3DDTCAPS_FLOAT16_2
|
4751 WINED3DDTCAPS_FLOAT16_4
;
4754 pCaps
->DeclTypes
= 0;
4756 /* Set DirectDraw helper Caps */
4757 ckey_caps
= WINEDDCKEYCAPS_DESTBLT
|
4758 WINEDDCKEYCAPS_SRCBLT
;
4759 fx_caps
= WINEDDFXCAPS_BLTALPHA
|
4760 WINEDDFXCAPS_BLTMIRRORLEFTRIGHT
|
4761 WINEDDFXCAPS_BLTMIRRORUPDOWN
|
4762 WINEDDFXCAPS_BLTROTATION90
|
4763 WINEDDFXCAPS_BLTSHRINKX
|
4764 WINEDDFXCAPS_BLTSHRINKXN
|
4765 WINEDDFXCAPS_BLTSHRINKY
|
4766 WINEDDFXCAPS_BLTSHRINKXN
|
4767 WINEDDFXCAPS_BLTSTRETCHX
|
4768 WINEDDFXCAPS_BLTSTRETCHXN
|
4769 WINEDDFXCAPS_BLTSTRETCHY
|
4770 WINEDDFXCAPS_BLTSTRETCHYN
;
4771 blit_caps
= WINEDDCAPS_BLT
|
4772 WINEDDCAPS_BLTCOLORFILL
|
4773 WINEDDCAPS_BLTDEPTHFILL
|
4774 WINEDDCAPS_BLTSTRETCH
|
4775 WINEDDCAPS_CANBLTSYSMEM
|
4776 WINEDDCAPS_CANCLIP
|
4777 WINEDDCAPS_CANCLIPSTRETCHED
|
4778 WINEDDCAPS_COLORKEY
|
4779 WINEDDCAPS_COLORKEYHWASSIST
|
4780 WINEDDCAPS_ALIGNBOUNDARYSRC
;
4782 /* Fill the ddraw caps structure */
4783 pCaps
->DirectDrawCaps
.Caps
= WINEDDCAPS_GDI
|
4784 WINEDDCAPS_PALETTE
|
4786 pCaps
->DirectDrawCaps
.Caps2
= WINEDDCAPS2_CERTIFIED
|
4787 WINEDDCAPS2_NOPAGELOCKREQUIRED
|
4788 WINEDDCAPS2_PRIMARYGAMMA
|
4789 WINEDDCAPS2_WIDESURFACES
|
4790 WINEDDCAPS2_CANRENDERWINDOWED
;
4791 pCaps
->DirectDrawCaps
.SVBCaps
= blit_caps
;
4792 pCaps
->DirectDrawCaps
.SVBCKeyCaps
= ckey_caps
;
4793 pCaps
->DirectDrawCaps
.SVBFXCaps
= fx_caps
;
4794 pCaps
->DirectDrawCaps
.VSBCaps
= blit_caps
;
4795 pCaps
->DirectDrawCaps
.VSBCKeyCaps
= ckey_caps
;
4796 pCaps
->DirectDrawCaps
.VSBFXCaps
= fx_caps
;
4797 pCaps
->DirectDrawCaps
.SSBCaps
= blit_caps
;
4798 pCaps
->DirectDrawCaps
.SSBCKeyCaps
= ckey_caps
;
4799 pCaps
->DirectDrawCaps
.SSBFXCaps
= fx_caps
;
4801 pCaps
->DirectDrawCaps
.ddsCaps
= WINEDDSCAPS_ALPHA
|
4802 WINEDDSCAPS_BACKBUFFER
|
4804 WINEDDSCAPS_FRONTBUFFER
|
4805 WINEDDSCAPS_OFFSCREENPLAIN
|
4806 WINEDDSCAPS_PALETTE
|
4807 WINEDDSCAPS_PRIMARYSURFACE
|
4808 WINEDDSCAPS_SYSTEMMEMORY
|
4809 WINEDDSCAPS_VIDEOMEMORY
|
4810 WINEDDSCAPS_VISIBLE
;
4811 pCaps
->DirectDrawCaps
.StrideAlign
= DDRAW_PITCH_ALIGNMENT
;
4813 /* Set D3D caps if OpenGL is available. */
4814 if (adapter
->opengl
)
4816 pCaps
->DirectDrawCaps
.ddsCaps
|=WINEDDSCAPS_3DDEVICE
|
4817 WINEDDSCAPS_MIPMAP
|
4818 WINEDDSCAPS_TEXTURE
|
4819 WINEDDSCAPS_ZBUFFER
;
4820 pCaps
->DirectDrawCaps
.Caps
|= WINEDDCAPS_3D
;
4826 static HRESULT WINAPI
IWineD3DImpl_CreateDevice(IWineD3D
*iface
, UINT adapter_idx
,
4827 WINED3DDEVTYPE device_type
, HWND focus_window
, DWORD flags
, IUnknown
*parent
,
4828 IWineD3DDeviceParent
*device_parent
, IWineD3DDevice
**device
)
4830 IWineD3DImpl
*This
= (IWineD3DImpl
*)iface
;
4831 IWineD3DDeviceImpl
*object
;
4834 TRACE("iface %p, adapter_idx %u, device_type %#x, focus_window %p, flags %#x.\n"
4835 "parent %p, device_parent %p, device %p.\n",
4836 iface
, adapter_idx
, device_type
, focus_window
, flags
,
4837 parent
, device_parent
, device
);
4839 /* Validate the adapter number. If no adapters are available(no GL), ignore the adapter
4840 * number and create a device without a 3D adapter for 2D only operation. */
4841 if (IWineD3D_GetAdapterCount(iface
) && adapter_idx
>= IWineD3D_GetAdapterCount(iface
))
4843 return WINED3DERR_INVALIDCALL
;
4846 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(*object
));
4849 ERR("Failed to allocate device memory.\n");
4850 return E_OUTOFMEMORY
;
4853 hr
= device_init(object
, This
, adapter_idx
, device_type
, focus_window
, flags
, parent
, device_parent
);
4856 WARN("Failed to initialize device, hr %#x.\n", hr
);
4857 HeapFree(GetProcessHeap(), 0, object
);
4861 TRACE("Created device %p.\n", object
);
4862 *device
= (IWineD3DDevice
*)object
;
4864 IWineD3DDeviceParent_WineD3DDeviceCreated(device_parent
, *device
);
4869 static HRESULT WINAPI
IWineD3DImpl_GetParent(IWineD3D
*iface
, IUnknown
**pParent
) {
4870 IWineD3DImpl
*This
= (IWineD3DImpl
*)iface
;
4871 IUnknown_AddRef(This
->parent
);
4872 *pParent
= This
->parent
;
4876 static void WINE_GLAPI
invalid_func(const void *data
)
4878 ERR("Invalid vertex attribute function called\n");
4882 static void WINE_GLAPI
invalid_texcoord_func(GLenum unit
, const void *data
)
4884 ERR("Invalid texcoord function called\n");
4888 /* Helper functions for providing vertex data to opengl. The arrays are initialized based on
4889 * the extension detection and are used in drawStridedSlow
4891 static void WINE_GLAPI
position_d3dcolor(const void *data
)
4893 DWORD pos
= *((const DWORD
*)data
);
4895 FIXME("Add a test for fixed function position from d3dcolor type\n");
4896 glVertex4s(D3DCOLOR_B_R(pos
),
4902 static void WINE_GLAPI
position_float4(const void *data
)
4904 const GLfloat
*pos
= data
;
4906 if (pos
[3] != 0.0f
&& pos
[3] != 1.0f
)
4908 float w
= 1.0f
/ pos
[3];
4910 glVertex4f(pos
[0] * w
, pos
[1] * w
, pos
[2] * w
, w
);
4918 static void WINE_GLAPI
diffuse_d3dcolor(const void *data
)
4920 DWORD diffuseColor
= *((const DWORD
*)data
);
4922 glColor4ub(D3DCOLOR_B_R(diffuseColor
),
4923 D3DCOLOR_B_G(diffuseColor
),
4924 D3DCOLOR_B_B(diffuseColor
),
4925 D3DCOLOR_B_A(diffuseColor
));
4928 static void WINE_GLAPI
specular_d3dcolor(const void *data
)
4930 DWORD specularColor
= *((const DWORD
*)data
);
4931 GLbyte d
[] = {D3DCOLOR_B_R(specularColor
),
4932 D3DCOLOR_B_G(specularColor
),
4933 D3DCOLOR_B_B(specularColor
)};
4935 specular_func_3ubv(d
);
4938 static void WINE_GLAPI
warn_no_specular_func(const void *data
)
4940 WARN("GL_EXT_secondary_color not supported\n");
4943 static void fillGLAttribFuncs(const struct wined3d_gl_info
*gl_info
)
4945 position_funcs
[WINED3D_FFP_EMIT_FLOAT1
] = invalid_func
;
4946 position_funcs
[WINED3D_FFP_EMIT_FLOAT2
] = invalid_func
;
4947 position_funcs
[WINED3D_FFP_EMIT_FLOAT3
] = (glAttribFunc
)glVertex3fv
;
4948 position_funcs
[WINED3D_FFP_EMIT_FLOAT4
] = position_float4
;
4949 position_funcs
[WINED3D_FFP_EMIT_D3DCOLOR
] = position_d3dcolor
;
4950 position_funcs
[WINED3D_FFP_EMIT_UBYTE4
] = invalid_func
;
4951 position_funcs
[WINED3D_FFP_EMIT_SHORT2
] = invalid_func
;
4952 position_funcs
[WINED3D_FFP_EMIT_SHORT4
] = (glAttribFunc
)glVertex2sv
;
4953 position_funcs
[WINED3D_FFP_EMIT_UBYTE4N
] = invalid_func
;
4954 position_funcs
[WINED3D_FFP_EMIT_SHORT2N
] = invalid_func
;
4955 position_funcs
[WINED3D_FFP_EMIT_SHORT4N
] = invalid_func
;
4956 position_funcs
[WINED3D_FFP_EMIT_USHORT2N
] = invalid_func
;
4957 position_funcs
[WINED3D_FFP_EMIT_USHORT4N
] = invalid_func
;
4958 position_funcs
[WINED3D_FFP_EMIT_UDEC3
] = invalid_func
;
4959 position_funcs
[WINED3D_FFP_EMIT_DEC3N
] = invalid_func
;
4960 position_funcs
[WINED3D_FFP_EMIT_FLOAT16_2
] = invalid_func
;
4961 position_funcs
[WINED3D_FFP_EMIT_FLOAT16_4
] = invalid_func
;
4963 diffuse_funcs
[WINED3D_FFP_EMIT_FLOAT1
] = invalid_func
;
4964 diffuse_funcs
[WINED3D_FFP_EMIT_FLOAT2
] = invalid_func
;
4965 diffuse_funcs
[WINED3D_FFP_EMIT_FLOAT3
] = (glAttribFunc
)glColor3fv
;
4966 diffuse_funcs
[WINED3D_FFP_EMIT_FLOAT4
] = (glAttribFunc
)glColor4fv
;
4967 diffuse_funcs
[WINED3D_FFP_EMIT_D3DCOLOR
] = diffuse_d3dcolor
;
4968 diffuse_funcs
[WINED3D_FFP_EMIT_UBYTE4
] = invalid_func
;
4969 diffuse_funcs
[WINED3D_FFP_EMIT_SHORT2
] = invalid_func
;
4970 diffuse_funcs
[WINED3D_FFP_EMIT_SHORT4
] = invalid_func
;
4971 diffuse_funcs
[WINED3D_FFP_EMIT_UBYTE4N
] = (glAttribFunc
)glColor4ubv
;
4972 diffuse_funcs
[WINED3D_FFP_EMIT_SHORT2N
] = invalid_func
;
4973 diffuse_funcs
[WINED3D_FFP_EMIT_SHORT4N
] = (glAttribFunc
)glColor4sv
;
4974 diffuse_funcs
[WINED3D_FFP_EMIT_USHORT2N
] = invalid_func
;
4975 diffuse_funcs
[WINED3D_FFP_EMIT_USHORT4N
] = (glAttribFunc
)glColor4usv
;
4976 diffuse_funcs
[WINED3D_FFP_EMIT_UDEC3
] = invalid_func
;
4977 diffuse_funcs
[WINED3D_FFP_EMIT_DEC3N
] = invalid_func
;
4978 diffuse_funcs
[WINED3D_FFP_EMIT_FLOAT16_2
] = invalid_func
;
4979 diffuse_funcs
[WINED3D_FFP_EMIT_FLOAT16_4
] = invalid_func
;
4981 /* No 4 component entry points here */
4982 specular_funcs
[WINED3D_FFP_EMIT_FLOAT1
] = invalid_func
;
4983 specular_funcs
[WINED3D_FFP_EMIT_FLOAT2
] = invalid_func
;
4984 if (gl_info
->supported
[EXT_SECONDARY_COLOR
])
4986 specular_funcs
[WINED3D_FFP_EMIT_FLOAT3
] = (glAttribFunc
)GL_EXTCALL(glSecondaryColor3fvEXT
);
4990 specular_funcs
[WINED3D_FFP_EMIT_FLOAT3
] = warn_no_specular_func
;
4992 specular_funcs
[WINED3D_FFP_EMIT_FLOAT4
] = invalid_func
;
4993 if (gl_info
->supported
[EXT_SECONDARY_COLOR
])
4995 specular_func_3ubv
= (glAttribFunc
)GL_EXTCALL(glSecondaryColor3ubvEXT
);
4996 specular_funcs
[WINED3D_FFP_EMIT_D3DCOLOR
] = specular_d3dcolor
;
5000 specular_funcs
[WINED3D_FFP_EMIT_D3DCOLOR
] = warn_no_specular_func
;
5002 specular_funcs
[WINED3D_FFP_EMIT_UBYTE4
] = invalid_func
;
5003 specular_funcs
[WINED3D_FFP_EMIT_SHORT2
] = invalid_func
;
5004 specular_funcs
[WINED3D_FFP_EMIT_SHORT4
] = invalid_func
;
5005 specular_funcs
[WINED3D_FFP_EMIT_UBYTE4N
] = invalid_func
;
5006 specular_funcs
[WINED3D_FFP_EMIT_SHORT2N
] = invalid_func
;
5007 specular_funcs
[WINED3D_FFP_EMIT_SHORT4N
] = invalid_func
;
5008 specular_funcs
[WINED3D_FFP_EMIT_USHORT2N
] = invalid_func
;
5009 specular_funcs
[WINED3D_FFP_EMIT_USHORT4N
] = invalid_func
;
5010 specular_funcs
[WINED3D_FFP_EMIT_UDEC3
] = invalid_func
;
5011 specular_funcs
[WINED3D_FFP_EMIT_DEC3N
] = invalid_func
;
5012 specular_funcs
[WINED3D_FFP_EMIT_FLOAT16_2
] = invalid_func
;
5013 specular_funcs
[WINED3D_FFP_EMIT_FLOAT16_4
] = invalid_func
;
5015 /* Only 3 component entry points here. Test how others behave. Float4 normals are used
5016 * by one of our tests, trying to pass it to the pixel shader, which fails on Windows.
5018 normal_funcs
[WINED3D_FFP_EMIT_FLOAT1
] = invalid_func
;
5019 normal_funcs
[WINED3D_FFP_EMIT_FLOAT2
] = invalid_func
;
5020 normal_funcs
[WINED3D_FFP_EMIT_FLOAT3
] = (glAttribFunc
)glNormal3fv
;
5021 normal_funcs
[WINED3D_FFP_EMIT_FLOAT4
] = (glAttribFunc
)glNormal3fv
; /* Just ignore the 4th value */
5022 normal_funcs
[WINED3D_FFP_EMIT_D3DCOLOR
] = invalid_func
;
5023 normal_funcs
[WINED3D_FFP_EMIT_UBYTE4
] = invalid_func
;
5024 normal_funcs
[WINED3D_FFP_EMIT_SHORT2
] = invalid_func
;
5025 normal_funcs
[WINED3D_FFP_EMIT_SHORT4
] = invalid_func
;
5026 normal_funcs
[WINED3D_FFP_EMIT_UBYTE4N
] = invalid_func
;
5027 normal_funcs
[WINED3D_FFP_EMIT_SHORT2N
] = invalid_func
;
5028 normal_funcs
[WINED3D_FFP_EMIT_SHORT4N
] = invalid_func
;
5029 normal_funcs
[WINED3D_FFP_EMIT_USHORT2N
] = invalid_func
;
5030 normal_funcs
[WINED3D_FFP_EMIT_USHORT4N
] = invalid_func
;
5031 normal_funcs
[WINED3D_FFP_EMIT_UDEC3
] = invalid_func
;
5032 normal_funcs
[WINED3D_FFP_EMIT_DEC3N
] = invalid_func
;
5033 normal_funcs
[WINED3D_FFP_EMIT_FLOAT16_2
] = invalid_func
;
5034 normal_funcs
[WINED3D_FFP_EMIT_FLOAT16_4
] = invalid_func
;
5036 multi_texcoord_funcs
[WINED3D_FFP_EMIT_FLOAT1
] = (glMultiTexCoordFunc
)GL_EXTCALL(glMultiTexCoord1fvARB
);
5037 multi_texcoord_funcs
[WINED3D_FFP_EMIT_FLOAT2
] = (glMultiTexCoordFunc
)GL_EXTCALL(glMultiTexCoord2fvARB
);
5038 multi_texcoord_funcs
[WINED3D_FFP_EMIT_FLOAT3
] = (glMultiTexCoordFunc
)GL_EXTCALL(glMultiTexCoord3fvARB
);
5039 multi_texcoord_funcs
[WINED3D_FFP_EMIT_FLOAT4
] = (glMultiTexCoordFunc
)GL_EXTCALL(glMultiTexCoord4fvARB
);
5040 multi_texcoord_funcs
[WINED3D_FFP_EMIT_D3DCOLOR
] = invalid_texcoord_func
;
5041 multi_texcoord_funcs
[WINED3D_FFP_EMIT_UBYTE4
] = invalid_texcoord_func
;
5042 multi_texcoord_funcs
[WINED3D_FFP_EMIT_SHORT2
] = (glMultiTexCoordFunc
)GL_EXTCALL(glMultiTexCoord2svARB
);
5043 multi_texcoord_funcs
[WINED3D_FFP_EMIT_SHORT4
] = (glMultiTexCoordFunc
)GL_EXTCALL(glMultiTexCoord4svARB
);
5044 multi_texcoord_funcs
[WINED3D_FFP_EMIT_UBYTE4N
] = invalid_texcoord_func
;
5045 multi_texcoord_funcs
[WINED3D_FFP_EMIT_SHORT2N
] = invalid_texcoord_func
;
5046 multi_texcoord_funcs
[WINED3D_FFP_EMIT_SHORT4N
] = invalid_texcoord_func
;
5047 multi_texcoord_funcs
[WINED3D_FFP_EMIT_USHORT2N
] = invalid_texcoord_func
;
5048 multi_texcoord_funcs
[WINED3D_FFP_EMIT_USHORT4N
] = invalid_texcoord_func
;
5049 multi_texcoord_funcs
[WINED3D_FFP_EMIT_UDEC3
] = invalid_texcoord_func
;
5050 multi_texcoord_funcs
[WINED3D_FFP_EMIT_DEC3N
] = invalid_texcoord_func
;
5051 if (gl_info
->supported
[NV_HALF_FLOAT
])
5053 /* Not supported by ARB_HALF_FLOAT_VERTEX, so check for NV_HALF_FLOAT */
5054 multi_texcoord_funcs
[WINED3D_FFP_EMIT_FLOAT16_2
] = (glMultiTexCoordFunc
)GL_EXTCALL(glMultiTexCoord2hvNV
);
5055 multi_texcoord_funcs
[WINED3D_FFP_EMIT_FLOAT16_4
] = (glMultiTexCoordFunc
)GL_EXTCALL(glMultiTexCoord4hvNV
);
5057 multi_texcoord_funcs
[WINED3D_FFP_EMIT_FLOAT16_2
] = invalid_texcoord_func
;
5058 multi_texcoord_funcs
[WINED3D_FFP_EMIT_FLOAT16_4
] = invalid_texcoord_func
;
5062 static BOOL
InitAdapters(IWineD3DImpl
*This
)
5064 static HMODULE mod_gl
;
5066 int ps_selected_mode
, vs_selected_mode
;
5068 /* No need to hold any lock. The calling library makes sure only one thread calls
5069 * wined3d simultaneously
5072 TRACE("Initializing adapters\n");
5075 #ifdef USE_WIN32_OPENGL
5076 #define USE_GL_FUNC(pfn) pfn = (void*)GetProcAddress(mod_gl, #pfn);
5077 mod_gl
= LoadLibraryA("opengl32.dll");
5079 ERR("Can't load opengl32.dll!\n");
5083 #define USE_GL_FUNC(pfn) pfn = (void*)pwglGetProcAddress(#pfn);
5084 /* To bypass the opengl32 thunks load wglGetProcAddress from gdi32 (glXGetProcAddress wrapper) instead of opengl32's */
5085 mod_gl
= GetModuleHandleA("gdi32.dll");
5089 /* Load WGL core functions from opengl32.dll */
5090 #define USE_WGL_FUNC(pfn) p##pfn = (void*)GetProcAddress(mod_gl, #pfn);
5094 if(!pwglGetProcAddress
) {
5095 ERR("Unable to load wglGetProcAddress!\n");
5099 /* Dynamically load all GL core functions */
5103 /* Load glFinish and glFlush from opengl32.dll even if we're not using WIN32 opengl
5104 * otherwise because we have to use winex11.drv's override
5106 #ifdef USE_WIN32_OPENGL
5107 wglFinish
= (void*)GetProcAddress(mod_gl
, "glFinish");
5108 wglFlush
= (void*)GetProcAddress(mod_gl
, "glFlush");
5110 wglFinish
= (void*)pwglGetProcAddress("wglFinish");
5111 wglFlush
= (void*)pwglGetProcAddress("wglFlush");
5114 glEnableWINE
= glEnable
;
5115 glDisableWINE
= glDisable
;
5117 /* For now only one default adapter */
5119 struct wined3d_adapter
*adapter
= &This
->adapters
[0];
5120 const struct wined3d_gl_info
*gl_info
= &adapter
->gl_info
;
5121 struct wined3d_fake_gl_ctx fake_gl_ctx
= {0};
5125 WineD3D_PixelFormat
*cfgs
;
5126 DISPLAY_DEVICEW DisplayDevice
;
5129 TRACE("Initializing default adapter\n");
5130 adapter
->ordinal
= 0;
5131 adapter
->monitorPoint
.x
= -1;
5132 adapter
->monitorPoint
.y
= -1;
5134 if (!AllocateLocallyUniqueId(&adapter
->luid
))
5136 DWORD err
= GetLastError();
5137 ERR("Failed to set adapter LUID (%#x).\n", err
);
5140 TRACE("Allocated LUID %08x:%08x for adapter.\n",
5141 adapter
->luid
.HighPart
, adapter
->luid
.LowPart
);
5143 if (!WineD3D_CreateFakeGLContext(&fake_gl_ctx
))
5145 ERR("Failed to get a gl context for default adapter\n");
5149 ret
= IWineD3DImpl_FillGLCaps(adapter
);
5151 ERR("Failed to initialize gl caps for default adapter\n");
5152 WineD3D_ReleaseFakeGLContext(&fake_gl_ctx
);
5155 ret
= initPixelFormats(&adapter
->gl_info
, adapter
->driver_info
.vendor
);
5157 ERR("Failed to init gl formats\n");
5158 WineD3D_ReleaseFakeGLContext(&fake_gl_ctx
);
5162 hdc
= fake_gl_ctx
.dc
;
5164 /* Use the VideoRamSize registry setting when set */
5165 if(wined3d_settings
.emulated_textureram
)
5166 adapter
->TextureRam
= wined3d_settings
.emulated_textureram
;
5168 adapter
->TextureRam
= adapter
->gl_info
.vidmem
;
5169 adapter
->UsedTextureRam
= 0;
5170 TRACE("Emulating %dMB of texture ram\n", adapter
->TextureRam
/(1024*1024));
5172 /* Initialize the Adapter's DeviceName which is required for ChangeDisplaySettings and friends */
5173 DisplayDevice
.cb
= sizeof(DisplayDevice
);
5174 EnumDisplayDevicesW(NULL
, 0 /* Adapter 0 = iDevNum 0 */, &DisplayDevice
, 0);
5175 TRACE("DeviceName: %s\n", debugstr_w(DisplayDevice
.DeviceName
));
5176 strcpyW(adapter
->DeviceName
, DisplayDevice
.DeviceName
);
5178 if (gl_info
->supported
[WGL_ARB_PIXEL_FORMAT
])
5185 attribute
= WGL_NUMBER_PIXEL_FORMATS_ARB
;
5186 GL_EXTCALL(wglGetPixelFormatAttribivARB(hdc
, 0, 0, 1, &attribute
, &adapter
->nCfgs
));
5188 adapter
->cfgs
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, adapter
->nCfgs
*sizeof(WineD3D_PixelFormat
));
5189 cfgs
= adapter
->cfgs
;
5190 attribs
[nAttribs
++] = WGL_RED_BITS_ARB
;
5191 attribs
[nAttribs
++] = WGL_GREEN_BITS_ARB
;
5192 attribs
[nAttribs
++] = WGL_BLUE_BITS_ARB
;
5193 attribs
[nAttribs
++] = WGL_ALPHA_BITS_ARB
;
5194 attribs
[nAttribs
++] = WGL_COLOR_BITS_ARB
;
5195 attribs
[nAttribs
++] = WGL_DEPTH_BITS_ARB
;
5196 attribs
[nAttribs
++] = WGL_STENCIL_BITS_ARB
;
5197 attribs
[nAttribs
++] = WGL_DRAW_TO_WINDOW_ARB
;
5198 attribs
[nAttribs
++] = WGL_PIXEL_TYPE_ARB
;
5199 attribs
[nAttribs
++] = WGL_DOUBLE_BUFFER_ARB
;
5200 attribs
[nAttribs
++] = WGL_AUX_BUFFERS_ARB
;
5202 for (iPixelFormat
=1; iPixelFormat
<= adapter
->nCfgs
; ++iPixelFormat
)
5204 res
= GL_EXTCALL(wglGetPixelFormatAttribivARB(hdc
, iPixelFormat
, 0, nAttribs
, attribs
, values
));
5209 /* Cache the pixel format */
5210 cfgs
->iPixelFormat
= iPixelFormat
;
5211 cfgs
->redSize
= values
[0];
5212 cfgs
->greenSize
= values
[1];
5213 cfgs
->blueSize
= values
[2];
5214 cfgs
->alphaSize
= values
[3];
5215 cfgs
->colorSize
= values
[4];
5216 cfgs
->depthSize
= values
[5];
5217 cfgs
->stencilSize
= values
[6];
5218 cfgs
->windowDrawable
= values
[7];
5219 cfgs
->iPixelType
= values
[8];
5220 cfgs
->doubleBuffer
= values
[9];
5221 cfgs
->auxBuffers
= values
[10];
5223 cfgs
->numSamples
= 0;
5224 /* Check multisample support */
5225 if (gl_info
->supported
[ARB_MULTISAMPLE
])
5227 int attrib
[2] = {WGL_SAMPLE_BUFFERS_ARB
, WGL_SAMPLES_ARB
};
5229 if(GL_EXTCALL(wglGetPixelFormatAttribivARB(hdc
, iPixelFormat
, 0, 2, attrib
, value
))) {
5230 /* value[0] = WGL_SAMPLE_BUFFERS_ARB which tells whether multisampling is supported.
5231 * value[1] = number of multi sample buffers*/
5233 cfgs
->numSamples
= value
[1];
5237 TRACE("iPixelFormat=%d, iPixelType=%#x, doubleBuffer=%d, RGBA=%d/%d/%d/%d, "
5238 "depth=%d, stencil=%d, samples=%d, windowDrawable=%d\n",
5239 cfgs
->iPixelFormat
, cfgs
->iPixelType
, cfgs
->doubleBuffer
,
5240 cfgs
->redSize
, cfgs
->greenSize
, cfgs
->blueSize
, cfgs
->alphaSize
,
5241 cfgs
->depthSize
, cfgs
->stencilSize
, cfgs
->numSamples
, cfgs
->windowDrawable
);
5247 int nCfgs
= DescribePixelFormat(hdc
, 0, 0, 0);
5248 adapter
->cfgs
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, nCfgs
*sizeof(WineD3D_PixelFormat
));
5249 adapter
->nCfgs
= 0; /* We won't accept all formats e.g. software accelerated ones will be skipped */
5251 cfgs
= adapter
->cfgs
;
5252 for(iPixelFormat
=1; iPixelFormat
<=nCfgs
; iPixelFormat
++)
5254 PIXELFORMATDESCRIPTOR ppfd
;
5256 res
= DescribePixelFormat(hdc
, iPixelFormat
, sizeof(PIXELFORMATDESCRIPTOR
), &ppfd
);
5260 /* We only want HW acceleration using an OpenGL ICD driver.
5261 * PFD_GENERIC_FORMAT = slow opengl 1.1 gdi software rendering
5262 * PFD_GENERIC_ACCELERATED = partial hw acceleration using a MCD driver (e.g. 3dfx minigl)
5264 if(ppfd
.dwFlags
& (PFD_GENERIC_FORMAT
| PFD_GENERIC_ACCELERATED
))
5266 TRACE("Skipping iPixelFormat=%d because it isn't ICD accelerated\n", iPixelFormat
);
5270 cfgs
->iPixelFormat
= iPixelFormat
;
5271 cfgs
->redSize
= ppfd
.cRedBits
;
5272 cfgs
->greenSize
= ppfd
.cGreenBits
;
5273 cfgs
->blueSize
= ppfd
.cBlueBits
;
5274 cfgs
->alphaSize
= ppfd
.cAlphaBits
;
5275 cfgs
->colorSize
= ppfd
.cColorBits
;
5276 cfgs
->depthSize
= ppfd
.cDepthBits
;
5277 cfgs
->stencilSize
= ppfd
.cStencilBits
;
5278 cfgs
->windowDrawable
= (ppfd
.dwFlags
& PFD_DRAW_TO_WINDOW
) ? 1 : 0;
5279 cfgs
->iPixelType
= (ppfd
.iPixelType
== PFD_TYPE_RGBA
) ? WGL_TYPE_RGBA_ARB
: WGL_TYPE_COLORINDEX_ARB
;
5280 cfgs
->doubleBuffer
= (ppfd
.dwFlags
& PFD_DOUBLEBUFFER
) ? 1 : 0;
5281 cfgs
->auxBuffers
= ppfd
.cAuxBuffers
;
5282 cfgs
->numSamples
= 0;
5284 TRACE("iPixelFormat=%d, iPixelType=%#x, doubleBuffer=%d, RGBA=%d/%d/%d/%d, "
5285 "depth=%d, stencil=%d, windowDrawable=%d\n",
5286 cfgs
->iPixelFormat
, cfgs
->iPixelType
, cfgs
->doubleBuffer
,
5287 cfgs
->redSize
, cfgs
->greenSize
, cfgs
->blueSize
, cfgs
->alphaSize
,
5288 cfgs
->depthSize
, cfgs
->stencilSize
, cfgs
->windowDrawable
);
5293 /* Yikes we haven't found any suitable formats. This should only happen in case of GDI software rendering which we can't use anyway as its 3D functionality is very, very limited */
5296 ERR("Disabling Direct3D because no hardware accelerated pixel formats have been found!\n");
5298 WineD3D_ReleaseFakeGLContext(&fake_gl_ctx
);
5299 HeapFree(GetProcessHeap(), 0, adapter
->cfgs
);
5304 /* D16, D24X8 and D24S8 are common depth / depth+stencil formats. All drivers support them though this doesn't
5305 * mean that the format is offered in hardware. For instance Geforce8 cards don't have offer D16 in hardware
5306 * but just fake it using D24(X8?) which is fine. D3D also allows that.
5307 * Some display drivers (i915 on Linux) only report mixed depth+stencil formats like D24S8. MSDN clearly mentions
5308 * that only on lockable formats (e.g. D16_locked) the bit order is guaranteed and that on other formats the
5309 * driver is allowed to consume more bits EXCEPT for stencil bits.
5311 * Mark an adapter with this broken stencil behavior.
5313 adapter
->brokenStencil
= TRUE
;
5314 for (i
= 0, cfgs
= adapter
->cfgs
; i
< adapter
->nCfgs
; ++i
)
5316 /* Nearly all drivers offer depth formats without stencil, only on i915 this if-statement won't be entered. */
5317 if(cfgs
[i
].depthSize
&& !cfgs
[i
].stencilSize
) {
5318 adapter
->brokenStencil
= FALSE
;
5323 WineD3D_ReleaseFakeGLContext(&fake_gl_ctx
);
5325 select_shader_mode(&adapter
->gl_info
, &ps_selected_mode
, &vs_selected_mode
);
5326 fillGLAttribFuncs(&adapter
->gl_info
);
5327 adapter
->opengl
= TRUE
;
5329 This
->adapter_count
= 1;
5330 TRACE("%u adapters successfully initialized\n", This
->adapter_count
);
5335 /* Initialize an adapter for ddraw-only memory counting */
5336 memset(This
->adapters
, 0, sizeof(This
->adapters
));
5337 This
->adapters
[0].ordinal
= 0;
5338 This
->adapters
[0].opengl
= FALSE
;
5339 This
->adapters
[0].monitorPoint
.x
= -1;
5340 This
->adapters
[0].monitorPoint
.y
= -1;
5342 This
->adapters
[0].driver_info
.name
= "Display";
5343 This
->adapters
[0].driver_info
.description
= "WineD3D DirectDraw Emulation";
5344 if(wined3d_settings
.emulated_textureram
) {
5345 This
->adapters
[0].TextureRam
= wined3d_settings
.emulated_textureram
;
5347 This
->adapters
[0].TextureRam
= 8 * 1024 * 1024; /* This is plenty for a DDraw-only card */
5350 initPixelFormatsNoGL(&This
->adapters
[0].gl_info
);
5352 This
->adapter_count
= 1;
5356 /**********************************************************
5357 * IWineD3D VTbl follows
5358 **********************************************************/
5360 static const struct IWineD3DVtbl IWineD3D_Vtbl
=
5363 IWineD3DImpl_QueryInterface
,
5364 IWineD3DImpl_AddRef
,
5365 IWineD3DImpl_Release
,
5367 IWineD3DImpl_GetParent
,
5368 IWineD3DImpl_GetAdapterCount
,
5369 IWineD3DImpl_RegisterSoftwareDevice
,
5370 IWineD3DImpl_GetAdapterMonitor
,
5371 IWineD3DImpl_GetAdapterModeCount
,
5372 IWineD3DImpl_EnumAdapterModes
,
5373 IWineD3DImpl_GetAdapterDisplayMode
,
5374 IWineD3DImpl_GetAdapterIdentifier
,
5375 IWineD3DImpl_CheckDeviceMultiSampleType
,
5376 IWineD3DImpl_CheckDepthStencilMatch
,
5377 IWineD3DImpl_CheckDeviceType
,
5378 IWineD3DImpl_CheckDeviceFormat
,
5379 IWineD3DImpl_CheckDeviceFormatConversion
,
5380 IWineD3DImpl_GetDeviceCaps
,
5381 IWineD3DImpl_CreateDevice
5384 static void STDMETHODCALLTYPE
wined3d_null_wined3d_object_destroyed(void *parent
) {}
5386 const struct wined3d_parent_ops wined3d_null_parent_ops
=
5388 wined3d_null_wined3d_object_destroyed
,
5391 HRESULT
wined3d_init(IWineD3DImpl
*wined3d
, UINT version
, IUnknown
*parent
)
5393 wined3d
->lpVtbl
= &IWineD3D_Vtbl
;
5394 wined3d
->dxVersion
= version
;
5396 wined3d
->parent
= parent
;
5398 if (!InitAdapters(wined3d
))
5400 WARN("Failed to initialize adapters.\n");
5403 MESSAGE("Direct3D%u is not available without OpenGL.\n", version
);