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
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
24 /* Compile time diagnostics: */
26 /* Uncomment this to force only a single display mode to be exposed: */
27 /*#define DEBUG_SINGLE_MODE*/
32 #include "wined3d_private.h"
34 WINE_DEFAULT_DEBUG_CHANNEL(d3d
);
35 WINE_DECLARE_DEBUG_CHANNEL(d3d_caps
);
36 #define GLINFO_LOCATION This->gl_info
38 /**********************************************************
39 * Utility functions follow
40 **********************************************************/
42 /* x11drv GDI escapes */
43 #define X11DRV_ESCAPE 6789
44 enum x11drv_escape_codes
46 X11DRV_GET_DISPLAY
, /* get X11 display for a DC */
47 X11DRV_GET_DRAWABLE
, /* get current drawable for a DC */
48 X11DRV_GET_FONT
, /* get current X font for a DC */
51 /* retrieve the X display to use on a given DC */
52 inline static Display
*get_display( HDC hdc
)
55 enum x11drv_escape_codes escape
= X11DRV_GET_DISPLAY
;
57 if (!ExtEscape( hdc
, X11DRV_ESCAPE
, sizeof(escape
), (LPCSTR
)&escape
,
58 sizeof(display
), (LPSTR
)&display
)) display
= NULL
;
63 int minLookup
[MAX_LOOKUPS
];
64 int maxLookup
[MAX_LOOKUPS
];
65 DWORD
*stateLookup
[MAX_LOOKUPS
];
67 DWORD minMipLookup
[WINED3DTEXF_ANISOTROPIC
+ 1][WINED3DTEXF_LINEAR
+ 1];
71 * Note: GL seems to trap if GetDeviceCaps is called before any HWND's created
72 * ie there is no GL Context - Get a default rendering context to enable the
73 * function query some info from GL
76 static int wined3d_fake_gl_context_ref
= 0;
77 static BOOL wined3d_fake_gl_context_foreign
;
78 static BOOL wined3d_fake_gl_context_available
= FALSE
;
79 static Display
* wined3d_fake_gl_context_display
= NULL
;
81 static void WineD3D_ReleaseFakeGLContext(void) {
84 if(!wined3d_fake_gl_context_available
) {
85 TRACE_(d3d_caps
)("context not available\n");
89 glCtx
= glXGetCurrentContext();
91 TRACE_(d3d_caps
)("decrementing ref from %i\n", wined3d_fake_gl_context_ref
);
92 if (0 == (--wined3d_fake_gl_context_ref
) ) {
93 if(!wined3d_fake_gl_context_foreign
&& glCtx
) {
94 TRACE_(d3d_caps
)("destroying fake GL context\n");
95 glXMakeCurrent(wined3d_fake_gl_context_display
, None
, NULL
);
96 glXDestroyContext(wined3d_fake_gl_context_display
, glCtx
);
99 wined3d_fake_gl_context_available
= FALSE
;
101 assert(wined3d_fake_gl_context_ref
>= 0);
105 static BOOL
WineD3D_CreateFakeGLContext(void) {
106 XVisualInfo
* visInfo
;
109 TRACE_(d3d_caps
)("getting context...\n");
110 if(wined3d_fake_gl_context_ref
> 0) goto ret
;
111 assert(0 == wined3d_fake_gl_context_ref
);
113 wined3d_fake_gl_context_foreign
= TRUE
;
115 if(!wined3d_fake_gl_context_display
) {
116 HDC device_context
= GetDC(0);
118 wined3d_fake_gl_context_display
= get_display(device_context
);
119 ReleaseDC(0, device_context
);
125 glCtx
= glXGetCurrentContext();
129 XVisualInfo
template;
132 XWindowAttributes win_attr
;
134 wined3d_fake_gl_context_foreign
= FALSE
;
135 drawable
= (Drawable
) GetPropA(GetDesktopWindow(), "__wine_x11_whole_window");
137 TRACE_(d3d_caps
)("Creating Fake GL Context\n");
139 /* Get the X visual */
140 if (XGetWindowAttributes(wined3d_fake_gl_context_display
, drawable
, &win_attr
)) {
141 visual
= win_attr
.visual
;
143 visual
= DefaultVisual(wined3d_fake_gl_context_display
, DefaultScreen(wined3d_fake_gl_context_display
));
145 template.visualid
= XVisualIDFromVisual(visual
);
146 visInfo
= XGetVisualInfo(wined3d_fake_gl_context_display
, VisualIDMask
, &template, &num
);
148 WARN_(d3d_caps
)("Error creating visual info for capabilities initialization\n");
152 /* Create a GL context */
153 glCtx
= glXCreateContext(wined3d_fake_gl_context_display
, visInfo
, NULL
, GL_TRUE
);
155 WARN_(d3d_caps
)("Error creating default context for capabilities initialization\n");
159 /* Make it the current GL context */
160 if (!glXMakeCurrent(wined3d_fake_gl_context_display
, drawable
, glCtx
)) {
161 WARN_(d3d_caps
)("Error setting default context as current for capabilities initialization\n");
170 TRACE_(d3d_caps
)("incrementing ref from %i\n", wined3d_fake_gl_context_ref
);
171 wined3d_fake_gl_context_ref
++;
172 wined3d_fake_gl_context_available
= TRUE
;
175 if(visInfo
) XFree(visInfo
);
176 if(glCtx
) glXDestroyContext(wined3d_fake_gl_context_display
, glCtx
);
181 /**********************************************************
182 * IUnknown parts follows
183 **********************************************************/
185 static HRESULT WINAPI
IWineD3DImpl_QueryInterface(IWineD3D
*iface
,REFIID riid
,LPVOID
*ppobj
)
187 IWineD3DDeviceImpl
*This
= (IWineD3DDeviceImpl
*)iface
;
189 TRACE("(%p)->(%s,%p)\n",This
,debugstr_guid(riid
),ppobj
);
190 if (IsEqualGUID(riid
, &IID_IUnknown
)
191 || IsEqualGUID(riid
, &IID_IWineD3DBase
)
192 || IsEqualGUID(riid
, &IID_IWineD3DDevice
)) {
193 IUnknown_AddRef(iface
);
198 return E_NOINTERFACE
;
201 static ULONG WINAPI
IWineD3DImpl_AddRef(IWineD3D
*iface
) {
202 IWineD3DImpl
*This
= (IWineD3DImpl
*)iface
;
203 ULONG refCount
= InterlockedIncrement(&This
->ref
);
205 TRACE("(%p) : AddRef increasing from %d\n", This
, refCount
- 1);
209 static ULONG WINAPI
IWineD3DImpl_Release(IWineD3D
*iface
) {
210 IWineD3DImpl
*This
= (IWineD3DImpl
*)iface
;
212 TRACE("(%p) : Releasing from %d\n", This
, This
->ref
);
213 ref
= InterlockedDecrement(&This
->ref
);
215 HeapFree(GetProcessHeap(), 0, This
);
221 /* Set the shader type for this device, depending on the given capabilities,
222 * the device type, and the user preferences in wined3d_settings */
224 static void select_shader_mode(
225 WineD3D_GL_Info
*gl_info
,
226 WINED3DDEVTYPE DeviceType
,
230 /* Give priority to user disable/emulation request.
231 * Then respect REF device for software.
232 * Then check capabilities for hardware, and fallback to software */
234 if (wined3d_settings
.vs_mode
== VS_NONE
) {
235 *vs_selected
= SHADER_NONE
;
236 } else if (DeviceType
== WINED3DDEVTYPE_REF
|| wined3d_settings
.vs_mode
== VS_SW
) {
237 *vs_selected
= SHADER_SW
;
238 } else if (gl_info
->supported
[ARB_VERTEX_SHADER
] && wined3d_settings
.glslRequested
) {
239 *vs_selected
= SHADER_GLSL
;
240 } else if (gl_info
->supported
[ARB_VERTEX_PROGRAM
]) {
241 *vs_selected
= SHADER_ARB
;
243 *vs_selected
= SHADER_SW
;
246 /* Fallback to SHADER_NONE where software pixel shaders should be used */
247 if (wined3d_settings
.ps_mode
== PS_NONE
) {
248 *ps_selected
= SHADER_NONE
;
249 } else if (DeviceType
== WINED3DDEVTYPE_REF
) {
250 *ps_selected
= SHADER_NONE
;
251 } else if (gl_info
->supported
[ARB_FRAGMENT_SHADER
] && wined3d_settings
.glslRequested
) {
252 *ps_selected
= SHADER_GLSL
;
253 } else if (gl_info
->supported
[ARB_FRAGMENT_PROGRAM
]) {
254 *ps_selected
= SHADER_ARB
;
256 *ps_selected
= SHADER_NONE
;
260 /** Select the number of report maximum shader constants based on the selected shader modes */
261 void select_shader_max_constants(
262 int ps_selected_mode
,
263 int vs_selected_mode
,
264 WineD3D_GL_Info
*gl_info
) {
266 switch (vs_selected_mode
) {
268 /* Subtract the other potential uniforms from the max available (bools, ints, and 1 row of projection matrix) */
269 gl_info
->max_vshader_constantsF
= gl_info
->vs_glsl_constantsF
- MAX_CONST_B
- MAX_CONST_I
- 1;
272 /* We have to subtract any other PARAMs that we might use in our shader programs.
273 * ATI seems to count 2 implicit PARAMs when we use fog and NVIDIA counts 1,
274 * and we reference one row of the PROJECTION matrix which counts as 1 PARAM. */
275 gl_info
->max_vshader_constantsF
= gl_info
->vs_arb_constantsF
- 3;
278 gl_info
->max_vshader_constantsF
= 96; /* TODO: Fixup software shaders */
281 gl_info
->max_vshader_constantsF
= 0;
285 switch (ps_selected_mode
) {
287 /* Subtract the other potential uniforms from the max available (bools & ints) */
288 gl_info
->max_pshader_constantsF
= gl_info
->ps_glsl_constantsF
- MAX_CONST_B
- MAX_CONST_I
;
291 gl_info
->max_pshader_constantsF
= gl_info
->ps_arb_constantsF
;
294 gl_info
->max_pshader_constantsF
= 96; /* TODO: Fixup software shaders */
297 gl_info
->max_pshader_constantsF
= 0;
302 /**********************************************************
303 * IWineD3D parts follows
304 **********************************************************/
306 BOOL
IWineD3DImpl_FillGLCaps(IWineD3D
*iface
, Display
* display
) {
307 IWineD3DImpl
*This
= (IWineD3DImpl
*)iface
;
308 WineD3D_GL_Info
*gl_info
= &This
->gl_info
;
310 const char *GL_Extensions
= NULL
;
311 const char *GLX_Extensions
= NULL
;
312 const char *gl_string
= NULL
;
313 const char *gl_string_cursor
= NULL
;
315 GLfloat gl_floatv
[2];
318 BOOL return_value
= TRUE
;
321 /* Make sure that we've got a context */
322 /* TODO: CreateFakeGLContext should really take a display as a parameter */
323 /* Only save the values obtained when a display is provided */
324 if (!WineD3D_CreateFakeGLContext() || wined3d_fake_gl_context_foreign
)
325 return_value
= FALSE
;
327 TRACE_(d3d_caps
)("(%p, %p)\n", gl_info
, display
);
329 gl_string
= (const char *) glGetString(GL_RENDERER
);
330 if (NULL
== gl_string
)
332 strcpy(gl_info
->gl_renderer
, gl_string
);
334 /* Fill in the GL info retrievable depending on the display */
335 if (NULL
!= display
) {
336 test
= glXQueryVersion(display
, &major
, &minor
);
337 gl_info
->glx_version
= ((major
& 0x0000FFFF) << 16) | (minor
& 0x0000FFFF);
339 FIXME("Display must not be NULL, use glXGetCurrentDisplay or getAdapterDisplay()\n");
341 gl_string
= (const char *) glGetString(GL_VENDOR
);
343 TRACE_(d3d_caps
)("Filling vendor string %s\n", gl_string
);
344 if (gl_string
!= NULL
) {
345 /* Fill in the GL vendor */
346 if (strstr(gl_string
, "NVIDIA")) {
347 gl_info
->gl_vendor
= VENDOR_NVIDIA
;
348 } else if (strstr(gl_string
, "ATI")) {
349 gl_info
->gl_vendor
= VENDOR_ATI
;
350 } else if (strstr(gl_string
, "Intel(R)") ||
351 strstr(gl_info
->gl_renderer
, "Intel(R)")) {
352 gl_info
->gl_vendor
= VENDOR_INTEL
;
353 } else if (strstr(gl_string
, "Mesa")) {
354 gl_info
->gl_vendor
= VENDOR_MESA
;
356 gl_info
->gl_vendor
= VENDOR_WINE
;
359 gl_info
->gl_vendor
= VENDOR_WINE
;
363 TRACE_(d3d_caps
)("found GL_VENDOR (%s)->(0x%04x)\n", debugstr_a(gl_string
), gl_info
->gl_vendor
);
365 /* Parse the GL_VERSION field into major and minor information */
366 gl_string
= (const char *) glGetString(GL_VERSION
);
367 if (gl_string
!= NULL
) {
369 switch (gl_info
->gl_vendor
) {
371 gl_string_cursor
= strstr(gl_string
, "NVIDIA");
372 if (!gl_string_cursor
) {
373 ERR_(d3d_caps
)("Invalid nVidia version string: %s\n", debugstr_a(gl_string
));
377 gl_string_cursor
= strstr(gl_string_cursor
, " ");
378 if (!gl_string_cursor
) {
379 ERR_(d3d_caps
)("Invalid nVidia version string: %s\n", debugstr_a(gl_string
));
383 while (*gl_string_cursor
== ' ') {
387 if (!*gl_string_cursor
) {
388 ERR_(d3d_caps
)("Invalid nVidia version string: %s\n", debugstr_a(gl_string
));
392 major
= atoi(gl_string_cursor
);
393 while (*gl_string_cursor
<= '9' && *gl_string_cursor
>= '0') {
397 if (*gl_string_cursor
++ != '.') {
398 ERR_(d3d_caps
)("Invalid nVidia version string: %s\n", debugstr_a(gl_string
));
402 minor
= atoi(gl_string_cursor
);
403 minor
= major
*100+minor
;
410 gl_string_cursor
= strchr(gl_string
, '-');
411 if (gl_string_cursor
) {
415 /* Check if version number is of the form x.y.z */
416 if (*gl_string_cursor
> '9' && *gl_string_cursor
< '0')
418 if (!error
&& *(gl_string_cursor
+2) > '9' && *(gl_string_cursor
+2) < '0')
420 if (!error
&& *(gl_string_cursor
+4) > '9' && *(gl_string_cursor
+4) < '0')
422 if (!error
&& *(gl_string_cursor
+1) != '.' && *(gl_string_cursor
+3) != '.')
425 /* Mark version number as malformed */
427 gl_string_cursor
= 0;
430 if (!gl_string_cursor
)
431 WARN_(d3d_caps
)("malformed GL_VERSION (%s)\n", debugstr_a(gl_string
));
433 major
= *gl_string_cursor
- '0';
434 minor
= (*(gl_string_cursor
+2) - '0') * 256 + (*(gl_string_cursor
+4) - '0');
440 gl_string_cursor
= strstr(gl_string
, "Mesa");
441 gl_string_cursor
= strstr(gl_string_cursor
, " ");
442 while (*gl_string_cursor
&& ' ' == *gl_string_cursor
) ++gl_string_cursor
;
443 if (*gl_string_cursor
) {
447 while (*gl_string_cursor
<= '9' && *gl_string_cursor
>= '0') {
448 tmp
[cursor
++] = *gl_string_cursor
;
454 if (*gl_string_cursor
!= '.') WARN_(d3d_caps
)("malformed GL_VERSION (%s)\n", debugstr_a(gl_string
));
458 while (*gl_string_cursor
<= '9' && *gl_string_cursor
>= '0') {
459 tmp
[cursor
++] = *gl_string_cursor
;
471 gl_info
->gl_driver_version
= MAKEDWORD_VERSION(major
, minor
);
472 TRACE_(d3d_caps
)("found GL_VERSION (%s)->%i.%i->(0x%08x)\n", debugstr_a(gl_string
), major
, minor
, gl_info
->gl_driver_version
);
475 TRACE_(d3d_caps
)("found GL_RENDERER (%s)->(0x%04x)\n", debugstr_a(gl_info
->gl_renderer
), gl_info
->gl_card
);
478 * Initialize openGL extension related variables
479 * with Default values
481 memset(&gl_info
->supported
, 0, sizeof(gl_info
->supported
));
482 gl_info
->max_buffers
= 1;
483 gl_info
->max_textures
= 1;
484 gl_info
->max_texture_stages
= 1;
485 gl_info
->max_samplers
= 1;
486 gl_info
->max_sampler_stages
= 1;
487 gl_info
->ps_arb_version
= PS_VERSION_NOT_SUPPORTED
;
488 gl_info
->ps_arb_max_temps
= 0;
489 gl_info
->ps_arb_max_instructions
= 0;
490 gl_info
->vs_arb_version
= VS_VERSION_NOT_SUPPORTED
;
491 gl_info
->vs_arb_max_temps
= 0;
492 gl_info
->vs_arb_max_instructions
= 0;
493 gl_info
->vs_nv_version
= VS_VERSION_NOT_SUPPORTED
;
494 gl_info
->vs_ati_version
= VS_VERSION_NOT_SUPPORTED
;
495 gl_info
->vs_glsl_constantsF
= 0;
496 gl_info
->ps_glsl_constantsF
= 0;
497 gl_info
->vs_arb_constantsF
= 0;
498 gl_info
->ps_arb_constantsF
= 0;
500 /* Now work out what GL support this card really has */
501 #define USE_GL_FUNC(type, pfn) gl_info->pfn = (type) glXGetProcAddressARB( (const GLubyte *) #pfn);
506 /* Retrieve opengl defaults */
507 glGetIntegerv(GL_MAX_CLIP_PLANES
, &gl_max
);
508 gl_info
->max_clipplanes
= min(WINED3DMAXUSERCLIPPLANES
, gl_max
);
509 TRACE_(d3d_caps
)("ClipPlanes support - num Planes=%d\n", gl_max
);
511 glGetIntegerv(GL_MAX_LIGHTS
, &gl_max
);
512 gl_info
->max_lights
= gl_max
;
513 TRACE_(d3d_caps
)("Lights support - max lights=%d\n", gl_max
);
515 glGetIntegerv(GL_MAX_TEXTURE_SIZE
, &gl_max
);
516 gl_info
->max_texture_size
= gl_max
;
517 TRACE_(d3d_caps
)("Maximum texture size support - max texture size=%d\n", gl_max
);
519 glGetFloatv(GL_POINT_SIZE_RANGE
, gl_floatv
);
520 gl_info
->max_pointsize
= gl_floatv
[1];
521 TRACE_(d3d_caps
)("Maximum point size support - max point size=%f\n", gl_floatv
[1]);
523 /* Parse the gl supported features, in theory enabling parts of our code appropriately */
524 GL_Extensions
= (const char *) glGetString(GL_EXTENSIONS
);
525 TRACE_(d3d_caps
)("GL_Extensions reported:\n");
527 if (NULL
== GL_Extensions
) {
528 ERR(" GL_Extensions returns NULL\n");
530 while (*GL_Extensions
!= 0x00) {
531 const char *Start
= GL_Extensions
;
534 memset(ThisExtn
, 0x00, sizeof(ThisExtn
));
535 while (*GL_Extensions
!= ' ' && *GL_Extensions
!= 0x00) {
538 memcpy(ThisExtn
, Start
, (GL_Extensions
- Start
));
539 TRACE_(d3d_caps
)("- %s\n", ThisExtn
);
544 if (strcmp(ThisExtn
, "GL_ARB_draw_buffers") == 0) {
545 glGetIntegerv(GL_MAX_DRAW_BUFFERS_ARB
, &gl_max
);
546 TRACE_(d3d_caps
)(" FOUND: ARB_draw_buffers support - max buffers=%u\n", gl_max
);
547 gl_info
->supported
[ARB_DRAW_BUFFERS
] = TRUE
;
548 gl_info
->max_buffers
= gl_max
;
549 } else if (strcmp(ThisExtn
, "GL_ARB_fragment_program") == 0) {
550 gl_info
->ps_arb_version
= PS_VERSION_11
;
551 TRACE_(d3d_caps
)(" FOUND: ARB Pixel Shader support - version=%02x\n", gl_info
->ps_arb_version
);
552 gl_info
->supported
[ARB_FRAGMENT_PROGRAM
] = TRUE
;
553 glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS_ARB
, &gl_max
);
554 TRACE_(d3d_caps
)(" FOUND: ARB Pixel Shader support - GL_MAX_TEXTURE_IMAGE_UNITS_ARB=%u\n", gl_max
);
555 gl_info
->max_samplers
= min(MAX_SAMPLERS
, gl_max
);
556 GL_EXTCALL(glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB
, GL_MAX_PROGRAM_ENV_PARAMETERS_ARB
, &gl_max
));
557 TRACE_(d3d_caps
)(" FOUND: ARB Pixel Shader support - max float constants=%u\n", gl_max
);
558 gl_info
->ps_arb_constantsF
= gl_max
;
559 GL_EXTCALL(glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB
, GL_MAX_PROGRAM_TEMPORARIES_ARB
, &gl_max
));
560 TRACE_(d3d_caps
)(" FOUND: ARB Pixel Shader support - max temporaries=%u\n", gl_max
);
561 gl_info
->ps_arb_max_temps
= gl_max
;
562 GL_EXTCALL(glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB
, GL_MAX_PROGRAM_INSTRUCTIONS_ARB
, &gl_max
));
563 TRACE_(d3d_caps
)(" FOUND: ARB Pixel Shader support - max instructions=%u\n", gl_max
);
564 gl_info
->ps_arb_max_instructions
= gl_max
;
565 } else if (strcmp(ThisExtn
, "GL_ARB_fragment_shader") == 0) {
566 gl_info
->supported
[ARB_FRAGMENT_SHADER
] = TRUE
;
567 glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB
, &gl_max
);
569 TRACE_(d3d_caps
)(" FOUND: ARB_fragment_shader (GLSL) support - max float ps constants=%u\n", gl_max
);
570 gl_info
->ps_glsl_constantsF
= gl_max
;
571 } else if (strcmp(ThisExtn
, "GL_ARB_imaging") == 0) {
572 TRACE_(d3d_caps
)(" FOUND: ARB imaging support\n");
573 gl_info
->supported
[ARB_IMAGING
] = TRUE
;
574 } else if (strcmp(ThisExtn
, "GL_ARB_multisample") == 0) {
575 TRACE_(d3d_caps
)(" FOUND: ARB Multisample support\n");
576 gl_info
->supported
[ARB_MULTISAMPLE
] = TRUE
;
577 } else if (strcmp(ThisExtn
, "GL_ARB_multitexture") == 0) {
578 glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB
, &gl_max
);
579 TRACE_(d3d_caps
)(" FOUND: ARB Multitexture support - GL_MAX_TEXTURE_UNITS_ARB=%u\n", gl_max
);
580 gl_info
->supported
[ARB_MULTITEXTURE
] = TRUE
;
581 gl_info
->max_textures
= min(MAX_TEXTURES
, gl_max
);
582 gl_info
->max_texture_stages
= min(MAX_TEXTURES
, gl_max
);
583 gl_info
->max_samplers
= max(gl_info
->max_samplers
, gl_max
);
584 } else if (strcmp(ThisExtn
, "GL_ARB_texture_cube_map") == 0) {
585 TRACE_(d3d_caps
)(" FOUND: ARB Texture Cube Map support\n");
586 gl_info
->supported
[ARB_TEXTURE_CUBE_MAP
] = TRUE
;
587 TRACE_(d3d_caps
)(" IMPLIED: NVIDIA (NV) Texture Gen Reflection support\n");
588 gl_info
->supported
[NV_TEXGEN_REFLECTION
] = TRUE
;
589 } else if (strcmp(ThisExtn
, "GL_ARB_texture_compression") == 0) {
590 TRACE_(d3d_caps
)(" FOUND: ARB Texture Compression support\n");
591 gl_info
->supported
[ARB_TEXTURE_COMPRESSION
] = TRUE
;
592 } else if (strcmp(ThisExtn
, "GL_ARB_texture_env_add") == 0) {
593 TRACE_(d3d_caps
)(" FOUND: ARB Texture Env Add support\n");
594 gl_info
->supported
[ARB_TEXTURE_ENV_ADD
] = TRUE
;
595 } else if (strcmp(ThisExtn
, "GL_ARB_texture_env_combine") == 0) {
596 TRACE_(d3d_caps
)(" FOUND: ARB Texture Env combine support\n");
597 gl_info
->supported
[ARB_TEXTURE_ENV_COMBINE
] = TRUE
;
598 } else if (strcmp(ThisExtn
, "GL_ARB_texture_env_dot3") == 0) {
599 TRACE_(d3d_caps
)(" FOUND: ARB Dot3 support\n");
600 gl_info
->supported
[ARB_TEXTURE_ENV_DOT3
] = TRUE
;
601 } else if (strcmp(ThisExtn
, "GL_ARB_texture_float") == 0) {
602 TRACE_(d3d_caps
)(" FOUND: ARB Float texture support\n");
603 gl_info
->supported
[ARB_TEXTURE_FLOAT
] = TRUE
;
604 } else if (strcmp(ThisExtn
, "GL_ARB_half_float_pixel") == 0) {
605 TRACE_(d3d_caps
)(" FOUND: ARB Half-float pixel support\n");
606 gl_info
->supported
[ARB_HALF_FLOAT_PIXEL
] = TRUE
;
607 } else if (strcmp(ThisExtn
, "GL_ARB_texture_border_clamp") == 0) {
608 TRACE_(d3d_caps
)(" FOUND: ARB Texture border clamp support\n");
609 gl_info
->supported
[ARB_TEXTURE_BORDER_CLAMP
] = TRUE
;
610 } else if (strcmp(ThisExtn
, "GL_ARB_texture_mirrored_repeat") == 0) {
611 TRACE_(d3d_caps
)(" FOUND: ARB Texture mirrored repeat support\n");
612 gl_info
->supported
[ARB_TEXTURE_MIRRORED_REPEAT
] = TRUE
;
613 } else if (strcmp(ThisExtn
, "GL_ARB_texture_non_power_of_two") == 0) {
614 TRACE_(d3d_caps
)(" FOUND: ARB NPOT texture support\n");
615 gl_info
->supported
[ARB_TEXTURE_NON_POWER_OF_TWO
] = TRUE
;
616 } else if (strcmp(ThisExtn
, "GLX_ARB_multisample") == 0) {
617 TRACE_(d3d_caps
)(" FOUND: ARB multisample support\n");
618 gl_info
->supported
[ARB_MULTISAMPLE
] = TRUE
;
619 } else if (strcmp(ThisExtn
, "GL_ARB_pixel_buffer_object") == 0) {
620 TRACE_(d3d_caps
)(" FOUND: ARB Pixel Buffer support\n");
621 gl_info
->supported
[ARB_PIXEL_BUFFER_OBJECT
] = TRUE
;
622 } else if (strcmp(ThisExtn
, "GL_ARB_point_sprite") == 0) {
623 TRACE_(d3d_caps
)(" FOUND: ARB point sprite support\n");
624 gl_info
->supported
[ARB_POINT_SPRITE
] = TRUE
;
625 } else if (strstr(ThisExtn
, "GL_ARB_vertex_program")) {
626 gl_info
->vs_arb_version
= VS_VERSION_11
;
627 TRACE_(d3d_caps
)(" FOUND: ARB Vertex Shader support - version=%02x\n", gl_info
->vs_arb_version
);
628 gl_info
->supported
[ARB_VERTEX_PROGRAM
] = TRUE
;
629 GL_EXTCALL(glGetProgramivARB(GL_VERTEX_PROGRAM_ARB
, GL_MAX_PROGRAM_ENV_PARAMETERS_ARB
, &gl_max
));
630 TRACE_(d3d_caps
)(" FOUND: ARB Vertex Shader support - max float constants=%u\n", gl_max
);
631 gl_info
->vs_arb_constantsF
= gl_max
;
632 GL_EXTCALL(glGetProgramivARB(GL_VERTEX_PROGRAM_ARB
, GL_MAX_PROGRAM_TEMPORARIES_ARB
, &gl_max
));
633 TRACE_(d3d_caps
)(" FOUND: ARB Vertex Shader support - max temporaries=%u\n", gl_max
);
634 gl_info
->vs_arb_max_temps
= gl_max
;
635 GL_EXTCALL(glGetProgramivARB(GL_VERTEX_PROGRAM_ARB
, GL_MAX_PROGRAM_INSTRUCTIONS_ARB
, &gl_max
));
636 TRACE_(d3d_caps
)(" FOUND: ARB Vertex Shader support - max instructions=%u\n", gl_max
);
637 gl_info
->vs_arb_max_instructions
= gl_max
;
638 } else if (strcmp(ThisExtn
, "GL_ARB_vertex_shader") == 0) {
639 gl_info
->supported
[ARB_VERTEX_SHADER
] = TRUE
;
640 glGetIntegerv(GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB
, &gl_max
);
642 TRACE_(d3d_caps
)(" FOUND: ARB_vertex_shader (GLSL) support - max float vs constants=%u\n", gl_max
);
643 gl_info
->vs_glsl_constantsF
= gl_max
;
644 } else if (strcmp(ThisExtn
, "GL_ARB_vertex_blend") == 0) {
645 glGetIntegerv(GL_MAX_VERTEX_UNITS_ARB
, &gl_max
);
646 TRACE_(d3d_caps
)(" FOUND: ARB Vertex Blend support GL_MAX_VERTEX_UNITS_ARB %d\n", gl_max
);
647 gl_info
->max_blends
= gl_max
;
648 gl_info
->supported
[ARB_VERTEX_BLEND
] = TRUE
;
649 } else if (strcmp(ThisExtn
, "GL_ARB_vertex_buffer_object") == 0) {
650 TRACE_(d3d_caps
)(" FOUND: ARB Vertex Buffer support\n");
651 gl_info
->supported
[ARB_VERTEX_BUFFER_OBJECT
] = TRUE
;
652 } else if (strcmp(ThisExtn
, "GL_ARB_occlusion_query") == 0) {
653 TRACE_(d3d_caps
)(" FOUND: ARB Occlusion Query support\n");
654 gl_info
->supported
[ARB_OCCLUSION_QUERY
] = TRUE
;
655 } else if (strcmp(ThisExtn
, "GL_ARB_point_parameters") == 0) {
656 TRACE_(d3d_caps
)(" FOUND: ARB Point parameters support\n");
657 gl_info
->supported
[ARB_POINT_PARAMETERS
] = TRUE
;
661 } else if (strcmp(ThisExtn
, "GL_EXT_fog_coord") == 0) {
662 TRACE_(d3d_caps
)(" FOUND: EXT Fog coord support\n");
663 gl_info
->supported
[EXT_FOG_COORD
] = TRUE
;
664 } else if (strcmp(ThisExtn
, "GL_EXT_framebuffer_object") == 0) {
665 TRACE_(d3d_caps
)(" FOUND: EXT Frame Buffer Object support\n");
666 gl_info
->supported
[EXT_FRAMEBUFFER_OBJECT
] = TRUE
;
667 } else if (strcmp(ThisExtn
, "GL_EXT_blend_minmax") == 0) {
668 TRACE_(d3d_caps
)(" FOUND: EXT Blend minmax support\n");
669 gl_info
->supported
[EXT_BLEND_MINMAX
] = TRUE
;
670 } else if (strcmp(ThisExtn
, "GL_EXT_paletted_texture") == 0) { /* handle paletted texture extensions */
671 TRACE_(d3d_caps
)(" FOUND: EXT Paletted texture support\n");
672 gl_info
->supported
[EXT_PALETTED_TEXTURE
] = TRUE
;
673 } else if (strcmp(ThisExtn
, "GL_EXT_point_parameters") == 0) {
674 TRACE_(d3d_caps
)(" FOUND: EXT Point parameters support\n");
675 gl_info
->supported
[EXT_POINT_PARAMETERS
] = TRUE
;
676 } else if (strcmp(ThisExtn
, "GL_EXT_secondary_color") == 0) {
677 TRACE_(d3d_caps
)(" FOUND: EXT Secondary coord support\n");
678 gl_info
->supported
[EXT_SECONDARY_COLOR
] = TRUE
;
679 } else if (strcmp(ThisExtn
, "GL_EXT_stencil_two_side") == 0) {
680 TRACE_(d3d_caps
)(" FOUND: EXT Stencil two side support\n");
681 gl_info
->supported
[EXT_STENCIL_TWO_SIDE
] = TRUE
;
682 } else if (strcmp(ThisExtn
, "GL_EXT_stencil_wrap") == 0) {
683 TRACE_(d3d_caps
)(" FOUND: EXT Stencil wrap support\n");
684 gl_info
->supported
[EXT_STENCIL_WRAP
] = TRUE
;
685 } else if (strcmp(ThisExtn
, "GL_EXT_texture3D") == 0) {
686 TRACE_(d3d_caps
)(" FOUND: EXT_texture3D support\n");
687 gl_info
->supported
[EXT_TEXTURE3D
] = TRUE
;
688 glGetIntegerv(GL_MAX_3D_TEXTURE_SIZE_EXT
, &gl_max
);
689 TRACE_(d3d_caps
)("Max texture3D size: %d\n", gl_max
);
690 gl_info
->max_texture3d_size
= gl_max
;
691 } else if (strcmp(ThisExtn
, "GL_EXT_texture_compression_s3tc") == 0) {
692 TRACE_(d3d_caps
)(" FOUND: EXT Texture S3TC compression support\n");
693 gl_info
->supported
[EXT_TEXTURE_COMPRESSION_S3TC
] = TRUE
;
694 } else if (strcmp(ThisExtn
, "GL_EXT_texture_env_add") == 0) {
695 TRACE_(d3d_caps
)(" FOUND: EXT Texture Env Add support\n");
696 gl_info
->supported
[EXT_TEXTURE_ENV_ADD
] = TRUE
;
697 } else if (strcmp(ThisExtn
, "GL_EXT_texture_env_combine") == 0) {
698 TRACE_(d3d_caps
)(" FOUND: EXT Texture Env combine support\n");
699 gl_info
->supported
[EXT_TEXTURE_ENV_COMBINE
] = TRUE
;
700 } else if (strcmp(ThisExtn
, "GL_EXT_texture_env_dot3") == 0) {
701 TRACE_(d3d_caps
)(" FOUND: EXT Dot3 support\n");
702 gl_info
->supported
[EXT_TEXTURE_ENV_DOT3
] = TRUE
;
703 } else if (strcmp(ThisExtn
, "GL_EXT_texture_filter_anisotropic") == 0) {
704 gl_info
->supported
[EXT_TEXTURE_FILTER_ANISOTROPIC
] = TRUE
;
705 glGetIntegerv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT
, &gl_max
);
706 TRACE_(d3d_caps
)(" FOUND: EXT Texture Anisotropic filter support. GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT %d\n", gl_max
);
707 gl_info
->max_anisotropy
= gl_max
;
708 } else if (strcmp(ThisExtn
, "GL_EXT_texture_lod") == 0) {
709 TRACE_(d3d_caps
)(" FOUND: EXT Texture LOD support\n");
710 gl_info
->supported
[EXT_TEXTURE_LOD
] = TRUE
;
711 } else if (strcmp(ThisExtn
, "GL_EXT_texture_lod_bias") == 0) {
712 TRACE_(d3d_caps
)(" FOUND: EXT Texture LOD bias support\n");
713 gl_info
->supported
[EXT_TEXTURE_LOD_BIAS
] = TRUE
;
714 } else if (strcmp(ThisExtn
, "GL_EXT_vertex_weighting") == 0) {
715 TRACE_(d3d_caps
)(" FOUND: EXT Vertex weighting support\n");
716 gl_info
->supported
[EXT_VERTEX_WEIGHTING
] = TRUE
;
721 } else if (strstr(ThisExtn
, "GL_NV_fog_distance")) {
722 TRACE_(d3d_caps
)(" FOUND: NVIDIA (NV) Fog Distance support\n");
723 gl_info
->supported
[NV_FOG_DISTANCE
] = TRUE
;
724 } else if (strstr(ThisExtn
, "GL_NV_fragment_program")) {
725 gl_info
->ps_nv_version
= (strcmp(ThisExtn
, "GL_NV_fragment_program2") == 0) ? PS_VERSION_30
: PS_VERSION_20
;
726 TRACE_(d3d_caps
)(" FOUND: NVIDIA (NV) Pixel Shader support - version=%02x\n", gl_info
->ps_nv_version
);
727 } else if (strcmp(ThisExtn
, "GL_NV_register_combiners") == 0) {
728 glGetIntegerv(GL_MAX_GENERAL_COMBINERS_NV
, &gl_max
);
729 gl_info
->max_texture_stages
= min(MAX_TEXTURES
, gl_max
);
730 TRACE_(d3d_caps
)(" FOUND: NVIDIA (NV) Register combiners (1) support - GL_MAX_GENERAL_COMBINERS_NV=%d\n", gl_max
);
731 gl_info
->supported
[NV_REGISTER_COMBINERS
] = TRUE
;
732 } else if (strcmp(ThisExtn
, "GL_NV_register_combiners2") == 0) {
733 TRACE_(d3d_caps
)(" FOUND: NVIDIA (NV) Register combiners (2) support\n");
734 gl_info
->supported
[NV_REGISTER_COMBINERS2
] = TRUE
;
735 } else if (strcmp(ThisExtn
, "GL_NV_texgen_reflection") == 0) {
736 TRACE_(d3d_caps
)(" FOUND: NVIDIA (NV) Texture Gen Reflection support\n");
737 gl_info
->supported
[NV_TEXGEN_REFLECTION
] = TRUE
;
738 } else if (strcmp(ThisExtn
, "GL_NV_texture_env_combine4") == 0) {
739 TRACE_(d3d_caps
)(" FOUND: NVIDIA (NV) Texture Env combine (4) support\n");
740 gl_info
->supported
[NV_TEXTURE_ENV_COMBINE4
] = TRUE
;
741 } else if (strcmp(ThisExtn
, "GL_NV_texture_shader") == 0) {
742 TRACE_(d3d_caps
)(" FOUND: NVIDIA (NV) Texture Shader (1) support\n");
743 gl_info
->supported
[NV_TEXTURE_SHADER
] = TRUE
;
744 } else if (strcmp(ThisExtn
, "GL_NV_texture_shader2") == 0) {
745 TRACE_(d3d_caps
)(" FOUND: NVIDIA (NV) Texture Shader (2) support\n");
746 gl_info
->supported
[NV_TEXTURE_SHADER2
] = TRUE
;
747 } else if (strcmp(ThisExtn
, "GL_NV_texture_shader3") == 0) {
748 TRACE_(d3d_caps
)(" FOUND: NVIDIA (NV) Texture Shader (3) support\n");
749 gl_info
->supported
[NV_TEXTURE_SHADER3
] = TRUE
;
750 } else if (strcmp(ThisExtn
, "GL_NV_occlusion_query") == 0) {
751 TRACE_(d3d_caps
)(" FOUND: NVIDIA (NV) Occlusion Query (3) support\n");
752 gl_info
->supported
[NV_OCCLUSION_QUERY
] = TRUE
;
753 } else if (strstr(ThisExtn
, "GL_NV_vertex_program")) {
754 if(strcmp(ThisExtn
, "GL_NV_vertex_program3") == 0)
755 gl_info
->vs_nv_version
= VS_VERSION_30
;
756 else if(strcmp(ThisExtn
, "GL_NV_vertex_program2") == 0)
757 gl_info
->vs_nv_version
= VS_VERSION_20
;
758 else if(strcmp(ThisExtn
, "GL_NV_vertex_program1_1") == 0)
759 gl_info
->vs_nv_version
= VS_VERSION_11
;
761 gl_info
->vs_nv_version
= VS_VERSION_10
;
762 TRACE_(d3d_caps
)(" FOUND: NVIDIA (NV) Vertex Shader support - version=%02x\n", gl_info
->vs_nv_version
);
763 gl_info
->supported
[NV_VERTEX_PROGRAM
] = TRUE
;
769 } else if (strcmp(ThisExtn
, "GL_ATI_separate_stencil") == 0) {
770 TRACE_(d3d_caps
)(" FOUND: ATI Separate stencil support\n");
771 gl_info
->supported
[ATI_SEPARATE_STENCIL
] = TRUE
;
772 } else if (strcmp(ThisExtn
, "GL_ATI_texture_env_combine3") == 0) {
773 TRACE_(d3d_caps
)(" FOUND: ATI Texture Env combine (3) support\n");
774 gl_info
->supported
[ATI_TEXTURE_ENV_COMBINE3
] = TRUE
;
775 } else if (strcmp(ThisExtn
, "GL_ATI_texture_mirror_once") == 0) {
776 TRACE_(d3d_caps
)(" FOUND: ATI Texture Mirror Once support\n");
777 gl_info
->supported
[ATI_TEXTURE_MIRROR_ONCE
] = TRUE
;
778 } else if (strcmp(ThisExtn
, "GL_EXT_vertex_shader") == 0) {
779 gl_info
->vs_ati_version
= VS_VERSION_11
;
780 TRACE_(d3d_caps
)(" FOUND: ATI (EXT) Vertex Shader support - version=%02x\n", gl_info
->vs_ati_version
);
781 gl_info
->supported
[EXT_VERTEX_SHADER
] = TRUE
;
785 if (*GL_Extensions
== ' ') GL_Extensions
++;
788 checkGLcall("extension detection\n");
790 /* In some cases the number of texture stages can be larger than the number
791 * of samplers. The GF4 for example can use only 2 samplers (no fragment
792 * shaders), but 8 texture stages (register combiners). */
793 gl_info
->max_sampler_stages
= max(gl_info
->max_samplers
, gl_info
->max_texture_stages
);
795 /* We can only use NP2_NATIVE when the hardware supports it. */
796 if (wined3d_settings
.nonpower2_mode
== NP2_NATIVE
&& !gl_info
->supported
[ARB_TEXTURE_NON_POWER_OF_TWO
]) {
797 WARN_(d3d_caps
)("GL_ARB_texture_non_power_of_two not supported, falling back to NP2_NONE NPOT mode.\n");
798 wined3d_settings
.nonpower2_mode
= NP2_NONE
;
801 /* We can only use ORM_FBO when the hardware supports it. */
802 if (wined3d_settings
.offscreen_rendering_mode
== ORM_FBO
&& !gl_info
->supported
[EXT_FRAMEBUFFER_OBJECT
]) {
803 WARN_(d3d_caps
)("GL_EXT_framebuffer_object not supported, falling back to PBuffer offscreen rendering mode.\n");
804 wined3d_settings
.offscreen_rendering_mode
= ORM_PBUFFER
;
807 /* Below is a list of Nvidia and ATI GPUs. Both vendors have dozens of different GPUs with roughly the same
808 * features. In most cases GPUs from a certain family differ in clockspeeds, the amount of video memory and
809 * in case of the latest videocards in the number of pixel/vertex pipelines.
811 * A Direct3D device object contains the PCI id (vendor + device) of the videocard which is used for
812 * rendering. Various games use this information to get a rough estimation of the features of the card
813 * and some might use it for enabling 3d effects only on certain types of videocards. In some cases
814 * games might even use it to work around bugs which happen on certain videocards/driver combinations.
815 * The problem is that OpenGL only exposes a rendering string containing the name of the videocard and
818 * Various games depend on the PCI id, so somehow we need to provide one. A simple option is to parse
819 * the renderer string and translate this to the right PCI id. This is a lot of work because there are more
820 * than 200 GPUs just for Nvidia. Various cards share the same renderer string, so the amount of code might
821 * be 'small' but there are quite a number of exceptions which would make this a pain to maintain.
822 * Another way would be to query the PCI id from the operating system (assuming this is the videocard which
823 * is used for rendering which is not always the case). This would work but it is not very portable. Second
824 * it would not work well in, let's say, a remote X situation in which the amount of 3d features which can be used
827 * As said most games only use the PCI id to get an indication of the capabilities of the card.
828 * It doesn't really matter if the given id is the correct one if we return the id of a card with
829 * similar 3d features.
831 * The code below checks the OpenGL capabilities of a videocard and matches that to a certain level of
832 * Direct3D functionality. Once a card passes the Direct3D9 check, we know that the card (in case of Nvidia)
833 * is at least a GeforceFX. To give a better estimate we do a basic check on the renderer string but if that
834 * won't pass we return a default card. This way is better than maintaining a full card database as even
835 * without a full database we can return a card with similar features. Second the size of the database
836 * can be made quite small because when you know what type of 3d functionality a card has, you know to which
837 * GPU family the GPU must belong. Because of this you only have to check a small part of the renderer string
838 * to distinguishes between different models from that family.
840 switch (gl_info
->gl_vendor
) {
842 /* Both the GeforceFX, 6xxx and 7xxx series support D3D9. The last two types have more
843 * shader capabilities, so we use the shader capabilities to distinguish between FX and 6xxx/7xxx.
845 if(WINE_D3D9_CAPABLE(gl_info
) && (gl_info
->vs_nv_version
== VS_VERSION_30
)) {
846 if (strstr(gl_info
->gl_renderer
, "7800") ||
847 strstr(gl_info
->gl_renderer
, "7900") ||
848 strstr(gl_info
->gl_renderer
, "7950") ||
849 strstr(gl_info
->gl_renderer
, "Quadro FX 4") ||
850 strstr(gl_info
->gl_renderer
, "Quadro FX 5"))
851 gl_info
->gl_card
= CARD_NVIDIA_GEFORCE_7800GT
;
852 else if(strstr(gl_info
->gl_renderer
, "6800") ||
853 strstr(gl_info
->gl_renderer
, "7600"))
854 gl_info
->gl_card
= CARD_NVIDIA_GEFORCE_6800
;
855 else if(strstr(gl_info
->gl_renderer
, "6600") ||
856 strstr(gl_info
->gl_renderer
, "6610") ||
857 strstr(gl_info
->gl_renderer
, "6700"))
858 gl_info
->gl_card
= CARD_NVIDIA_GEFORCE_6600GT
;
860 gl_info
->gl_card
= CARD_NVIDIA_GEFORCE_6200
; /* Geforce 6100/6150/6200/7300/7400 */
861 } else if(WINE_D3D9_CAPABLE(gl_info
)) {
862 if (strstr(gl_info
->gl_renderer
, "5800") ||
863 strstr(gl_info
->gl_renderer
, "5900") ||
864 strstr(gl_info
->gl_renderer
, "5950") ||
865 strstr(gl_info
->gl_renderer
, "Quadro FX"))
866 gl_info
->gl_card
= CARD_NVIDIA_GEFORCEFX_5800
;
867 else if(strstr(gl_info
->gl_renderer
, "5600") ||
868 strstr(gl_info
->gl_renderer
, "5650") ||
869 strstr(gl_info
->gl_renderer
, "5700") ||
870 strstr(gl_info
->gl_renderer
, "5750"))
871 gl_info
->gl_card
= CARD_NVIDIA_GEFORCEFX_5600
;
873 gl_info
->gl_card
= CARD_NVIDIA_GEFORCEFX_5200
; /* GeforceFX 5100/5200/5250/5300/5500 */
874 } else if(WINE_D3D8_CAPABLE(gl_info
)) {
875 if (strstr(gl_info
->gl_renderer
, "GeForce4 Ti") || strstr(gl_info
->gl_renderer
, "Quadro4"))
876 gl_info
->gl_card
= CARD_NVIDIA_GEFORCE4_TI4200
; /* Geforce4 Ti4200/Ti4400/Ti4600/Ti4800, Quadro4 */
878 gl_info
->gl_card
= CARD_NVIDIA_GEFORCE3
; /* Geforce3 standard/Ti200/Ti500, Quadro DCC */
879 } else if(WINE_D3D7_CAPABLE(gl_info
)) {
880 if (strstr(gl_info
->gl_renderer
, "GeForce4 MX"))
881 gl_info
->gl_card
= CARD_NVIDIA_GEFORCE4_MX
; /* MX420/MX440/MX460/MX4000 */
882 else if(strstr(gl_info
->gl_renderer
, "GeForce2 MX") || strstr(gl_info
->gl_renderer
, "Quadro2 MXR"))
883 gl_info
->gl_card
= CARD_NVIDIA_GEFORCE2_MX
; /* Geforce2 standard/MX100/MX200/MX400, Quadro2 MXR */
884 else if(strstr(gl_info
->gl_renderer
, "GeForce2") || strstr(gl_info
->gl_renderer
, "Quadro2"))
885 gl_info
->gl_card
= CARD_NVIDIA_GEFORCE2
; /* Geforce2 GTS/Pro/Ti/Ultra, Quadro2 */
887 gl_info
->gl_card
= CARD_NVIDIA_GEFORCE
; /* Geforce 256/DDR, Quadro */
889 if (strstr(gl_info
->gl_renderer
, "TNT2"))
890 gl_info
->gl_card
= CARD_NVIDIA_RIVA_TNT2
; /* Riva TNT2 standard/M64/Pro/Ultra */
892 gl_info
->gl_card
= CARD_NVIDIA_RIVA_TNT
; /* Riva TNT, Vanta */
896 if(WINE_D3D9_CAPABLE(gl_info
)) {
898 if (strstr(gl_info
->gl_renderer
, "X1600") ||
899 strstr(gl_info
->gl_renderer
, "X1800") ||
900 strstr(gl_info
->gl_renderer
, "X1900") ||
901 strstr(gl_info
->gl_renderer
, "X1950"))
902 gl_info
->gl_card
= CARD_ATI_RADEON_X1600
;
903 /* Radeon R4xx + X1300/X1400 (lowend R5xx) */
904 else if(strstr(gl_info
->gl_renderer
, "X700") ||
905 strstr(gl_info
->gl_renderer
, "X800") ||
906 strstr(gl_info
->gl_renderer
, "X850") ||
907 strstr(gl_info
->gl_renderer
, "X1300") ||
908 strstr(gl_info
->gl_renderer
, "X1400"))
909 gl_info
->gl_card
= CARD_ATI_RADEON_X700
;
912 gl_info
->gl_card
= CARD_ATI_RADEON_9500
; /* Radeon 9500/9550/9600/9700/9800/X300/X550/X600 */
913 } else if(WINE_D3D8_CAPABLE(gl_info
)) {
914 gl_info
->gl_card
= CARD_ATI_RADEON_8500
; /* Radeon 8500/9000/9100/9200/9300 */
915 } else if(WINE_D3D7_CAPABLE(gl_info
)) {
916 gl_info
->gl_card
= CARD_ATI_RADEON_7200
; /* Radeon 7000/7100/7200/7500 */
918 gl_info
->gl_card
= CARD_ATI_RAGE_128PRO
;
921 if (strstr(gl_info
->gl_renderer
, "915GM")) {
922 gl_info
->gl_card
= CARD_INTEL_I915GM
;
923 } else if (strstr(gl_info
->gl_renderer
, "915G")) {
924 gl_info
->gl_card
= CARD_INTEL_I915G
;
925 } else if (strstr(gl_info
->gl_renderer
, "865G")) {
926 gl_info
->gl_card
= CARD_INTEL_I865G
;
927 } else if (strstr(gl_info
->gl_renderer
, "855G")) {
928 gl_info
->gl_card
= CARD_INTEL_I855G
;
929 } else if (strstr(gl_info
->gl_renderer
, "830G")) {
930 gl_info
->gl_card
= CARD_INTEL_I830G
;
932 gl_info
->gl_card
= CARD_INTEL_I915G
;
938 /* Default to generic Nvidia hardware based on the supported OpenGL extensions. The choice
939 * for Nvidia was because the hardware and drivers they make are of good quality. This makes
940 * them a good generic choice.
942 gl_info
->gl_vendor
= VENDOR_NVIDIA
;
943 if(WINE_D3D9_CAPABLE(gl_info
))
944 gl_info
->gl_card
= CARD_NVIDIA_GEFORCEFX_5600
;
945 else if(WINE_D3D8_CAPABLE(gl_info
))
946 gl_info
->gl_card
= CARD_NVIDIA_GEFORCE3
;
947 else if(WINE_D3D7_CAPABLE(gl_info
))
948 gl_info
->gl_card
= CARD_NVIDIA_GEFORCE
;
949 else if(WINE_D3D6_CAPABLE(gl_info
))
950 gl_info
->gl_card
= CARD_NVIDIA_RIVA_TNT
;
952 gl_info
->gl_card
= CARD_NVIDIA_RIVA_128
;
954 TRACE("FOUND (fake) card: 0x%x (vendor id), 0x%x (device id)\n", gl_info
->gl_vendor
, gl_info
->gl_card
);
956 /* Load all the lookup tables
957 TODO: It may be a good idea to make minLookup and maxLookup const and populate them in wined3d_private.h where they are declared */
958 minLookup
[WINELOOKUP_WARPPARAM
] = WINED3DTADDRESS_WRAP
;
959 maxLookup
[WINELOOKUP_WARPPARAM
] = WINED3DTADDRESS_MIRRORONCE
;
961 minLookup
[WINELOOKUP_MAGFILTER
] = WINED3DTEXF_NONE
;
962 maxLookup
[WINELOOKUP_MAGFILTER
] = WINED3DTEXF_ANISOTROPIC
;
965 for (i
= 0; i
< MAX_LOOKUPS
; i
++) {
966 stateLookup
[i
] = HeapAlloc(GetProcessHeap(), 0, sizeof(*stateLookup
[i
]) * (1 + maxLookup
[i
] - minLookup
[i
]) );
969 stateLookup
[WINELOOKUP_WARPPARAM
][WINED3DTADDRESS_WRAP
- minLookup
[WINELOOKUP_WARPPARAM
]] = GL_REPEAT
;
970 stateLookup
[WINELOOKUP_WARPPARAM
][WINED3DTADDRESS_CLAMP
- minLookup
[WINELOOKUP_WARPPARAM
]] = GL_CLAMP_TO_EDGE
;
971 stateLookup
[WINELOOKUP_WARPPARAM
][WINED3DTADDRESS_BORDER
- minLookup
[WINELOOKUP_WARPPARAM
]] =
972 gl_info
->supported
[ARB_TEXTURE_BORDER_CLAMP
] ? GL_CLAMP_TO_BORDER_ARB
: GL_REPEAT
;
973 stateLookup
[WINELOOKUP_WARPPARAM
][WINED3DTADDRESS_BORDER
- minLookup
[WINELOOKUP_WARPPARAM
]] =
974 gl_info
->supported
[ARB_TEXTURE_BORDER_CLAMP
] ? GL_CLAMP_TO_BORDER_ARB
: GL_REPEAT
;
975 stateLookup
[WINELOOKUP_WARPPARAM
][WINED3DTADDRESS_MIRROR
- minLookup
[WINELOOKUP_WARPPARAM
]] =
976 gl_info
->supported
[ARB_TEXTURE_MIRRORED_REPEAT
] ? GL_MIRRORED_REPEAT_ARB
: GL_REPEAT
;
977 stateLookup
[WINELOOKUP_WARPPARAM
][WINED3DTADDRESS_MIRRORONCE
- minLookup
[WINELOOKUP_WARPPARAM
]] =
978 gl_info
->supported
[ATI_TEXTURE_MIRROR_ONCE
] ? GL_MIRROR_CLAMP_TO_EDGE_ATI
: GL_REPEAT
;
980 stateLookup
[WINELOOKUP_MAGFILTER
][WINED3DTEXF_NONE
- minLookup
[WINELOOKUP_MAGFILTER
]] = GL_NEAREST
;
981 stateLookup
[WINELOOKUP_MAGFILTER
][WINED3DTEXF_POINT
- minLookup
[WINELOOKUP_MAGFILTER
]] = GL_NEAREST
;
982 stateLookup
[WINELOOKUP_MAGFILTER
][WINED3DTEXF_LINEAR
- minLookup
[WINELOOKUP_MAGFILTER
]] = GL_LINEAR
;
983 stateLookup
[WINELOOKUP_MAGFILTER
][WINED3DTEXF_ANISOTROPIC
- minLookup
[WINELOOKUP_MAGFILTER
]] =
984 gl_info
->supported
[EXT_TEXTURE_FILTER_ANISOTROPIC
] ? GL_LINEAR
: GL_NEAREST
;
987 minMipLookup
[WINED3DTEXF_NONE
][WINED3DTEXF_NONE
] = GL_LINEAR
;
988 minMipLookup
[WINED3DTEXF_NONE
][WINED3DTEXF_POINT
] = GL_LINEAR
;
989 minMipLookup
[WINED3DTEXF_NONE
][WINED3DTEXF_LINEAR
] = GL_LINEAR
;
990 minMipLookup
[WINED3DTEXF_POINT
][WINED3DTEXF_NONE
] = GL_NEAREST
;
991 minMipLookup
[WINED3DTEXF_POINT
][WINED3DTEXF_POINT
] = GL_NEAREST_MIPMAP_NEAREST
;
992 minMipLookup
[WINED3DTEXF_POINT
][WINED3DTEXF_LINEAR
] = GL_NEAREST_MIPMAP_LINEAR
;
993 minMipLookup
[WINED3DTEXF_LINEAR
][WINED3DTEXF_NONE
] = GL_LINEAR
;
994 minMipLookup
[WINED3DTEXF_LINEAR
][WINED3DTEXF_POINT
] = GL_LINEAR_MIPMAP_NEAREST
;
995 minMipLookup
[WINED3DTEXF_LINEAR
][WINED3DTEXF_LINEAR
] = GL_LINEAR_MIPMAP_LINEAR
;
996 minMipLookup
[WINED3DTEXF_ANISOTROPIC
][WINED3DTEXF_NONE
] = gl_info
->supported
[EXT_TEXTURE_FILTER_ANISOTROPIC
] ?
997 GL_LINEAR_MIPMAP_LINEAR
: GL_LINEAR
;
998 minMipLookup
[WINED3DTEXF_ANISOTROPIC
][WINED3DTEXF_POINT
] = gl_info
->supported
[EXT_TEXTURE_FILTER_ANISOTROPIC
] ? GL_LINEAR_MIPMAP_NEAREST
: GL_LINEAR
;
999 minMipLookup
[WINED3DTEXF_ANISOTROPIC
][WINED3DTEXF_LINEAR
] = gl_info
->supported
[EXT_TEXTURE_FILTER_ANISOTROPIC
] ? GL_LINEAR_MIPMAP_LINEAR
: GL_LINEAR
;
1001 /* TODO: config lookups */
1003 if (display
!= NULL
) {
1004 GLX_Extensions
= glXQueryExtensionsString(display
, DefaultScreen(display
));
1005 TRACE_(d3d_caps
)("GLX_Extensions reported:\n");
1007 if (NULL
== GLX_Extensions
) {
1008 ERR(" GLX_Extensions returns NULL\n");
1010 while (*GLX_Extensions
!= 0x00) {
1011 const char *Start
= GLX_Extensions
;
1014 memset(ThisExtn
, 0x00, sizeof(ThisExtn
));
1015 while (*GLX_Extensions
!= ' ' && *GLX_Extensions
!= 0x00) {
1018 memcpy(ThisExtn
, Start
, (GLX_Extensions
- Start
));
1019 TRACE_(d3d_caps
)("- %s\n", ThisExtn
);
1020 if (*GLX_Extensions
== ' ') GLX_Extensions
++;
1026 WineD3D_ReleaseFakeGLContext();
1027 return return_value
;
1030 /**********************************************************
1031 * IWineD3D implementation follows
1032 **********************************************************/
1034 static UINT WINAPI
IWineD3DImpl_GetAdapterCount (IWineD3D
*iface
) {
1035 IWineD3DImpl
*This
= (IWineD3DImpl
*)iface
;
1037 /* FIXME: Set to one for now to imply the display */
1038 TRACE_(d3d_caps
)("(%p): Mostly stub, only returns primary display\n", This
);
1042 static HRESULT WINAPI
IWineD3DImpl_RegisterSoftwareDevice(IWineD3D
*iface
, void* pInitializeFunction
) {
1043 IWineD3DImpl
*This
= (IWineD3DImpl
*)iface
;
1044 FIXME("(%p)->(%p): stub\n", This
, pInitializeFunction
);
1048 static HMONITOR WINAPI
IWineD3DImpl_GetAdapterMonitor(IWineD3D
*iface
, UINT Adapter
) {
1049 IWineD3DImpl
*This
= (IWineD3DImpl
*)iface
;
1050 POINT pt
= { -1, -1 };
1052 if (Adapter
>= IWineD3DImpl_GetAdapterCount(iface
)) {
1056 FIXME_(d3d_caps
)("(%p): returning the primary monitor for adapter %d\n", This
, Adapter
);
1057 return MonitorFromPoint(pt
, MONITOR_DEFAULTTOPRIMARY
);
1060 /* FIXME: GetAdapterModeCount and EnumAdapterModes currently only returns modes
1061 of the same bpp but different resolutions */
1063 /* Note: dx9 supplies a format. Calls from d3d8 supply WINED3DFMT_UNKNOWN */
1064 static UINT WINAPI
IWineD3DImpl_GetAdapterModeCount(IWineD3D
*iface
, UINT Adapter
, WINED3DFORMAT Format
) {
1065 IWineD3DImpl
*This
= (IWineD3DImpl
*)iface
;
1066 TRACE_(d3d_caps
)("(%p}->(Adapter: %d, Format: %s)\n", This
, Adapter
, debug_d3dformat(Format
));
1068 if (Adapter
>= IWineD3D_GetAdapterCount(iface
)) {
1072 if (Adapter
== 0) { /* Display */
1075 #if !defined( DEBUG_SINGLE_MODE )
1078 /* Work out the current screen bpp */
1079 HDC hdc
= CreateDCA("DISPLAY", NULL
, NULL
, NULL
);
1080 int bpp
= GetDeviceCaps(hdc
, BITSPIXEL
);
1083 while (EnumDisplaySettingsExW(NULL
, j
, &DevModeW
, 0)) {
1087 case WINED3DFMT_UNKNOWN
:
1090 case WINED3DFMT_X8R8G8B8
:
1091 case WINED3DFMT_A8R8G8B8
:
1092 if (min(DevModeW
.dmBitsPerPel
, bpp
) == 32) i
++;
1093 if (min(DevModeW
.dmBitsPerPel
, bpp
) == 24) i
++;
1095 case WINED3DFMT_X1R5G5B5
:
1096 case WINED3DFMT_A1R5G5B5
:
1097 case WINED3DFMT_R5G6B5
:
1098 if (min(DevModeW
.dmBitsPerPel
, bpp
) == 16) i
++;
1101 /* Skip other modes as they do not match the requested format */
1109 TRACE_(d3d_caps
)("(%p}->(Adapter: %d) => %d (out of %d)\n", This
, Adapter
, i
, j
);
1112 FIXME_(d3d_caps
)("Adapter not primary display\n");
1117 /* Note: dx9 supplies a format. Calls from d3d8 supply WINED3DFMT_UNKNOWN */
1118 static HRESULT WINAPI
IWineD3DImpl_EnumAdapterModes(IWineD3D
*iface
, UINT Adapter
, WINED3DFORMAT Format
, UINT Mode
, WINED3DDISPLAYMODE
* pMode
) {
1119 IWineD3DImpl
*This
= (IWineD3DImpl
*)iface
;
1120 TRACE_(d3d_caps
)("(%p}->(Adapter:%d, mode:%d, pMode:%p, format:%s)\n", This
, Adapter
, Mode
, pMode
, debug_d3dformat(Format
));
1122 /* Validate the parameters as much as possible */
1123 if (NULL
== pMode
||
1124 Adapter
>= IWineD3DImpl_GetAdapterCount(iface
) ||
1125 Mode
>= IWineD3DImpl_GetAdapterModeCount(iface
, Adapter
, Format
)) {
1126 return WINED3DERR_INVALIDCALL
;
1129 if (Adapter
== 0) { /* Display */
1131 #if !defined( DEBUG_SINGLE_MODE )
1135 /* Work out the current screen bpp */
1136 HDC hdc
= CreateDCA("DISPLAY", NULL
, NULL
, NULL
);
1137 bpp
= GetDeviceCaps(hdc
, BITSPIXEL
);
1140 /* If we are filtering to a specific format, then need to skip all unrelated
1141 modes, but if mode is irrelevant, then we can use the index directly */
1142 if (Format
== WINED3DFMT_UNKNOWN
)
1148 DEVMODEW DevModeWtmp
;
1151 while (i
<(Mode
) && EnumDisplaySettingsExW(NULL
, j
, &DevModeWtmp
, 0)) {
1155 case WINED3DFMT_UNKNOWN
:
1158 case WINED3DFMT_X8R8G8B8
:
1159 case WINED3DFMT_A8R8G8B8
:
1160 if (min(DevModeWtmp
.dmBitsPerPel
, bpp
) == 32) i
++;
1161 if (min(DevModeWtmp
.dmBitsPerPel
, bpp
) == 24) i
++;
1163 case WINED3DFMT_X1R5G5B5
:
1164 case WINED3DFMT_A1R5G5B5
:
1165 case WINED3DFMT_R5G6B5
:
1166 if (min(DevModeWtmp
.dmBitsPerPel
, bpp
) == 16) i
++;
1169 /* Skip other modes as they do not match requested format */
1176 /* Now get the display mode via the calculated index */
1177 if (EnumDisplaySettingsExW(NULL
, ModeIdx
, &DevModeW
, 0))
1179 pMode
->Width
= DevModeW
.dmPelsWidth
;
1180 pMode
->Height
= DevModeW
.dmPelsHeight
;
1181 bpp
= min(DevModeW
.dmBitsPerPel
, bpp
);
1182 pMode
->RefreshRate
= D3DADAPTER_DEFAULT
;
1183 if (DevModeW
.dmFields
& DM_DISPLAYFREQUENCY
)
1185 pMode
->RefreshRate
= DevModeW
.dmDisplayFrequency
;
1188 if (Format
== WINED3DFMT_UNKNOWN
)
1191 case 8: pMode
->Format
= WINED3DFMT_R3G3B2
; break;
1192 case 16: pMode
->Format
= WINED3DFMT_R5G6B5
; break;
1193 case 24: /* Robots and EVE Online need 24 and 32 bit as A8R8G8B8 to start */
1194 case 32: pMode
->Format
= WINED3DFMT_A8R8G8B8
; break;
1195 default: pMode
->Format
= WINED3DFMT_UNKNOWN
;
1198 pMode
->Format
= Format
;
1203 TRACE_(d3d_caps
)("Requested mode out of range %d\n", Mode
);
1204 return WINED3DERR_INVALIDCALL
;
1208 /* Return one setting of the format requested */
1209 if (Mode
> 0) return WINED3DERR_INVALIDCALL
;
1211 pMode
->Height
= 600;
1212 pMode
->RefreshRate
= D3DADAPTER_DEFAULT
;
1213 pMode
->Format
= (Format
== WINED3DFMT_UNKNOWN
) ? WINED3DFMT_A8R8G8B8
: Format
;
1216 TRACE_(d3d_caps
)("W %d H %d rr %d fmt (%x - %s) bpp %u\n", pMode
->Width
, pMode
->Height
,
1217 pMode
->RefreshRate
, pMode
->Format
, debug_d3dformat(pMode
->Format
), bpp
);
1220 FIXME_(d3d_caps
)("Adapter not primary display\n");
1226 static HRESULT WINAPI
IWineD3DImpl_GetAdapterDisplayMode(IWineD3D
*iface
, UINT Adapter
, WINED3DDISPLAYMODE
* pMode
) {
1227 IWineD3DImpl
*This
= (IWineD3DImpl
*)iface
;
1228 TRACE_(d3d_caps
)("(%p}->(Adapter: %d, pMode: %p)\n", This
, Adapter
, pMode
);
1230 if (NULL
== pMode
||
1231 Adapter
>= IWineD3D_GetAdapterCount(iface
)) {
1232 return WINED3DERR_INVALIDCALL
;
1235 if (Adapter
== 0) { /* Display */
1239 EnumDisplaySettingsExW(NULL
, (DWORD
)-1, &DevModeW
, 0);
1240 pMode
->Width
= DevModeW
.dmPelsWidth
;
1241 pMode
->Height
= DevModeW
.dmPelsHeight
;
1242 bpp
= DevModeW
.dmBitsPerPel
;
1243 pMode
->RefreshRate
= D3DADAPTER_DEFAULT
;
1244 if (DevModeW
.dmFields
&DM_DISPLAYFREQUENCY
)
1246 pMode
->RefreshRate
= DevModeW
.dmDisplayFrequency
;
1250 case 8: pMode
->Format
= WINED3DFMT_R3G3B2
; break;
1251 case 16: pMode
->Format
= WINED3DFMT_R5G6B5
; break;
1252 case 24: pMode
->Format
= WINED3DFMT_X8R8G8B8
; break; /* Robots needs 24bit to be X8R8G8B8 */
1253 case 32: pMode
->Format
= WINED3DFMT_X8R8G8B8
; break; /* EVE online and the Fur demo need 32bit AdapterDisplatMode to return X8R8G8B8 */
1254 default: pMode
->Format
= WINED3DFMT_UNKNOWN
;
1258 FIXME_(d3d_caps
)("Adapter not primary display\n");
1261 TRACE_(d3d_caps
)("returning w:%d, h:%d, ref:%d, fmt:%s\n", pMode
->Width
,
1262 pMode
->Height
, pMode
->RefreshRate
, debug_d3dformat(pMode
->Format
));
1266 static Display
* WINAPI
IWineD3DImpl_GetAdapterDisplay(IWineD3D
*iface
, UINT Adapter
) {
1269 /* only works with one adapter at the moment... */
1271 /* Get the display */
1272 device_context
= GetDC(0);
1273 display
= get_display(device_context
);
1274 ReleaseDC(0, device_context
);
1278 /* NOTE: due to structure differences between dx8 and dx9 D3DADAPTER_IDENTIFIER,
1279 and fields being inserted in the middle, a new structure is used in place */
1280 static HRESULT WINAPI
IWineD3DImpl_GetAdapterIdentifier(IWineD3D
*iface
, UINT Adapter
, DWORD Flags
,
1281 WINED3DADAPTER_IDENTIFIER
* pIdentifier
) {
1282 IWineD3DImpl
*This
= (IWineD3DImpl
*)iface
;
1284 TRACE_(d3d_caps
)("(%p}->(Adapter: %d, Flags: %x, pId=%p)\n", This
, Adapter
, Flags
, pIdentifier
);
1286 if (Adapter
>= IWineD3D_GetAdapterCount(iface
)) {
1287 return WINED3DERR_INVALIDCALL
;
1290 if (Adapter
== 0) { /* Display - only device supported for now */
1292 BOOL isGLInfoValid
= This
->isGLInfoValid
;
1294 /* FillGLCaps updates gl_info, but we only want to store and
1295 reuse the values once we have a context which is valid. Values from
1296 a temporary context may differ from the final ones */
1297 if (!isGLInfoValid
) {
1298 /* If we don't know the device settings, go query them now */
1299 isGLInfoValid
= IWineD3DImpl_FillGLCaps(iface
, IWineD3DImpl_GetAdapterDisplay(iface
, Adapter
));
1302 /* If it worked, return the information requested */
1303 if (isGLInfoValid
) {
1304 TRACE_(d3d_caps
)("device/Vendor Name and Version detection using FillGLCaps\n");
1305 strcpy(pIdentifier
->Driver
, "Display");
1306 strcpy(pIdentifier
->Description
, "Direct3D HAL");
1308 /* Note dx8 doesn't supply a DeviceName */
1309 if (NULL
!= pIdentifier
->DeviceName
) strcpy(pIdentifier
->DeviceName
, "\\\\.\\DISPLAY"); /* FIXME: May depend on desktop? */
1310 /* Current Windows drivers have versions like 6.14.... (some older have an earlier version) */
1311 pIdentifier
->DriverVersion
->u
.HighPart
= MAKEDWORD_VERSION(6, 14);
1312 pIdentifier
->DriverVersion
->u
.LowPart
= This
->gl_info
.gl_driver_version
;
1313 *(pIdentifier
->VendorId
) = This
->gl_info
.gl_vendor
;
1314 *(pIdentifier
->DeviceId
) = This
->gl_info
.gl_card
;
1315 *(pIdentifier
->SubSysId
) = 0;
1316 *(pIdentifier
->Revision
) = 0;
1320 /* If it failed, return dummy values from an NVidia driver */
1321 WARN_(d3d_caps
)("Cannot get GLCaps for device/Vendor Name and Version detection using FillGLCaps, currently using NVIDIA identifiers\n");
1322 strcpy(pIdentifier
->Driver
, "Display");
1323 strcpy(pIdentifier
->Description
, "Direct3D HAL");
1324 if (NULL
!= pIdentifier
->DeviceName
) strcpy(pIdentifier
->DeviceName
, "\\\\.\\DISPLAY"); /* FIXME: May depend on desktop? */
1325 /* Current Windows Nvidia drivers have versions like e.g. 6.14.10.5672 */
1326 pIdentifier
->DriverVersion
->u
.HighPart
= MAKEDWORD_VERSION(6, 14);
1327 /* 71.74 is a current Linux Nvidia driver version */
1328 pIdentifier
->DriverVersion
->u
.LowPart
= MAKEDWORD_VERSION(10, (71*100+74));
1329 *(pIdentifier
->VendorId
) = VENDOR_NVIDIA
;
1330 *(pIdentifier
->DeviceId
) = CARD_NVIDIA_GEFORCE4_TI4200
;
1331 *(pIdentifier
->SubSysId
) = 0;
1332 *(pIdentifier
->Revision
) = 0;
1335 /*FIXME: memcpy(&pIdentifier->DeviceIdentifier, ??, sizeof(??GUID)); */
1336 if (Flags
& D3DENUM_NO_WHQL_LEVEL
) {
1337 *(pIdentifier
->WHQLLevel
) = 0;
1339 *(pIdentifier
->WHQLLevel
) = 1;
1343 FIXME_(d3d_caps
)("Adapter not primary display\n");
1349 static BOOL
IWineD3DImpl_IsGLXFBConfigCompatibleWithRenderFmt(Display
*display
, GLXFBConfig cfgs
, WINED3DFORMAT Format
) {
1350 #if 0 /* This code performs a strict test between the format and the current X11 buffer depth, which may give the best performance */
1352 int rb
, gb
, bb
, ab
, type
, buf_sz
;
1354 gl_test
= glXGetFBConfigAttrib(display
, cfgs
, GLX_RED_SIZE
, &rb
);
1355 gl_test
= glXGetFBConfigAttrib(display
, cfgs
, GLX_GREEN_SIZE
, &gb
);
1356 gl_test
= glXGetFBConfigAttrib(display
, cfgs
, GLX_BLUE_SIZE
, &bb
);
1357 gl_test
= glXGetFBConfigAttrib(display
, cfgs
, GLX_ALPHA_SIZE
, &ab
);
1358 gl_test
= glXGetFBConfigAttrib(display
, cfgs
, GLX_RENDER_TYPE
, &type
);
1359 gl_test
= glXGetFBConfigAttrib(display
, cfgs
, GLX_BUFFER_SIZE
, &buf_sz
);
1362 case WINED3DFMT_X8R8G8B8
:
1363 case WINED3DFMT_R8G8B8
:
1364 if (8 == rb
&& 8 == gb
&& 8 == bb
) return TRUE
;
1366 case WINED3DFMT_A8R8G8B8
:
1367 if (8 == rb
&& 8 == gb
&& 8 == bb
&& 8 == ab
) return TRUE
;
1369 case WINED3DFMT_A2R10G10B10
:
1370 if (10 == rb
&& 10 == gb
&& 10 == bb
&& 2 == ab
) return TRUE
;
1372 case WINED3DFMT_X1R5G5B5
:
1373 if (5 == rb
&& 5 == gb
&& 5 == bb
) return TRUE
;
1375 case WINED3DFMT_A1R5G5B5
:
1376 if (5 == rb
&& 5 == gb
&& 5 == bb
&& 1 == ab
) return TRUE
;
1378 case WINED3DFMT_X4R4G4B4
:
1379 if (16 == buf_sz
&& 4 == rb
&& 4 == gb
&& 4 == bb
) return TRUE
;
1381 case WINED3DFMT_R5G6B5
:
1382 if (5 == rb
&& 6 == gb
&& 5 == bb
) return TRUE
;
1384 case WINED3DFMT_R3G3B2
:
1385 if (3 == rb
&& 3 == gb
&& 2 == bb
) return TRUE
;
1387 case WINED3DFMT_A8P8
:
1388 if (type
& GLX_COLOR_INDEX_BIT
&& 8 == buf_sz
&& 8 == ab
) return TRUE
;
1391 if (type
& GLX_COLOR_INDEX_BIT
&& 8 == buf_sz
) return TRUE
;
1394 ERR("unsupported format %s\n", debug_d3dformat(Format
));
1398 #else /* Most of the time performance is less of an issue than compatibility, this code allows for most common opengl/d3d formats */
1400 case WINED3DFMT_X8R8G8B8
:
1401 case WINED3DFMT_R8G8B8
:
1402 case WINED3DFMT_A8R8G8B8
:
1403 case WINED3DFMT_A2R10G10B10
:
1404 case WINED3DFMT_X1R5G5B5
:
1405 case WINED3DFMT_A1R5G5B5
:
1406 case WINED3DFMT_R5G6B5
:
1407 case WINED3DFMT_R3G3B2
:
1408 case WINED3DFMT_A8P8
:
1412 ERR("unsupported format %s\n", debug_d3dformat(Format
));
1419 static BOOL
IWineD3DImpl_IsGLXFBConfigCompatibleWithDepthFmt(Display
*display
, GLXFBConfig cfgs
, WINED3DFORMAT Format
) {
1420 #if 0/* This code performs a strict test between the format and the current X11 buffer depth, which may give the best performance */
1424 gl_test
= glXGetFBConfigAttrib(display
, cfgs
, GLX_DEPTH_SIZE
, &db
);
1425 gl_test
= glXGetFBConfigAttrib(display
, cfgs
, GLX_STENCIL_SIZE
, &sb
);
1428 case WINED3DFMT_D16
:
1429 case WINED3DFMT_D16_LOCKABLE
:
1430 if (16 == db
) return TRUE
;
1432 case WINED3DFMT_D32
:
1433 if (32 == db
) return TRUE
;
1435 case WINED3DFMT_D15S1
:
1436 if (15 == db
) return TRUE
;
1438 case WINED3DFMT_D24S8
:
1439 if (24 == db
&& 8 == sb
) return TRUE
;
1441 case WINED3DFMT_D24FS8
:
1442 if (24 == db
&& 8 == sb
) return TRUE
;
1444 case WINED3DFMT_D24X8
:
1445 if (24 == db
) return TRUE
;
1447 case WINED3DFMT_D24X4S4
:
1448 if (24 == db
&& 4 == sb
) return TRUE
;
1450 case WINED3DFMT_D32F_LOCKABLE
:
1451 if (32 == db
) return TRUE
;
1454 ERR("unsupported format %s\n", debug_d3dformat(Format
));
1458 #else /* Most of the time performance is less of an issue than compatibility, this code allows for most common opengl/d3d formats */
1460 case WINED3DFMT_D16
:
1461 case WINED3DFMT_D16_LOCKABLE
:
1462 case WINED3DFMT_D32
:
1463 case WINED3DFMT_D15S1
:
1464 case WINED3DFMT_D24S8
:
1465 case WINED3DFMT_D24FS8
:
1466 case WINED3DFMT_D24X8
:
1467 case WINED3DFMT_D24X4S4
:
1468 case WINED3DFMT_D32F_LOCKABLE
:
1471 ERR("unsupported format %s\n", debug_d3dformat(Format
));
1478 static HRESULT WINAPI
IWineD3DImpl_CheckDepthStencilMatch(IWineD3D
*iface
, UINT Adapter
, WINED3DDEVTYPE DeviceType
,
1479 WINED3DFORMAT AdapterFormat
,
1480 WINED3DFORMAT RenderTargetFormat
,
1481 WINED3DFORMAT DepthStencilFormat
) {
1482 IWineD3DImpl
*This
= (IWineD3DImpl
*)iface
;
1483 HRESULT hr
= WINED3DERR_NOTAVAILABLE
;
1484 GLXFBConfig
* cfgs
= NULL
;
1488 WARN_(d3d_caps
)("(%p)-> (STUB) (Adptr:%d, DevType:(%x,%s), AdptFmt:(%x,%s), RendrTgtFmt:(%x,%s), DepthStencilFmt:(%x,%s))\n",
1490 DeviceType
, debug_d3ddevicetype(DeviceType
),
1491 AdapterFormat
, debug_d3dformat(AdapterFormat
),
1492 RenderTargetFormat
, debug_d3dformat(RenderTargetFormat
),
1493 DepthStencilFormat
, debug_d3dformat(DepthStencilFormat
));
1495 if (Adapter
>= IWineD3D_GetAdapterCount(iface
)) {
1496 TRACE("(%p) Failed: Atapter (%u) higher than supported adapters (%u) returning WINED3DERR_INVALIDCALL\n", This
, Adapter
, IWineD3D_GetAdapterCount(iface
));
1497 return WINED3DERR_INVALIDCALL
;
1500 if(WineD3D_CreateFakeGLContext())
1501 cfgs
= glXGetFBConfigs(wined3d_fake_gl_context_display
, DefaultScreen(wined3d_fake_gl_context_display
), &nCfgs
);
1504 for (it
= 0; it
< nCfgs
; ++it
) {
1505 if (IWineD3DImpl_IsGLXFBConfigCompatibleWithRenderFmt(wined3d_fake_gl_context_display
, cfgs
[it
], RenderTargetFormat
)) {
1506 if (IWineD3DImpl_IsGLXFBConfigCompatibleWithDepthFmt(wined3d_fake_gl_context_display
, cfgs
[it
], DepthStencilFormat
)) {
1515 /* If there's a current context then we cannot create a fake one so pass everything */
1519 WineD3D_ReleaseFakeGLContext();
1521 if (hr
!= WINED3D_OK
)
1522 TRACE_(d3d_caps
)("Failed to match stencil format to device\n");
1524 TRACE_(d3d_caps
)("(%p) : Returning %x\n", This
, hr
);
1528 static HRESULT WINAPI
IWineD3DImpl_CheckDeviceMultiSampleType(IWineD3D
*iface
, UINT Adapter
, WINED3DDEVTYPE DeviceType
,
1529 WINED3DFORMAT SurfaceFormat
,
1530 BOOL Windowed
, WINED3DMULTISAMPLE_TYPE MultiSampleType
, DWORD
* pQualityLevels
) {
1532 IWineD3DImpl
*This
= (IWineD3DImpl
*)iface
;
1533 TRACE_(d3d_caps
)("(%p)-> (STUB) (Adptr:%d, DevType:(%x,%s), SurfFmt:(%x,%s), Win?%d, MultiSamp:%x, pQual:%p)\n",
1536 DeviceType
, debug_d3ddevicetype(DeviceType
),
1537 SurfaceFormat
, debug_d3dformat(SurfaceFormat
),
1542 if (Adapter
>= IWineD3D_GetAdapterCount(iface
)) {
1543 return WINED3DERR_INVALIDCALL
;
1546 if (pQualityLevels
!= NULL
) {
1547 static int s_single_shot
= 0;
1548 if (!s_single_shot
) {
1549 FIXME("Quality levels unsupported at present\n");
1552 *pQualityLevels
= 1; /* Guess at a value! */
1555 if (WINED3DMULTISAMPLE_NONE
== MultiSampleType
) return WINED3D_OK
;
1556 return WINED3DERR_NOTAVAILABLE
;
1559 static HRESULT WINAPI
IWineD3DImpl_CheckDeviceType(IWineD3D
*iface
, UINT Adapter
, WINED3DDEVTYPE CheckType
,
1560 WINED3DFORMAT DisplayFormat
, WINED3DFORMAT BackBufferFormat
, BOOL Windowed
) {
1562 IWineD3DImpl
*This
= (IWineD3DImpl
*)iface
;
1563 GLXFBConfig
* cfgs
= NULL
;
1566 HRESULT hr
= WINED3DERR_NOTAVAILABLE
;
1568 TRACE_(d3d_caps
)("(%p)-> (STUB) (Adptr:%d, CheckType:(%x,%s), DispFmt:(%x,%s), BackBuf:(%x,%s), Win?%d): stub\n",
1571 CheckType
, debug_d3ddevicetype(CheckType
),
1572 DisplayFormat
, debug_d3dformat(DisplayFormat
),
1573 BackBufferFormat
, debug_d3dformat(BackBufferFormat
),
1576 if (Adapter
>= IWineD3D_GetAdapterCount(iface
)) {
1577 WARN_(d3d_caps
)("Adapter >= IWineD3D_GetAdapterCount(iface), returning WINED3DERR_INVALIDCALL\n");
1578 return WINED3DERR_INVALIDCALL
;
1581 if (WineD3D_CreateFakeGLContext()) {
1582 cfgs
= glXGetFBConfigs(wined3d_fake_gl_context_display
, DefaultScreen(wined3d_fake_gl_context_display
), &nCfgs
);
1583 for (it
= 0; it
< nCfgs
; ++it
) {
1584 if (IWineD3DImpl_IsGLXFBConfigCompatibleWithRenderFmt(wined3d_fake_gl_context_display
, cfgs
[it
], DisplayFormat
)) {
1586 TRACE_(d3d_caps
)("OK\n");
1590 if(cfgs
) XFree(cfgs
);
1591 WineD3D_ReleaseFakeGLContext();
1594 if(hr
!= WINED3D_OK
)
1595 TRACE_(d3d_caps
)("returning something different from WINED3D_OK\n");
1600 static HRESULT WINAPI
IWineD3DImpl_CheckDeviceFormat(IWineD3D
*iface
, UINT Adapter
, WINED3DDEVTYPE DeviceType
,
1601 WINED3DFORMAT AdapterFormat
, DWORD Usage
, WINED3DRESOURCETYPE RType
, WINED3DFORMAT CheckFormat
) {
1602 IWineD3DImpl
*This
= (IWineD3DImpl
*)iface
;
1603 TRACE_(d3d_caps
)("(%p)-> (STUB) (Adptr:%d, DevType:(%u,%s), AdptFmt:(%u,%s), Use:(%u,%s,%s), ResTyp:(%x,%s), CheckFmt:(%u,%s))\n",
1606 DeviceType
, debug_d3ddevicetype(DeviceType
),
1607 AdapterFormat
, debug_d3dformat(AdapterFormat
),
1608 Usage
, debug_d3dusage(Usage
), debug_d3dusagequery(Usage
),
1609 RType
, debug_d3dresourcetype(RType
),
1610 CheckFormat
, debug_d3dformat(CheckFormat
));
1612 if (Adapter
>= IWineD3D_GetAdapterCount(iface
)) {
1613 return WINED3DERR_INVALIDCALL
;
1616 /* TODO: Check support against more of the WINED3DUSAGE_QUERY_* constants
1617 * See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/directx9_c/IDirect3D9__CheckDeviceFormat.asp
1618 * and http://msdn.microsoft.com/library/default.asp?url=/library/en-us/directx9_c/D3DUSAGE_QUERY.asp */
1619 if (Usage
& WINED3DUSAGE_QUERY_VERTEXTEXTURE
) {
1620 TRACE_(d3d_caps
)("[FAILED]\n");
1621 return WINED3DERR_NOTAVAILABLE
; /* Enable when fully supported */
1624 if(Usage
& WINED3DUSAGE_DEPTHSTENCIL
) {
1625 switch (CheckFormat
) {
1626 case WINED3DFMT_D16_LOCKABLE
:
1627 case WINED3DFMT_D32
:
1628 case WINED3DFMT_D15S1
:
1629 case WINED3DFMT_D24S8
:
1630 case WINED3DFMT_D24X8
:
1631 case WINED3DFMT_D24X4S4
:
1632 case WINED3DFMT_D16
:
1633 case WINED3DFMT_L16
:
1634 case WINED3DFMT_D32F_LOCKABLE
:
1635 case WINED3DFMT_D24FS8
:
1636 TRACE_(d3d_caps
)("[OK]\n");
1639 TRACE_(d3d_caps
)("[FAILED]\n");
1640 return WINED3DERR_NOTAVAILABLE
;
1642 } else if(Usage
& WINED3DUSAGE_RENDERTARGET
) {
1643 switch (CheckFormat
) {
1644 case WINED3DFMT_R8G8B8
:
1645 case WINED3DFMT_A8R8G8B8
:
1646 case WINED3DFMT_X8R8G8B8
:
1647 case WINED3DFMT_R5G6B5
:
1648 case WINED3DFMT_X1R5G5B5
:
1649 case WINED3DFMT_A1R5G5B5
:
1650 case WINED3DFMT_A4R4G4B4
:
1651 case WINED3DFMT_R3G3B2
:
1652 case WINED3DFMT_X4R4G4B4
:
1653 case WINED3DFMT_A8B8G8R8
:
1654 case WINED3DFMT_X8B8G8R8
:
1656 TRACE_(d3d_caps
)("[OK]\n");
1659 TRACE_(d3d_caps
)("[FAILED]\n");
1660 return WINED3DERR_NOTAVAILABLE
;
1664 if (GL_SUPPORT(EXT_TEXTURE_COMPRESSION_S3TC
)) {
1665 switch (CheckFormat
) {
1666 case WINED3DFMT_DXT1
:
1667 case WINED3DFMT_DXT2
:
1668 case WINED3DFMT_DXT3
:
1669 case WINED3DFMT_DXT4
:
1670 case WINED3DFMT_DXT5
:
1671 TRACE_(d3d_caps
)("[OK]\n");
1674 break; /* Avoid compiler warnings */
1678 if (GL_SUPPORT(ARB_TEXTURE_FLOAT
)) {
1680 BOOL half_pixel_support
= GL_SUPPORT(ARB_HALF_FLOAT_PIXEL
);
1682 switch (CheckFormat
) {
1683 case WINED3DFMT_R16F
:
1684 case WINED3DFMT_A16B16G16R16F
:
1685 if (!half_pixel_support
) break;
1686 case WINED3DFMT_R32F
:
1687 case WINED3DFMT_A32B32G32R32F
:
1688 TRACE_(d3d_caps
)("[OK]\n");
1691 break; /* Avoid compiler warnings */
1695 /* This format is nothing special and it is supported perfectly.
1696 * However, ati and nvidia driver on windows do not mark this format as
1697 * supported (tested with the dxCapsViewer) and pretending to
1698 * support this format uncovers a bug in Battlefield 1942 (fonts are missing)
1699 * So do the same as Windows drivers and pretend not to support it on dx8 and 9
1700 * Enable it on dx7. It will need additional checking on dx10 when we support it.
1702 if(This
->dxVersion
> 7 && CheckFormat
== WINED3DFMT_R8G8B8
) {
1703 TRACE_(d3d_caps
)("[FAILED]\n");
1704 return WINED3DERR_NOTAVAILABLE
;
1707 switch (CheckFormat
) {
1710 * supported: RGB(A) formats
1712 case WINED3DFMT_R8G8B8
: /* Enable for dx7, blacklisted for 8 and 9 above */
1713 case WINED3DFMT_A8R8G8B8
:
1714 case WINED3DFMT_X8R8G8B8
:
1715 case WINED3DFMT_R5G6B5
:
1716 case WINED3DFMT_X1R5G5B5
:
1717 case WINED3DFMT_A1R5G5B5
:
1718 case WINED3DFMT_A4R4G4B4
:
1719 case WINED3DFMT_R3G3B2
:
1721 case WINED3DFMT_A8R3G3B2
:
1722 case WINED3DFMT_X4R4G4B4
:
1723 case WINED3DFMT_A8B8G8R8
:
1724 case WINED3DFMT_X8B8G8R8
:
1725 case WINED3DFMT_A2R10G10B10
:
1726 case WINED3DFMT_A2B10G10R10
:
1727 TRACE_(d3d_caps
)("[OK]\n");
1731 * supported: Palettized
1734 TRACE_(d3d_caps
)("[OK]\n");
1738 * Supported: (Alpha)-Luminance
1741 case WINED3DFMT_A8L8
:
1742 case WINED3DFMT_A4L4
:
1743 TRACE_(d3d_caps
)("[OK]\n");
1747 * Not supported for now: Bump mapping formats
1748 * Enable some because games often fail when they are not available
1749 * and are still playable even without bump mapping
1751 case WINED3DFMT_V8U8
:
1752 case WINED3DFMT_V16U16
:
1753 case WINED3DFMT_L6V5U5
:
1754 case WINED3DFMT_X8L8V8U8
:
1755 case WINED3DFMT_Q8W8V8U8
:
1756 case WINED3DFMT_W11V11U10
:
1757 case WINED3DFMT_A2W10V10U10
:
1758 WARN_(d3d_caps
)("[Not supported, but pretended to do]\n");
1762 * DXTN Formats: Handled above
1771 * Odd formats - not supported
1773 case WINED3DFMT_VERTEXDATA
:
1774 case WINED3DFMT_INDEX16
:
1775 case WINED3DFMT_INDEX32
:
1776 case WINED3DFMT_Q16W16V16U16
:
1777 TRACE_(d3d_caps
)("[FAILED]\n"); /* Enable when implemented */
1778 return WINED3DERR_NOTAVAILABLE
;
1781 * Float formats: Not supported right now
1783 case WINED3DFMT_G16R16F
:
1784 case WINED3DFMT_G32R32F
:
1785 case WINED3DFMT_CxV8U8
:
1786 TRACE_(d3d_caps
)("[FAILED]\n"); /* Enable when implemented */
1787 return WINED3DERR_NOTAVAILABLE
;
1790 case WINED3DFMT_G16R16
:
1791 case WINED3DFMT_A16B16G16R16
:
1792 TRACE_(d3d_caps
)("[FAILED]\n"); /* Enable when implemented */
1793 return WINED3DERR_NOTAVAILABLE
;
1799 TRACE_(d3d_caps
)("[FAILED]\n");
1800 return WINED3DERR_NOTAVAILABLE
;
1803 static HRESULT WINAPI
IWineD3DImpl_CheckDeviceFormatConversion(IWineD3D
*iface
, UINT Adapter
, WINED3DDEVTYPE DeviceType
,
1804 WINED3DFORMAT SourceFormat
, WINED3DFORMAT TargetFormat
) {
1805 IWineD3DImpl
*This
= (IWineD3DImpl
*)iface
;
1807 FIXME_(d3d_caps
)("(%p)-> (STUB) (Adptr:%d, DevType:(%u,%s), SrcFmt:(%u,%s), TgtFmt:(%u,%s))\n",
1810 DeviceType
, debug_d3ddevicetype(DeviceType
),
1811 SourceFormat
, debug_d3dformat(SourceFormat
),
1812 TargetFormat
, debug_d3dformat(TargetFormat
));
1816 /* Note: d3d8 passes in a pointer to a D3DCAPS8 structure, which is a true
1817 subset of a D3DCAPS9 structure. However, it has to come via a void *
1818 as the d3d8 interface cannot import the d3d9 header */
1819 static HRESULT WINAPI
IWineD3DImpl_GetDeviceCaps(IWineD3D
*iface
, UINT Adapter
, WINED3DDEVTYPE DeviceType
, WINED3DCAPS
* pCaps
) {
1821 IWineD3DImpl
*This
= (IWineD3DImpl
*)iface
;
1822 int vs_selected_mode
;
1823 int ps_selected_mode
;
1825 TRACE_(d3d_caps
)("(%p)->(Adptr:%d, DevType: %x, pCaps: %p)\n", This
, Adapter
, DeviceType
, pCaps
);
1827 if (Adapter
>= IWineD3D_GetAdapterCount(iface
)) {
1828 return WINED3DERR_INVALIDCALL
;
1831 /* FIXME: GL info should be per adapter */
1833 /* If we don't know the device settings, go query them now */
1834 if (!This
->isGLInfoValid
) {
1835 /* use the desktop window to fill gl caps */
1836 BOOL rc
= IWineD3DImpl_FillGLCaps(iface
, IWineD3DImpl_GetAdapterDisplay(iface
, Adapter
));
1838 /* We are running off a real context, save the values */
1839 if (rc
) This
->isGLInfoValid
= TRUE
;
1841 select_shader_mode(&This
->gl_info
, DeviceType
, &ps_selected_mode
, &vs_selected_mode
);
1843 /* This function should *not* be modifying GL caps
1844 * TODO: move the functionality where it belongs */
1845 select_shader_max_constants(ps_selected_mode
, vs_selected_mode
, &This
->gl_info
);
1847 /* ------------------------------------------------
1848 The following fields apply to both d3d8 and d3d9
1849 ------------------------------------------------ */
1850 *pCaps
->DeviceType
= (DeviceType
== WINED3DDEVTYPE_HAL
) ? WINED3DDEVTYPE_HAL
: WINED3DDEVTYPE_REF
; /* Not quite true, but use h/w supported by opengl I suppose */
1851 *pCaps
->AdapterOrdinal
= Adapter
;
1854 *pCaps
->Caps2
= WINED3DCAPS2_CANRENDERWINDOWED
|
1855 WINED3DCAPS2_FULLSCREENGAMMA
;
1857 *pCaps
->PresentationIntervals
= D3DPRESENT_INTERVAL_IMMEDIATE
;
1859 *pCaps
->CursorCaps
= 0;
1862 *pCaps
->DevCaps
= WINED3DDEVCAPS_FLOATTLVERTEX
|
1863 WINED3DDEVCAPS_EXECUTESYSTEMMEMORY
|
1864 WINED3DDEVCAPS_TLVERTEXSYSTEMMEMORY
|
1865 WINED3DDEVCAPS_TLVERTEXVIDEOMEMORY
|
1866 WINED3DDEVCAPS_DRAWPRIMTLVERTEX
|
1867 WINED3DDEVCAPS_HWTRANSFORMANDLIGHT
|
1868 WINED3DDEVCAPS_EXECUTEVIDEOMEMORY
|
1869 WINED3DDEVCAPS_PUREDEVICE
|
1870 WINED3DDEVCAPS_HWRASTERIZATION
|
1871 WINED3DDEVCAPS_TEXTUREVIDEOMEMORY
|
1872 WINED3DDEVCAPS_TEXTURESYSTEMMEMORY
|
1873 WINED3DDEVCAPS_CANRENDERAFTERFLIP
|
1874 WINED3DDEVCAPS_DRAWPRIMITIVES2
|
1875 WINED3DDEVCAPS_DRAWPRIMITIVES2EX
;
1877 *pCaps
->PrimitiveMiscCaps
= D3DPMISCCAPS_CULLNONE
|
1878 D3DPMISCCAPS_CULLCCW
|
1879 D3DPMISCCAPS_CULLCW
|
1880 D3DPMISCCAPS_COLORWRITEENABLE
|
1881 D3DPMISCCAPS_CLIPTLVERTS
|
1882 D3DPMISCCAPS_CLIPPLANESCALEDPOINTS
|
1883 D3DPMISCCAPS_MASKZ
|
1884 D3DPMISCCAPS_BLENDOP
;
1886 D3DPMISCCAPS_NULLREFERENCE
1887 D3DPMISCCAPS_INDEPENDENTWRITEMASKS
1888 D3DPMISCCAPS_FOGANDSPECULARALPHA
1889 D3DPMISCCAPS_SEPARATEALPHABLEND
1890 D3DPMISCCAPS_MRTINDEPENDENTBITDEPTHS
1891 D3DPMISCCAPS_MRTPOSTPIXELSHADERBLENDING
1892 D3DPMISCCAPS_FOGVERTEXCLAMPED */
1894 /* The caps below can be supported but aren't handled yet in utils.c 'd3dta_to_combiner_input', disable them until support is fixed */
1896 if (GL_SUPPORT(NV_REGISTER_COMBINERS
))
1897 *pCaps
->PrimitiveMiscCaps
|= D3DPMISCCAPS_TSSARGTEMP
;
1898 if (GL_SUPPORT(NV_REGISTER_COMBINERS2
))
1899 *pCaps
->PrimitiveMiscCaps
|= D3DPMISCCAPS_PERSTAGECONSTANT
;
1902 *pCaps
->RasterCaps
= WINED3DPRASTERCAPS_DITHER
|
1903 WINED3DPRASTERCAPS_PAT
|
1904 WINED3DPRASTERCAPS_WFOG
|
1905 WINED3DPRASTERCAPS_ZFOG
|
1906 WINED3DPRASTERCAPS_FOGVERTEX
|
1907 WINED3DPRASTERCAPS_FOGTABLE
|
1908 WINED3DPRASTERCAPS_FOGRANGE
|
1909 WINED3DPRASTERCAPS_STIPPLE
|
1910 WINED3DPRASTERCAPS_SUBPIXEL
|
1911 WINED3DPRASTERCAPS_ZTEST
|
1912 WINED3DPRASTERCAPS_SCISSORTEST
|
1913 WINED3DPRASTERCAPS_SLOPESCALEDEPTHBIAS
|
1914 WINED3DPRASTERCAPS_DEPTHBIAS
;
1916 if (GL_SUPPORT(EXT_TEXTURE_FILTER_ANISOTROPIC
)) {
1917 *pCaps
->RasterCaps
|= WINED3DPRASTERCAPS_ANISOTROPY
|
1918 WINED3DPRASTERCAPS_ZBIAS
|
1919 WINED3DPRASTERCAPS_MIPMAPLODBIAS
;
1922 WINED3DPRASTERCAPS_COLORPERSPECTIVE
1923 WINED3DPRASTERCAPS_STRETCHBLTMULTISAMPLE
1924 WINED3DPRASTERCAPS_ANTIALIASEDGES
1925 WINED3DPRASTERCAPS_ZBUFFERLESSHSR
1926 WINED3DPRASTERCAPS_WBUFFER */
1928 *pCaps
->ZCmpCaps
= D3DPCMPCAPS_ALWAYS
|
1930 D3DPCMPCAPS_GREATER
|
1931 D3DPCMPCAPS_GREATEREQUAL
|
1933 D3DPCMPCAPS_LESSEQUAL
|
1935 D3DPCMPCAPS_NOTEQUAL
;
1937 *pCaps
->SrcBlendCaps
= D3DPBLENDCAPS_BLENDFACTOR
|
1938 D3DPBLENDCAPS_BOTHINVSRCALPHA
|
1939 D3DPBLENDCAPS_BOTHSRCALPHA
|
1940 D3DPBLENDCAPS_DESTALPHA
|
1941 D3DPBLENDCAPS_DESTCOLOR
|
1942 D3DPBLENDCAPS_INVDESTALPHA
|
1943 D3DPBLENDCAPS_INVDESTCOLOR
|
1944 D3DPBLENDCAPS_INVSRCALPHA
|
1945 D3DPBLENDCAPS_INVSRCCOLOR
|
1947 D3DPBLENDCAPS_SRCALPHA
|
1948 D3DPBLENDCAPS_SRCALPHASAT
|
1949 D3DPBLENDCAPS_SRCCOLOR
|
1952 *pCaps
->DestBlendCaps
= D3DPBLENDCAPS_BLENDFACTOR
|
1953 D3DPBLENDCAPS_BOTHINVSRCALPHA
|
1954 D3DPBLENDCAPS_BOTHSRCALPHA
|
1955 D3DPBLENDCAPS_DESTALPHA
|
1956 D3DPBLENDCAPS_DESTCOLOR
|
1957 D3DPBLENDCAPS_INVDESTALPHA
|
1958 D3DPBLENDCAPS_INVDESTCOLOR
|
1959 D3DPBLENDCAPS_INVSRCALPHA
|
1960 D3DPBLENDCAPS_INVSRCCOLOR
|
1962 D3DPBLENDCAPS_SRCALPHA
|
1963 D3DPBLENDCAPS_SRCALPHASAT
|
1964 D3DPBLENDCAPS_SRCCOLOR
|
1967 *pCaps
->AlphaCmpCaps
= D3DPCMPCAPS_ALWAYS
|
1969 D3DPCMPCAPS_GREATER
|
1970 D3DPCMPCAPS_GREATEREQUAL
|
1972 D3DPCMPCAPS_LESSEQUAL
|
1974 D3DPCMPCAPS_NOTEQUAL
;
1976 *pCaps
->ShadeCaps
= WINED3DPSHADECAPS_SPECULARGOURAUDRGB
|
1977 WINED3DPSHADECAPS_COLORGOURAUDRGB
|
1978 WINED3DPSHADECAPS_ALPHAFLATBLEND
|
1979 WINED3DPSHADECAPS_ALPHAGOURAUDBLEND
|
1980 WINED3DPSHADECAPS_COLORFLATRGB
|
1981 WINED3DPSHADECAPS_FOGFLAT
|
1982 WINED3DPSHADECAPS_FOGGOURAUD
|
1983 WINED3DPSHADECAPS_SPECULARFLATRGB
;
1985 *pCaps
->TextureCaps
= WINED3DPTEXTURECAPS_ALPHA
|
1986 WINED3DPTEXTURECAPS_ALPHAPALETTE
|
1987 WINED3DPTEXTURECAPS_BORDER
|
1988 WINED3DPTEXTURECAPS_MIPMAP
|
1989 WINED3DPTEXTURECAPS_PROJECTED
|
1990 WINED3DPTEXTURECAPS_PERSPECTIVE
|
1991 WINED3DPTEXTURECAPS_NONPOW2CONDITIONAL
;
1993 if( GL_SUPPORT(EXT_TEXTURE3D
)) {
1994 *pCaps
->TextureCaps
|= WINED3DPTEXTURECAPS_VOLUMEMAP
|
1995 WINED3DPTEXTURECAPS_MIPVOLUMEMAP
|
1996 WINED3DPTEXTURECAPS_VOLUMEMAP_POW2
;
1999 if (GL_SUPPORT(ARB_TEXTURE_CUBE_MAP
)) {
2000 *pCaps
->TextureCaps
|= WINED3DPTEXTURECAPS_CUBEMAP
|
2001 WINED3DPTEXTURECAPS_MIPCUBEMAP
|
2002 WINED3DPTEXTURECAPS_CUBEMAP_POW2
;
2006 *pCaps
->TextureFilterCaps
= WINED3DPTFILTERCAPS_MAGFLINEAR
|
2007 WINED3DPTFILTERCAPS_MAGFPOINT
|
2008 WINED3DPTFILTERCAPS_MINFLINEAR
|
2009 WINED3DPTFILTERCAPS_MINFPOINT
|
2010 WINED3DPTFILTERCAPS_MIPFLINEAR
|
2011 WINED3DPTFILTERCAPS_MIPFPOINT
|
2012 WINED3DPTFILTERCAPS_LINEAR
|
2013 WINED3DPTFILTERCAPS_LINEARMIPLINEAR
|
2014 WINED3DPTFILTERCAPS_LINEARMIPNEAREST
|
2015 WINED3DPTFILTERCAPS_MIPLINEAR
|
2016 WINED3DPTFILTERCAPS_MIPNEAREST
|
2017 WINED3DPTFILTERCAPS_NEAREST
;
2019 if (GL_SUPPORT(EXT_TEXTURE_FILTER_ANISOTROPIC
)) {
2020 *pCaps
->TextureFilterCaps
|= WINED3DPTFILTERCAPS_MAGFANISOTROPIC
|
2021 WINED3DPTFILTERCAPS_MINFANISOTROPIC
;
2024 if (GL_SUPPORT(ARB_TEXTURE_CUBE_MAP
)) {
2025 *pCaps
->CubeTextureFilterCaps
= WINED3DPTFILTERCAPS_MAGFLINEAR
|
2026 WINED3DPTFILTERCAPS_MAGFPOINT
|
2027 WINED3DPTFILTERCAPS_MINFLINEAR
|
2028 WINED3DPTFILTERCAPS_MINFPOINT
|
2029 WINED3DPTFILTERCAPS_MIPFLINEAR
|
2030 WINED3DPTFILTERCAPS_MIPFPOINT
|
2031 WINED3DPTFILTERCAPS_LINEAR
|
2032 WINED3DPTFILTERCAPS_LINEARMIPLINEAR
|
2033 WINED3DPTFILTERCAPS_LINEARMIPNEAREST
|
2034 WINED3DPTFILTERCAPS_MIPLINEAR
|
2035 WINED3DPTFILTERCAPS_MIPNEAREST
|
2036 WINED3DPTFILTERCAPS_NEAREST
;
2038 if (GL_SUPPORT(EXT_TEXTURE_FILTER_ANISOTROPIC
)) {
2039 *pCaps
->CubeTextureFilterCaps
|= WINED3DPTFILTERCAPS_MAGFANISOTROPIC
|
2040 WINED3DPTFILTERCAPS_MINFANISOTROPIC
;
2043 *pCaps
->CubeTextureFilterCaps
= 0;
2045 if (GL_SUPPORT(EXT_TEXTURE3D
)) {
2046 *pCaps
->VolumeTextureFilterCaps
= WINED3DPTFILTERCAPS_MAGFLINEAR
|
2047 WINED3DPTFILTERCAPS_MAGFPOINT
|
2048 WINED3DPTFILTERCAPS_MINFLINEAR
|
2049 WINED3DPTFILTERCAPS_MINFPOINT
|
2050 WINED3DPTFILTERCAPS_MIPFLINEAR
|
2051 WINED3DPTFILTERCAPS_MIPFPOINT
|
2052 WINED3DPTFILTERCAPS_LINEAR
|
2053 WINED3DPTFILTERCAPS_LINEARMIPLINEAR
|
2054 WINED3DPTFILTERCAPS_LINEARMIPNEAREST
|
2055 WINED3DPTFILTERCAPS_MIPLINEAR
|
2056 WINED3DPTFILTERCAPS_MIPNEAREST
|
2057 WINED3DPTFILTERCAPS_NEAREST
;
2059 *pCaps
->VolumeTextureFilterCaps
= 0;
2061 *pCaps
->TextureAddressCaps
= D3DPTADDRESSCAPS_INDEPENDENTUV
|
2062 D3DPTADDRESSCAPS_CLAMP
|
2063 D3DPTADDRESSCAPS_WRAP
;
2065 if (GL_SUPPORT(ARB_TEXTURE_BORDER_CLAMP
)) {
2066 *pCaps
->TextureAddressCaps
|= D3DPTADDRESSCAPS_BORDER
;
2068 if (GL_SUPPORT(ARB_TEXTURE_MIRRORED_REPEAT
)) {
2069 *pCaps
->TextureAddressCaps
|= D3DPTADDRESSCAPS_MIRROR
;
2071 if (GL_SUPPORT(ATI_TEXTURE_MIRROR_ONCE
)) {
2072 *pCaps
->TextureAddressCaps
|= D3DPTADDRESSCAPS_MIRRORONCE
;
2075 if (GL_SUPPORT(EXT_TEXTURE3D
)) {
2076 *pCaps
->VolumeTextureAddressCaps
= D3DPTADDRESSCAPS_INDEPENDENTUV
|
2077 D3DPTADDRESSCAPS_CLAMP
|
2078 D3DPTADDRESSCAPS_WRAP
;
2079 if (GL_SUPPORT(ARB_TEXTURE_BORDER_CLAMP
)) {
2080 *pCaps
->VolumeTextureAddressCaps
|= D3DPTADDRESSCAPS_BORDER
;
2082 if (GL_SUPPORT(ARB_TEXTURE_MIRRORED_REPEAT
)) {
2083 *pCaps
->VolumeTextureAddressCaps
|= D3DPTADDRESSCAPS_MIRROR
;
2085 if (GL_SUPPORT(ATI_TEXTURE_MIRROR_ONCE
)) {
2086 *pCaps
->VolumeTextureAddressCaps
|= D3DPTADDRESSCAPS_MIRRORONCE
;
2089 *pCaps
->VolumeTextureAddressCaps
= 0;
2091 *pCaps
->LineCaps
= D3DLINECAPS_TEXTURE
|
2095 D3DLINECAPS_ALPHACMP
2098 *pCaps
->MaxTextureWidth
= GL_LIMITS(texture_size
);
2099 *pCaps
->MaxTextureHeight
= GL_LIMITS(texture_size
);
2101 if(GL_SUPPORT(EXT_TEXTURE3D
))
2102 *pCaps
->MaxVolumeExtent
= GL_LIMITS(texture3d_size
);
2104 *pCaps
->MaxVolumeExtent
= 0;
2106 *pCaps
->MaxTextureRepeat
= 32768;
2107 *pCaps
->MaxTextureAspectRatio
= GL_LIMITS(texture_size
);
2108 *pCaps
->MaxVertexW
= 1.0;
2110 *pCaps
->GuardBandLeft
= 0;
2111 *pCaps
->GuardBandTop
= 0;
2112 *pCaps
->GuardBandRight
= 0;
2113 *pCaps
->GuardBandBottom
= 0;
2115 *pCaps
->ExtentsAdjust
= 0;
2117 *pCaps
->StencilCaps
= D3DSTENCILCAPS_DECRSAT
|
2118 D3DSTENCILCAPS_INCRSAT
|
2119 D3DSTENCILCAPS_INVERT
|
2120 D3DSTENCILCAPS_KEEP
|
2121 D3DSTENCILCAPS_REPLACE
|
2122 D3DSTENCILCAPS_ZERO
;
2123 if (GL_SUPPORT(EXT_STENCIL_WRAP
)) {
2124 *pCaps
->StencilCaps
|= D3DSTENCILCAPS_DECR
|
2125 D3DSTENCILCAPS_INCR
;
2127 if ( This
->dxVersion
> 8 &&
2128 ( GL_SUPPORT(EXT_STENCIL_TWO_SIDE
) ||
2129 GL_SUPPORT(ATI_SEPARATE_STENCIL
) ) ) {
2130 *pCaps
->StencilCaps
|= D3DSTENCILCAPS_TWOSIDED
;
2133 *pCaps
->FVFCaps
= D3DFVFCAPS_PSIZE
| 0x0008; /* 8 texture coords */
2135 *pCaps
->TextureOpCaps
= D3DTEXOPCAPS_ADD
|
2136 D3DTEXOPCAPS_ADDSIGNED
|
2137 D3DTEXOPCAPS_ADDSIGNED2X
|
2138 D3DTEXOPCAPS_MODULATE
|
2139 D3DTEXOPCAPS_MODULATE2X
|
2140 D3DTEXOPCAPS_MODULATE4X
|
2141 D3DTEXOPCAPS_SELECTARG1
|
2142 D3DTEXOPCAPS_SELECTARG2
|
2143 D3DTEXOPCAPS_DISABLE
;
2145 if (GL_SUPPORT(ARB_TEXTURE_ENV_COMBINE
) ||
2146 GL_SUPPORT(EXT_TEXTURE_ENV_COMBINE
) ||
2147 GL_SUPPORT(NV_TEXTURE_ENV_COMBINE4
)) {
2148 *pCaps
->TextureOpCaps
|= D3DTEXOPCAPS_BLENDDIFFUSEALPHA
|
2149 D3DTEXOPCAPS_BLENDTEXTUREALPHA
|
2150 D3DTEXOPCAPS_BLENDFACTORALPHA
|
2151 D3DTEXOPCAPS_BLENDCURRENTALPHA
|
2153 D3DTEXOPCAPS_SUBTRACT
;
2155 if (GL_SUPPORT(NV_TEXTURE_ENV_COMBINE4
)) {
2156 *pCaps
->TextureOpCaps
|= D3DTEXOPCAPS_ADDSMOOTH
|
2157 D3DTEXOPCAPS_MULTIPLYADD
|
2158 D3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR
|
2159 D3DTEXOPCAPS_MODULATECOLOR_ADDALPHA
|
2160 D3DTEXOPCAPS_BLENDTEXTUREALPHAPM
;
2162 if (GL_SUPPORT(ARB_TEXTURE_ENV_DOT3
))
2163 *pCaps
->TextureOpCaps
|= D3DTEXOPCAPS_DOTPRODUCT3
;
2165 if (GL_SUPPORT(NV_REGISTER_COMBINERS
)) {
2166 *pCaps
->TextureOpCaps
|= D3DTEXOPCAPS_MODULATEINVALPHA_ADDCOLOR
|
2167 D3DTEXOPCAPS_MODULATEINVCOLOR_ADDALPHA
;
2172 *pCaps
->TextureOpCaps
|= D3DTEXOPCAPS_BUMPENVMAP
;
2174 D3DTEXOPCAPS_BUMPENVMAPLUMINANCE
2175 D3DTEXOPCAPS_PREMODULATE */
2178 *pCaps
->MaxTextureBlendStages
= GL_LIMITS(texture_stages
);
2179 *pCaps
->MaxSimultaneousTextures
= GL_LIMITS(textures
);
2180 *pCaps
->MaxUserClipPlanes
= GL_LIMITS(clipplanes
);
2181 *pCaps
->MaxActiveLights
= GL_LIMITS(lights
);
2185 #if 0 /* TODO: Blends support in drawprim */
2186 *pCaps
->MaxVertexBlendMatrices
= GL_LIMITS(blends
);
2188 *pCaps
->MaxVertexBlendMatrices
= 0;
2190 *pCaps
->MaxVertexBlendMatrixIndex
= 1;
2192 *pCaps
->MaxAnisotropy
= GL_LIMITS(anisotropy
);
2193 *pCaps
->MaxPointSize
= GL_LIMITS(pointsize
);
2196 *pCaps
->VertexProcessingCaps
= WINED3DVTXPCAPS_DIRECTIONALLIGHTS
|
2197 WINED3DVTXPCAPS_MATERIALSOURCE7
|
2198 WINED3DVTXPCAPS_POSITIONALLIGHTS
|
2199 WINED3DVTXPCAPS_LOCALVIEWER
|
2200 WINED3DVTXPCAPS_VERTEXFOG
|
2201 WINED3DVTXPCAPS_TEXGEN
;
2203 D3DVTXPCAPS_TWEENING, D3DVTXPCAPS_TEXGEN_SPHEREMAP */
2205 *pCaps
->MaxPrimitiveCount
= 0xFFFFF; /* For now set 2^20-1 which is used by most >=Geforce3/Radeon8500 cards */
2206 *pCaps
->MaxVertexIndex
= 0xFFFFF;
2207 *pCaps
->MaxStreams
= MAX_STREAMS
;
2208 *pCaps
->MaxStreamStride
= 1024;
2210 if (vs_selected_mode
== SHADER_GLSL
) {
2211 /* Nvidia Geforce6/7 or Ati R4xx/R5xx cards with GLSL support, support VS 3.0 but older Nvidia/Ati
2212 models with GLSL support only support 2.0. In case of nvidia we can detect VS 2.0 support using
2213 vs_nv_version which is based on NV_vertex_program. For Ati cards there's no easy way, so for
2214 now only support 2.0/3.0 detection on Nvidia GeforceFX cards and default to 3.0 for everything else */
2215 if(This
->gl_info
.vs_nv_version
== VS_VERSION_20
)
2216 *pCaps
->VertexShaderVersion
= WINED3DVS_VERSION(2,0);
2218 *pCaps
->VertexShaderVersion
= WINED3DVS_VERSION(3,0);
2219 TRACE_(d3d_caps
)("Hardware vertex shader version 3.0 enabled (GLSL)\n");
2220 } else if (vs_selected_mode
== SHADER_ARB
) {
2221 *pCaps
->VertexShaderVersion
= WINED3DVS_VERSION(1,1);
2222 TRACE_(d3d_caps
)("Hardware vertex shader version 1.1 enabled (ARB_PROGRAM)\n");
2223 } else if (vs_selected_mode
== SHADER_SW
) {
2224 *pCaps
->VertexShaderVersion
= WINED3DVS_VERSION(3,0);
2225 TRACE_(d3d_caps
)("Software vertex shader version 3.0 enabled\n");
2227 *pCaps
->VertexShaderVersion
= 0;
2228 TRACE_(d3d_caps
)("Vertex shader functionality not available\n");
2231 *pCaps
->MaxVertexShaderConst
= GL_LIMITS(vshader_constantsF
);
2233 if (ps_selected_mode
== SHADER_GLSL
) {
2234 /* See the comment about VS2.0/VS3.0 detection as we do the same here but then based on NV_fragment_program
2235 in case of GeforceFX cards. */
2236 if(This
->gl_info
.ps_nv_version
== PS_VERSION_20
)
2237 *pCaps
->PixelShaderVersion
= WINED3DPS_VERSION(2,0);
2239 *pCaps
->PixelShaderVersion
= WINED3DPS_VERSION(3,0);
2240 /* FIXME: The following line is card dependent. -1.0 to 1.0 is a safe default clamp range for now */
2241 *pCaps
->PixelShader1xMaxValue
= 1.0;
2242 TRACE_(d3d_caps
)("Hardware pixel shader version 3.0 enabled (GLSL)\n");
2243 } else if (ps_selected_mode
== SHADER_ARB
) {
2244 *pCaps
->PixelShaderVersion
= WINED3DPS_VERSION(1,4);
2245 *pCaps
->PixelShader1xMaxValue
= 1.0;
2246 TRACE_(d3d_caps
)("Hardware pixel shader version 1.4 enabled (ARB_PROGRAM)\n");
2247 /* FIXME: Uncomment this when there is support for software Pixel Shader 3.0 and PS_SW is defined
2248 } else if (ps_selected_mode = SHADER_SW) {
2249 *pCaps->PixelShaderVersion = WINED3DPS_VERSION(3,0);
2250 *pCaps->PixelShader1xMaxValue = 1.0;
2251 TRACE_(d3d_caps)("Software pixel shader version 3.0 enabled\n"); */
2253 *pCaps
->PixelShaderVersion
= 0;
2254 *pCaps
->PixelShader1xMaxValue
= 0.0;
2255 TRACE_(d3d_caps
)("Pixel shader functionality not available\n");
2258 /* ------------------------------------------------
2259 The following fields apply to d3d9 only
2260 ------------------------------------------------ */
2261 if (This
->dxVersion
> 8) {
2262 FIXME("Caps support for directx9 is nonexistent at the moment!\n");
2263 *pCaps
->DevCaps2
= 0;
2264 /* TODO: D3DDEVCAPS2_CAN_STRETCHRECT_FROM_TEXTURES and VS3.0 needs at least D3DDEVCAPS2_VERTEXELEMENTSCANSHARESTREAMOFFSET */
2265 *pCaps
->MaxNpatchTessellationLevel
= 0;
2266 *pCaps
->MasterAdapterOrdinal
= 0;
2267 *pCaps
->AdapterOrdinalInGroup
= 0;
2268 *pCaps
->NumberOfAdaptersInGroup
= 1;
2270 if(*pCaps
->VertexShaderVersion
>= WINED3DVS_VERSION(2,0)) {
2271 /* OpenGL supports all formats below, perhaps not always without conversion but it supports them.
2272 Further GLSL doesn't seem to have an official unsigned type as I'm not sure how we handle it
2273 don't advertise it yet. We might need to add some clamping in the shader engine to support it.
2274 TODO: D3DDTCAPS_USHORT2N, D3DDTCAPS_USHORT4N, D3DDTCAPS_UDEC3, D3DDTCAPS_DEC3N */
2275 *pCaps
->DeclTypes
= D3DDTCAPS_UBYTE4
|
2279 D3DDTCAPS_FLOAT16_2
|
2280 D3DDTCAPS_FLOAT16_4
;
2283 *pCaps
->DeclTypes
= 0;
2285 #if 0 /* We don't properly support multiple render targets yet, so disable this for now */
2286 if (GL_SUPPORT(ARB_DRAWBUFFERS
)) {
2287 *pCaps
->NumSimultaneousRTs
= GL_LIMITS(buffers
);
2290 *pCaps
->NumSimultaneousRTs
= 1;
2292 *pCaps
->StretchRectFilterCaps
= 0;
2293 *pCaps
->VertexTextureFilterCaps
= 0;
2295 if(*pCaps
->VertexShaderVersion
== WINED3DVS_VERSION(3,0)) {
2296 /* Where possible set the caps based on OpenGL extensions and if they aren't set (in case of software rendering)
2297 use the VS 3.0 from MSDN or else if there's OpenGL spec use a hardcoded value minimum VS3.0 value. */
2298 *pCaps
->VS20Caps
.Caps
= D3DVS20CAPS_PREDICATION
;
2299 *pCaps
->VS20Caps
.DynamicFlowControlDepth
= D3DVS20_MAX_DYNAMICFLOWCONTROLDEPTH
; /* VS 3.0 requires MAX_DYNAMICFLOWCONTROLDEPTH (24) */
2300 *pCaps
->VS20Caps
.NumTemps
= max(32, This
->gl_info
.vs_arb_max_temps
);
2301 *pCaps
->VS20Caps
.StaticFlowControlDepth
= D3DVS20_MAX_STATICFLOWCONTROLDEPTH
; /* level of nesting in loops / if-statements; VS 3.0 requires MAX (4) */
2303 *pCaps
->MaxVShaderInstructionsExecuted
= 65535; /* VS 3.0 needs at least 65535, some cards even use 2^32-1 */
2304 *pCaps
->MaxVertexShader30InstructionSlots
= max(512, This
->gl_info
.vs_arb_max_instructions
);
2305 } else if(*pCaps
->VertexShaderVersion
== WINED3DVS_VERSION(2,0)) {
2306 *pCaps
->VS20Caps
.Caps
= 0;
2307 *pCaps
->VS20Caps
.DynamicFlowControlDepth
= D3DVS20_MIN_DYNAMICFLOWCONTROLDEPTH
;
2308 *pCaps
->VS20Caps
.NumTemps
= max(12, This
->gl_info
.vs_arb_max_temps
);
2309 *pCaps
->VS20Caps
.StaticFlowControlDepth
= 1;
2311 *pCaps
->MaxVShaderInstructionsExecuted
= 65535;
2312 *pCaps
->MaxVertexShader30InstructionSlots
= 0;
2313 } else { /* VS 1.x */
2314 *pCaps
->VS20Caps
.Caps
= 0;
2315 *pCaps
->VS20Caps
.DynamicFlowControlDepth
= 0;
2316 *pCaps
->VS20Caps
.NumTemps
= 0;
2317 *pCaps
->VS20Caps
.StaticFlowControlDepth
= 0;
2319 *pCaps
->MaxVShaderInstructionsExecuted
= 0;
2320 *pCaps
->MaxVertexShader30InstructionSlots
= 0;
2323 if(*pCaps
->PixelShaderVersion
== WINED3DPS_VERSION(3,0)) {
2324 /* Where possible set the caps based on OpenGL extensions and if they aren't set (in case of software rendering)
2325 use the PS 3.0 from MSDN or else if there's OpenGL spec use a hardcoded value minimum PS 3.0 value. */
2327 /* 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 */
2328 *pCaps
->PS20Caps
.Caps
= D3DPS20CAPS_ARBITRARYSWIZZLE
|
2329 D3DPS20CAPS_GRADIENTINSTRUCTIONS
|
2330 D3DPS20CAPS_PREDICATION
|
2331 D3DPS20CAPS_NODEPENDENTREADLIMIT
|
2332 D3DPS20CAPS_NOTEXINSTRUCTIONLIMIT
;
2333 *pCaps
->PS20Caps
.DynamicFlowControlDepth
= D3DPS20_MAX_DYNAMICFLOWCONTROLDEPTH
; /* PS 3.0 requires MAX_DYNAMICFLOWCONTROLDEPTH (24) */
2334 *pCaps
->PS20Caps
.NumTemps
= max(32, This
->gl_info
.ps_arb_max_temps
);
2335 *pCaps
->PS20Caps
.StaticFlowControlDepth
= D3DPS20_MAX_STATICFLOWCONTROLDEPTH
; /* PS 3.0 requires MAX_STATICFLOWCONTROLDEPTH (4) */
2336 *pCaps
->PS20Caps
.NumInstructionSlots
= D3DPS20_MAX_NUMINSTRUCTIONSLOTS
; /* PS 3.0 requires MAX_NUMINSTRUCTIONSLOTS (512) */
2338 *pCaps
->MaxPShaderInstructionsExecuted
= 65535;
2339 *pCaps
->MaxPixelShader30InstructionSlots
= max(D3DMIN30SHADERINSTRUCTIONS
, This
->gl_info
.ps_arb_max_instructions
);
2340 } else if(*pCaps
->PixelShaderVersion
== WINED3DPS_VERSION(2,0)) {
2341 /* Below we assume PS2.0 specs, not extended 2.0a(GeforceFX)/2.0b(Radeon R3xx) ones */
2342 *pCaps
->PS20Caps
.Caps
= 0;
2343 *pCaps
->PS20Caps
.DynamicFlowControlDepth
= 0; /* D3DVS20_MIN_DYNAMICFLOWCONTROLDEPTH = 0 */
2344 *pCaps
->PS20Caps
.NumTemps
= max(12, This
->gl_info
.ps_arb_max_temps
);
2345 *pCaps
->PS20Caps
.StaticFlowControlDepth
= D3DPS20_MIN_STATICFLOWCONTROLDEPTH
; /* Minumum: 1 */
2346 *pCaps
->PS20Caps
.NumInstructionSlots
= D3DPS20_MIN_NUMINSTRUCTIONSLOTS
; /* Minimum number (64 ALU + 32 Texture), a GeforceFX uses 512 */
2348 *pCaps
->MaxPShaderInstructionsExecuted
= 512; /* Minimum value, a GeforceFX uses 1024 */
2349 *pCaps
->MaxPixelShader30InstructionSlots
= 0;
2350 } else { /* PS 1.x */
2351 *pCaps
->PS20Caps
.Caps
= 0;
2352 *pCaps
->PS20Caps
.DynamicFlowControlDepth
= 0;
2353 *pCaps
->PS20Caps
.NumTemps
= 0;
2354 *pCaps
->PS20Caps
.StaticFlowControlDepth
= 0;
2355 *pCaps
->PS20Caps
.NumInstructionSlots
= 0;
2357 *pCaps
->MaxPShaderInstructionsExecuted
= 0;
2358 *pCaps
->MaxPixelShader30InstructionSlots
= 0;
2366 /* Note due to structure differences between dx8 and dx9 D3DPRESENT_PARAMETERS,
2367 and fields being inserted in the middle, a new structure is used in place */
2368 static HRESULT WINAPI
IWineD3DImpl_CreateDevice(IWineD3D
*iface
, UINT Adapter
, WINED3DDEVTYPE DeviceType
, HWND hFocusWindow
,
2369 DWORD BehaviourFlags
, IWineD3DDevice
** ppReturnedDeviceInterface
,
2372 IWineD3DDeviceImpl
*object
= NULL
;
2373 IWineD3DImpl
*This
= (IWineD3DImpl
*)iface
;
2375 HRESULT temp_result
;
2377 /* Validate the adapter number */
2378 if (Adapter
>= IWineD3D_GetAdapterCount(iface
)) {
2379 return WINED3DERR_INVALIDCALL
;
2382 /* Create a WineD3DDevice object */
2383 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IWineD3DDeviceImpl
));
2384 *ppReturnedDeviceInterface
= (IWineD3DDevice
*)object
;
2385 TRACE("Created WineD3DDevice object @ %p\n", object
);
2386 if (NULL
== object
) {
2387 return WINED3DERR_OUTOFVIDEOMEMORY
;
2390 /* Set up initial COM information */
2391 object
->lpVtbl
= &IWineD3DDevice_Vtbl
;
2393 object
->wineD3D
= iface
;
2394 IWineD3D_AddRef(object
->wineD3D
);
2395 object
->parent
= parent
;
2397 /* Set the state up as invalid until the device is fully created */
2398 object
->state
= WINED3DERR_DRIVERINTERNALERROR
;
2400 TRACE("(%p)->(Adptr:%d, DevType: %x, FocusHwnd: %p, BehFlags: %x, RetDevInt: %p)\n", This
, Adapter
, DeviceType
,
2401 hFocusWindow
, BehaviourFlags
, ppReturnedDeviceInterface
);
2403 /* Save the creation parameters */
2404 object
->createParms
.AdapterOrdinal
= Adapter
;
2405 object
->createParms
.DeviceType
= DeviceType
;
2406 object
->createParms
.hFocusWindow
= hFocusWindow
;
2407 object
->createParms
.BehaviorFlags
= BehaviourFlags
;
2409 /* Initialize other useful values */
2410 object
->adapterNo
= Adapter
;
2411 object
->devType
= DeviceType
;
2413 TRACE("(%p) : Creating stateblock\n", This
);
2414 /* Creating the startup stateBlock - Note Special Case: 0 => Don't fill in yet! */
2415 if (WINED3D_OK
!= IWineD3DDevice_CreateStateBlock((IWineD3DDevice
*)object
,
2417 (IWineD3DStateBlock
**)&object
->stateBlock
,
2418 NULL
) || NULL
== object
->stateBlock
) { /* Note: No parent needed for initial internal stateblock */
2419 WARN("Failed to create stateblock\n");
2420 goto create_device_error
;
2422 TRACE("(%p) : Created stateblock (%p)\n", This
, object
->stateBlock
);
2423 object
->updateStateBlock
= object
->stateBlock
;
2424 IWineD3DStateBlock_AddRef((IWineD3DStateBlock
*)object
->updateStateBlock
);
2425 /* Setup surfaces for the backbuffer, frontbuffer and depthstencil buffer */
2427 /* Setup some defaults for creating the implicit swapchain */
2429 /* FIXME: GL info should be per adapter */
2430 IWineD3DImpl_FillGLCaps(iface
, IWineD3DImpl_GetAdapterDisplay(iface
, Adapter
));
2432 select_shader_mode(&This
->gl_info
, DeviceType
, &object
->ps_selected_mode
, &object
->vs_selected_mode
);
2433 if (object
->ps_selected_mode
== SHADER_GLSL
|| object
->vs_selected_mode
== SHADER_GLSL
) {
2434 object
->shader_backend
= &glsl_shader_backend
;
2435 } else if (object
->ps_selected_mode
== SHADER_ARB
|| object
->vs_selected_mode
== SHADER_ARB
) {
2436 object
->shader_backend
= &arb_program_shader_backend
;
2438 object
->shader_backend
= &none_shader_backend
;
2441 /* This function should *not* be modifying GL caps
2442 * TODO: move the functionality where it belongs */
2443 select_shader_max_constants(object
->ps_selected_mode
, object
->vs_selected_mode
, &This
->gl_info
);
2445 temp_result
= allocate_shader_constants(object
->updateStateBlock
);
2446 if (WINED3D_OK
!= temp_result
)
2449 /* set the state of the device to valid */
2450 object
->state
= WINED3D_OK
;
2452 /* Get the initial screen setup for ddraw */
2453 object
->ddraw_width
= GetSystemMetrics(SM_CXSCREEN
);
2454 object
->ddraw_height
= GetSystemMetrics(SM_CYSCREEN
);
2455 hDC
= CreateDCA("DISPLAY", NULL
, NULL
, NULL
);
2456 object
->ddraw_format
= pixelformat_for_depth(GetDeviceCaps(hDC
, BITSPIXEL
) * GetDeviceCaps(hDC
, PLANES
));
2460 create_device_error
:
2462 /* Set the device state to error */
2463 object
->state
= WINED3DERR_DRIVERINTERNALERROR
;
2465 if (object
->updateStateBlock
!= NULL
) {
2466 IWineD3DStateBlock_Release((IWineD3DStateBlock
*)object
->updateStateBlock
);
2467 object
->updateStateBlock
= NULL
;
2469 if (object
->stateBlock
!= NULL
) {
2470 IWineD3DStateBlock_Release((IWineD3DStateBlock
*)object
->stateBlock
);
2471 object
->stateBlock
= NULL
;
2473 if (object
->renderTarget
!= NULL
) {
2474 IWineD3DSurface_Release(object
->renderTarget
);
2475 object
->renderTarget
= NULL
;
2477 if (object
->stencilBufferTarget
!= NULL
) {
2478 IWineD3DSurface_Release(object
->stencilBufferTarget
);
2479 object
->stencilBufferTarget
= NULL
;
2481 HeapFree(GetProcessHeap(), 0, object
);
2482 *ppReturnedDeviceInterface
= NULL
;
2483 return WINED3DERR_INVALIDCALL
;
2487 static HRESULT WINAPI
IWineD3DImpl_GetParent(IWineD3D
*iface
, IUnknown
**pParent
) {
2488 IWineD3DImpl
*This
= (IWineD3DImpl
*)iface
;
2489 IUnknown_AddRef(This
->parent
);
2490 *pParent
= This
->parent
;
2494 /**********************************************************
2495 * IWineD3D VTbl follows
2496 **********************************************************/
2498 const IWineD3DVtbl IWineD3D_Vtbl
=
2501 IWineD3DImpl_QueryInterface
,
2502 IWineD3DImpl_AddRef
,
2503 IWineD3DImpl_Release
,
2505 IWineD3DImpl_GetParent
,
2506 IWineD3DImpl_GetAdapterCount
,
2507 IWineD3DImpl_RegisterSoftwareDevice
,
2508 IWineD3DImpl_GetAdapterMonitor
,
2509 IWineD3DImpl_GetAdapterModeCount
,
2510 IWineD3DImpl_EnumAdapterModes
,
2511 IWineD3DImpl_GetAdapterDisplayMode
,
2512 IWineD3DImpl_GetAdapterIdentifier
,
2513 IWineD3DImpl_CheckDeviceMultiSampleType
,
2514 IWineD3DImpl_CheckDepthStencilMatch
,
2515 IWineD3DImpl_CheckDeviceType
,
2516 IWineD3DImpl_CheckDeviceFormat
,
2517 IWineD3DImpl_CheckDeviceFormatConversion
,
2518 IWineD3DImpl_GetDeviceCaps
,
2519 IWineD3DImpl_CreateDevice