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*/
31 #include "wined3d_private.h"
33 WINE_DEFAULT_DEBUG_CHANNEL(d3d
);
34 WINE_DECLARE_DEBUG_CHANNEL(d3d_caps
);
35 #define GLINFO_LOCATION This->gl_info
37 /**********************************************************
38 * Utility functions follow
39 **********************************************************/
41 /* x11drv GDI escapes */
42 #define X11DRV_ESCAPE 6789
43 enum x11drv_escape_codes
45 X11DRV_GET_DISPLAY
, /* get X11 display for a DC */
46 X11DRV_GET_DRAWABLE
, /* get current drawable for a DC */
47 X11DRV_GET_FONT
, /* get current X font for a DC */
50 /* retrieve the X display to use on a given DC */
51 inline static Display
*get_display( HDC hdc
)
54 enum x11drv_escape_codes escape
= X11DRV_GET_DISPLAY
;
56 if (!ExtEscape( hdc
, X11DRV_ESCAPE
, sizeof(escape
), (LPCSTR
)&escape
,
57 sizeof(display
), (LPSTR
)&display
)) display
= NULL
;
62 int minLookup
[MAX_LOOKUPS
];
63 int maxLookup
[MAX_LOOKUPS
];
64 DWORD
*stateLookup
[MAX_LOOKUPS
];
66 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
75 static WineD3D_Context
* WineD3D_CreateFakeGLContext(void) {
76 static WineD3D_Context ctx
= { NULL
, NULL
, NULL
, 0, 0 };
77 WineD3D_Context
* ret
= NULL
;
79 if (glXGetCurrentContext() == NULL
) {
80 BOOL gotContext
= FALSE
;
87 XWindowAttributes win_attr
;
89 TRACE_(d3d_caps
)("Creating Fake GL Context\n");
91 ctx
.drawable
= (Drawable
) GetPropA(GetDesktopWindow(), "__wine_x11_whole_window");
94 device_context
= GetDC(0);
95 ctx
.display
= get_display(device_context
);
96 ReleaseDC(0, device_context
);
98 /* Get the X visual */
100 if (XGetWindowAttributes(ctx
.display
, ctx
.drawable
, &win_attr
)) {
101 visual
= win_attr
.visual
;
103 visual
= DefaultVisual(ctx
.display
, DefaultScreen(ctx
.display
));
105 template.visualid
= XVisualIDFromVisual(visual
);
106 ctx
.visInfo
= XGetVisualInfo(ctx
.display
, VisualIDMask
, &template, &num
);
107 if (ctx
.visInfo
== NULL
) {
109 WARN_(d3d_caps
)("Error creating visual info for capabilities initialization\n");
113 /* Create a GL context */
115 ctx
.glCtx
= glXCreateContext(ctx
.display
, ctx
.visInfo
, NULL
, GL_TRUE
);
117 if (ctx
.glCtx
== NULL
) {
119 WARN_(d3d_caps
)("Error creating default context for capabilities initialization\n");
124 /* Make it the current GL context */
125 if (!failed
&& glXMakeCurrent(ctx
.display
, ctx
.drawable
, ctx
.glCtx
) == False
) {
126 glXDestroyContext(ctx
.display
, ctx
.glCtx
);
128 WARN_(d3d_caps
)("Error setting default context as current for capabilities initialization\n");
132 /* It worked! Wow... */
142 if (ctx
.ref
> 0) ret
= &ctx
;
145 if (NULL
!= ret
) InterlockedIncrement(&ret
->ref
);
149 static void WineD3D_ReleaseFakeGLContext(WineD3D_Context
* ctx
) {
150 /* If we created a dummy context, throw it away */
152 if (0 == InterlockedDecrement(&ctx
->ref
)) {
153 glXMakeCurrent(ctx
->display
, None
, NULL
);
154 glXDestroyContext(ctx
->display
, ctx
->glCtx
);
162 /**********************************************************
163 * IUnknown parts follows
164 **********************************************************/
166 static HRESULT WINAPI
IWineD3DImpl_QueryInterface(IWineD3D
*iface
,REFIID riid
,LPVOID
*ppobj
)
168 IWineD3DDeviceImpl
*This
= (IWineD3DDeviceImpl
*)iface
;
170 TRACE("(%p)->(%s,%p)\n",This
,debugstr_guid(riid
),ppobj
);
171 if (IsEqualGUID(riid
, &IID_IUnknown
)
172 || IsEqualGUID(riid
, &IID_IWineD3DBase
)
173 || IsEqualGUID(riid
, &IID_IWineD3DDevice
)) {
174 IUnknown_AddRef(iface
);
179 return E_NOINTERFACE
;
182 static ULONG WINAPI
IWineD3DImpl_AddRef(IWineD3D
*iface
) {
183 IWineD3DImpl
*This
= (IWineD3DImpl
*)iface
;
184 ULONG refCount
= InterlockedIncrement(&This
->ref
);
186 TRACE("(%p) : AddRef increasing from %ld\n", This
, refCount
- 1);
190 static ULONG WINAPI
IWineD3DImpl_Release(IWineD3D
*iface
) {
191 IWineD3DImpl
*This
= (IWineD3DImpl
*)iface
;
193 TRACE("(%p) : Releasing from %ld\n", This
, This
->ref
);
194 ref
= InterlockedDecrement(&This
->ref
);
196 HeapFree(GetProcessHeap(), 0, This
);
202 /* Set the shader type for this device, depending on the given capabilities,
203 * the device type, and the user preferences in wined3d_settings */
205 static void select_shader_mode(
206 WineD3D_GL_Info
*gl_info
,
207 WINED3DDEVTYPE DeviceType
,
211 /* Give priority to user disable/emulation request.
212 * Then respect REF device for software.
213 * Then check capabilities for hardware, and fallback to software */
215 if (wined3d_settings
.vs_mode
== VS_NONE
) {
216 *vs_selected
= SHADER_NONE
;
217 } else if (DeviceType
== WINED3DDEVTYPE_REF
|| wined3d_settings
.vs_mode
== VS_SW
) {
218 *vs_selected
= SHADER_SW
;
219 } else if (gl_info
->supported
[ARB_VERTEX_SHADER
] && wined3d_settings
.glslRequested
) {
220 *vs_selected
= SHADER_GLSL
;
221 } else if (gl_info
->supported
[ARB_VERTEX_PROGRAM
]) {
222 *vs_selected
= SHADER_ARB
;
224 *vs_selected
= SHADER_SW
;
227 /* Fallback to SHADER_NONE where software pixel shaders should be used */
228 if (wined3d_settings
.ps_mode
== PS_NONE
) {
229 *ps_selected
= SHADER_NONE
;
230 } else if (DeviceType
== WINED3DDEVTYPE_REF
) {
231 *ps_selected
= SHADER_NONE
;
232 } else if (gl_info
->supported
[ARB_FRAGMENT_SHADER
] && wined3d_settings
.glslRequested
) {
233 *ps_selected
= SHADER_GLSL
;
234 } else if (gl_info
->supported
[ARB_FRAGMENT_PROGRAM
]) {
235 *ps_selected
= SHADER_ARB
;
237 *ps_selected
= SHADER_NONE
;
241 /** Select the number of report maximum shader constants based on the selected shader modes */
242 void select_shader_max_constants(WineD3D_GL_Info
*gl_info
) {
244 switch (wined3d_settings
.vs_selected_mode
) {
246 /* Subtract the other potential uniforms from the max available (bools, ints, and 1 row of projection matrix) */
247 gl_info
->max_vshader_constantsF
= gl_info
->vs_glsl_constantsF
- MAX_CONST_B
- MAX_CONST_I
- 1;
250 /* We have to subtract any other PARAMs that we might use in our shader programs.
251 * ATI seems to count 2 implicit PARAMs when we use fog and NVIDIA counts 1,
252 * and we reference one row of the PROJECTION matrix which counts as 1 PARAM. */
253 gl_info
->max_vshader_constantsF
= gl_info
->vs_arb_constantsF
- 3;
256 gl_info
->max_vshader_constantsF
= 96; /* TODO: Fixup software shaders */
259 gl_info
->max_vshader_constantsF
= 0;
263 switch (wined3d_settings
.ps_selected_mode
) {
265 /* Subtract the other potential uniforms from the max available (bools & ints) */
266 gl_info
->max_pshader_constantsF
= gl_info
->ps_glsl_constantsF
- MAX_CONST_B
- MAX_CONST_I
;
269 gl_info
->max_pshader_constantsF
= gl_info
->ps_arb_constantsF
;
272 gl_info
->max_pshader_constantsF
= 96; /* TODO: Fixup software shaders */
275 gl_info
->max_pshader_constantsF
= 0;
280 /**********************************************************
281 * IWineD3D parts follows
282 **********************************************************/
284 BOOL
IWineD3DImpl_FillGLCaps(IWineD3D
*iface
, Display
* display
) {
285 IWineD3DImpl
*This
= (IWineD3DImpl
*)iface
;
286 WineD3D_GL_Info
*gl_info
= &This
->gl_info
;
288 const char *GL_Extensions
= NULL
;
289 const char *GLX_Extensions
= NULL
;
290 const char *gl_string
= NULL
;
291 const char *gl_string_cursor
= NULL
;
296 WineD3D_Context
*fake_ctx
= NULL
;
297 BOOL gotContext
= FALSE
;
300 /* Make sure that we've got a context */
301 if (glXGetCurrentContext() == NULL
) {
302 /* TODO: CreateFakeGLContext should really take a display as a parameter */
303 fake_ctx
= WineD3D_CreateFakeGLContext();
304 if (NULL
!= fake_ctx
) gotContext
= TRUE
;
309 TRACE_(d3d_caps
)("(%p, %p)\n", gl_info
, display
);
311 gl_string
= (const char *) glGetString(GL_RENDERER
);
312 strcpy(gl_info
->gl_renderer
, gl_string
);
314 /* Fill in the GL info retrievable depending on the display */
315 if (NULL
!= display
) {
316 test
= glXQueryVersion(display
, &major
, &minor
);
317 gl_info
->glx_version
= ((major
& 0x0000FFFF) << 16) | (minor
& 0x0000FFFF);
319 FIXME("Display must not be NULL, use glXGetCurrentDisplay or getAdapterDisplay()\n");
321 gl_string
= (const char *) glGetString(GL_VENDOR
);
323 TRACE_(d3d_caps
)("Filling vendor string %s\n", gl_string
);
324 if (gl_string
!= NULL
) {
325 /* Fill in the GL vendor */
326 if (strstr(gl_string
, "NVIDIA")) {
327 gl_info
->gl_vendor
= VENDOR_NVIDIA
;
328 } else if (strstr(gl_string
, "ATI")) {
329 gl_info
->gl_vendor
= VENDOR_ATI
;
330 } else if (strstr(gl_string
, "Intel(R)") ||
331 strstr(gl_info
->gl_renderer
, "Intel(R)")) {
332 gl_info
->gl_vendor
= VENDOR_INTEL
;
333 } else if (strstr(gl_string
, "Mesa")) {
334 gl_info
->gl_vendor
= VENDOR_MESA
;
336 gl_info
->gl_vendor
= VENDOR_WINE
;
339 gl_info
->gl_vendor
= VENDOR_WINE
;
343 TRACE_(d3d_caps
)("found GL_VENDOR (%s)->(0x%04x)\n", debugstr_a(gl_string
), gl_info
->gl_vendor
);
345 /* Parse the GL_VERSION field into major and minor information */
346 gl_string
= (const char *) glGetString(GL_VERSION
);
347 if (gl_string
!= NULL
) {
349 switch (gl_info
->gl_vendor
) {
351 gl_string_cursor
= strstr(gl_string
, "NVIDIA");
352 if (!gl_string_cursor
) {
353 ERR_(d3d_caps
)("Invalid nVidia version string: %s\n", debugstr_a(gl_string
));
357 gl_string_cursor
= strstr(gl_string_cursor
, " ");
358 if (!gl_string_cursor
) {
359 ERR_(d3d_caps
)("Invalid nVidia version string: %s\n", debugstr_a(gl_string
));
363 while (*gl_string_cursor
== ' ') {
367 if (!*gl_string_cursor
) {
368 ERR_(d3d_caps
)("Invalid nVidia version string: %s\n", debugstr_a(gl_string
));
372 major
= atoi(gl_string_cursor
);
373 while (*gl_string_cursor
<= '9' && *gl_string_cursor
>= '0') {
377 if (*gl_string_cursor
++ != '.') {
378 ERR_(d3d_caps
)("Invalid nVidia version string: %s\n", debugstr_a(gl_string
));
382 minor
= atoi(gl_string_cursor
);
383 minor
= major
*100+minor
;
390 gl_string_cursor
= strchr(gl_string
, '-');
391 if (gl_string_cursor
) {
395 /* Check if version number is of the form x.y.z */
396 if (*gl_string_cursor
> '9' && *gl_string_cursor
< '0')
398 if (!error
&& *(gl_string_cursor
+2) > '9' && *(gl_string_cursor
+2) < '0')
400 if (!error
&& *(gl_string_cursor
+4) > '9' && *(gl_string_cursor
+4) < '0')
402 if (!error
&& *(gl_string_cursor
+1) != '.' && *(gl_string_cursor
+3) != '.')
405 /* Mark version number as malformed */
407 gl_string_cursor
= 0;
410 if (!gl_string_cursor
)
411 WARN_(d3d_caps
)("malformed GL_VERSION (%s)\n", debugstr_a(gl_string
));
413 major
= *gl_string_cursor
- '0';
414 minor
= (*(gl_string_cursor
+2) - '0') * 256 + (*(gl_string_cursor
+4) - '0');
420 gl_string_cursor
= strstr(gl_string
, "Mesa");
421 gl_string_cursor
= strstr(gl_string_cursor
, " ");
422 while (*gl_string_cursor
&& ' ' == *gl_string_cursor
) ++gl_string_cursor
;
423 if (*gl_string_cursor
) {
427 while (*gl_string_cursor
<= '9' && *gl_string_cursor
>= '0') {
428 tmp
[cursor
++] = *gl_string_cursor
;
434 if (*gl_string_cursor
!= '.') WARN_(d3d_caps
)("malformed GL_VERSION (%s)\n", debugstr_a(gl_string
));
438 while (*gl_string_cursor
<= '9' && *gl_string_cursor
>= '0') {
439 tmp
[cursor
++] = *gl_string_cursor
;
451 gl_info
->gl_driver_version
= MAKEDWORD_VERSION(major
, minor
);
452 TRACE_(d3d_caps
)("found GL_VERSION (%s)->%i.%i->(0x%08lx)\n", debugstr_a(gl_string
), major
, minor
, gl_info
->gl_driver_version
);
454 /* Fill in the renderer information */
456 switch (gl_info
->gl_vendor
) {
458 if (strstr(gl_info
->gl_renderer
, "GeForce4 Ti")) {
459 gl_info
->gl_card
= CARD_NVIDIA_GEFORCE4_TI4600
;
460 } else if (strstr(gl_info
->gl_renderer
, "GeForceFX")) {
461 gl_info
->gl_card
= CARD_NVIDIA_GEFORCEFX_5900ULTRA
;
462 } else if (strstr(gl_info
->gl_renderer
, "Quadro FX 3000")) {
463 gl_info
->gl_card
= CARD_NVIDIA_QUADROFX_3000
;
464 } else if (strstr(gl_info
->gl_renderer
, "GeForce 6800")) {
465 gl_info
->gl_card
= CARD_NVIDIA_GEFORCE_6800ULTRA
;
466 } else if (strstr(gl_info
->gl_renderer
, "Quadro FX 4000")) {
467 gl_info
->gl_card
= CARD_NVIDIA_QUADROFX_4000
;
468 } else if (strstr(gl_info
->gl_renderer
, "GeForce 7800")) {
469 gl_info
->gl_card
= CARD_NVIDIA_GEFORCE_7800ULTRA
;
471 gl_info
->gl_card
= CARD_NVIDIA_GEFORCE4_TI4600
;
476 if (strstr(gl_info
->gl_renderer
, "RADEON 9800 PRO")) {
477 gl_info
->gl_card
= CARD_ATI_RADEON_9800PRO
;
478 } else if (strstr(gl_info
->gl_renderer
, "RADEON 9700 PRO")) {
479 gl_info
->gl_card
= CARD_ATI_RADEON_9700PRO
;
481 gl_info
->gl_card
= CARD_ATI_RADEON_8500
;
486 if (strstr(gl_info
->gl_renderer
, "915GM")) {
487 gl_info
->gl_card
= CARD_INTEL_I915GM
;
488 } else if (strstr(gl_info
->gl_renderer
, "915G")) {
489 gl_info
->gl_card
= CARD_INTEL_I915G
;
490 } else if (strstr(gl_info
->gl_renderer
, "865G")) {
491 gl_info
->gl_card
= CARD_INTEL_I865G
;
492 } else if (strstr(gl_info
->gl_renderer
, "855G")) {
493 gl_info
->gl_card
= CARD_INTEL_I855G
;
494 } else if (strstr(gl_info
->gl_renderer
, "830G")) {
495 gl_info
->gl_card
= CARD_INTEL_I830G
;
497 gl_info
->gl_card
= CARD_INTEL_I915G
;
502 gl_info
->gl_card
= CARD_WINE
;
506 FIXME("get version string returned null\n");
509 TRACE_(d3d_caps
)("found GL_RENDERER (%s)->(0x%04x)\n", debugstr_a(gl_info
->gl_renderer
), gl_info
->gl_card
);
512 * Initialize openGL extension related variables
513 * with Default values
515 memset(&gl_info
->supported
, 0, sizeof(gl_info
->supported
));
516 gl_info
->max_textures
= 1;
517 gl_info
->max_texture_stages
= 1;
518 gl_info
->max_samplers
= 1;
519 gl_info
->max_sampler_stages
= 1;
520 gl_info
->ps_arb_version
= PS_VERSION_NOT_SUPPORTED
;
521 gl_info
->vs_arb_version
= VS_VERSION_NOT_SUPPORTED
;
522 gl_info
->vs_nv_version
= VS_VERSION_NOT_SUPPORTED
;
523 gl_info
->vs_ati_version
= VS_VERSION_NOT_SUPPORTED
;
524 gl_info
->vs_glsl_constantsF
= 0;
525 gl_info
->ps_glsl_constantsF
= 0;
526 gl_info
->vs_arb_constantsF
= 0;
527 gl_info
->ps_arb_constantsF
= 0;
529 /* Now work out what GL support this card really has */
530 #define USE_GL_FUNC(type, pfn) gl_info->pfn = (type) glXGetProcAddressARB( (const GLubyte *) #pfn);
535 /* Retrieve opengl defaults */
536 glGetIntegerv(GL_MAX_CLIP_PLANES
, &gl_max
);
537 gl_info
->max_clipplanes
= min(D3DMAXUSERCLIPPLANES
, gl_max
);
538 TRACE_(d3d_caps
)("ClipPlanes support - num Planes=%d\n", gl_max
);
540 glGetIntegerv(GL_MAX_LIGHTS
, &gl_max
);
541 gl_info
->max_lights
= gl_max
;
542 TRACE_(d3d_caps
)("Lights support - max lights=%d\n", gl_max
);
544 glGetIntegerv(GL_MAX_TEXTURE_SIZE
, &gl_max
);
545 gl_info
->max_texture_size
= gl_max
;
546 TRACE_(d3d_caps
)("Maximum texture size support - max texture size=%d\n", gl_max
);
548 glGetFloatv(GL_POINT_SIZE_RANGE
, &gl_float
);
549 gl_info
->max_pointsize
= gl_float
;
550 TRACE_(d3d_caps
)("Maximum point size support - max texture size=%f\n", gl_float
);
552 /* Parse the gl supported features, in theory enabling parts of our code appropriately */
553 GL_Extensions
= (const char *) glGetString(GL_EXTENSIONS
);
554 TRACE_(d3d_caps
)("GL_Extensions reported:\n");
556 if (NULL
== GL_Extensions
) {
557 ERR(" GL_Extensions returns NULL\n");
559 while (*GL_Extensions
!= 0x00) {
560 const char *Start
= GL_Extensions
;
563 memset(ThisExtn
, 0x00, sizeof(ThisExtn
));
564 while (*GL_Extensions
!= ' ' && *GL_Extensions
!= 0x00) {
567 memcpy(ThisExtn
, Start
, (GL_Extensions
- Start
));
568 TRACE_(d3d_caps
)("- %s\n", ThisExtn
);
573 if (strcmp(ThisExtn
, "GL_ARB_fragment_program") == 0) {
574 gl_info
->ps_arb_version
= PS_VERSION_11
;
575 TRACE_(d3d_caps
)(" FOUND: ARB Pixel Shader support - version=%02x\n", gl_info
->ps_arb_version
);
576 gl_info
->supported
[ARB_FRAGMENT_PROGRAM
] = TRUE
;
577 glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS_ARB
, &gl_max
);
578 TRACE_(d3d_caps
)(" FOUND: ARB Pixel Shader support - GL_MAX_TEXTURE_IMAGE_UNITS_ARB=%u\n", gl_max
);
579 gl_info
->max_samplers
= min(MAX_SAMPLERS
, gl_max
);
580 GL_EXTCALL(glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB
, GL_MAX_PROGRAM_ENV_PARAMETERS_ARB
, &gl_max
));
581 TRACE_(d3d_caps
)(" FOUND: ARB Pixel Shader support - max float constants=%u\n", gl_max
);
582 gl_info
->ps_arb_constantsF
= gl_max
;
583 } else if (strcmp(ThisExtn
, "GL_ARB_fragment_shader") == 0) {
584 gl_info
->supported
[ARB_FRAGMENT_SHADER
] = TRUE
;
585 glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB
, &gl_max
);
586 TRACE_(d3d_caps
)(" FOUND: ARB_fragment_shader (GLSL) support - max float ps constants=%u\n", gl_max
);
587 gl_info
->ps_glsl_constantsF
= gl_max
;
588 } else if (strcmp(ThisExtn
, "GL_ARB_imaging") == 0) {
589 TRACE_(d3d_caps
)(" FOUND: ARB imaging support\n");
590 gl_info
->supported
[ARB_IMAGING
] = TRUE
;
591 } else if (strcmp(ThisExtn
, "GL_ARB_multisample") == 0) {
592 TRACE_(d3d_caps
)(" FOUND: ARB Multisample support\n");
593 gl_info
->supported
[ARB_MULTISAMPLE
] = TRUE
;
594 } else if (strcmp(ThisExtn
, "GL_ARB_multitexture") == 0) {
595 glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB
, &gl_max
);
596 TRACE_(d3d_caps
)(" FOUND: ARB Multitexture support - GL_MAX_TEXTURE_UNITS_ARB=%u\n", gl_max
);
597 gl_info
->supported
[ARB_MULTITEXTURE
] = TRUE
;
598 gl_info
->max_textures
= min(MAX_TEXTURES
, gl_max
);
599 gl_info
->max_texture_stages
= min(MAX_TEXTURES
, gl_max
);
600 gl_info
->max_samplers
= max(gl_info
->max_samplers
, gl_max
);
601 } else if (strcmp(ThisExtn
, "GL_ARB_texture_cube_map") == 0) {
602 TRACE_(d3d_caps
)(" FOUND: ARB Texture Cube Map support\n");
603 gl_info
->supported
[ARB_TEXTURE_CUBE_MAP
] = TRUE
;
604 TRACE_(d3d_caps
)(" IMPLIED: NVIDIA (NV) Texture Gen Reflection support\n");
605 gl_info
->supported
[NV_TEXGEN_REFLECTION
] = TRUE
;
606 } else if (strcmp(ThisExtn
, "GL_ARB_texture_compression") == 0) {
607 TRACE_(d3d_caps
)(" FOUND: ARB Texture Compression support\n");
608 gl_info
->supported
[ARB_TEXTURE_COMPRESSION
] = TRUE
;
609 } else if (strcmp(ThisExtn
, "GL_ARB_texture_env_add") == 0) {
610 TRACE_(d3d_caps
)(" FOUND: ARB Texture Env Add support\n");
611 gl_info
->supported
[ARB_TEXTURE_ENV_ADD
] = TRUE
;
612 } else if (strcmp(ThisExtn
, "GL_ARB_texture_env_combine") == 0) {
613 TRACE_(d3d_caps
)(" FOUND: ARB Texture Env combine support\n");
614 gl_info
->supported
[ARB_TEXTURE_ENV_COMBINE
] = TRUE
;
615 } else if (strcmp(ThisExtn
, "GL_ARB_texture_env_dot3") == 0) {
616 TRACE_(d3d_caps
)(" FOUND: ARB Dot3 support\n");
617 gl_info
->supported
[ARB_TEXTURE_ENV_DOT3
] = TRUE
;
618 } else if (strcmp(ThisExtn
, "GL_ARB_texture_border_clamp") == 0) {
619 TRACE_(d3d_caps
)(" FOUND: ARB Texture border clamp support\n");
620 gl_info
->supported
[ARB_TEXTURE_BORDER_CLAMP
] = TRUE
;
621 } else if (strcmp(ThisExtn
, "GL_ARB_texture_mirrored_repeat") == 0) {
622 TRACE_(d3d_caps
)(" FOUND: ARB Texture mirrored repeat support\n");
623 gl_info
->supported
[ARB_TEXTURE_MIRRORED_REPEAT
] = TRUE
;
624 } else if (strcmp(ThisExtn
, "GLX_ARB_multisample") == 0) {
625 TRACE_(d3d_caps
)(" FOUND: ARB multisample support\n");
626 gl_info
->supported
[ARB_MULTISAMPLE
] = TRUE
;
627 } else if (strcmp(ThisExtn
, "GL_ARB_pixel_buffer_object") == 0) {
628 TRACE_(d3d_caps
)(" FOUND: ARB Pixel Buffer support\n");
629 gl_info
->supported
[ARB_PIXEL_BUFFER_OBJECT
] = TRUE
;
630 } else if (strcmp(ThisExtn
, "GL_ARB_point_sprite") == 0) {
631 TRACE_(d3d_caps
)(" FOUND: ARB point sprite support\n");
632 gl_info
->supported
[ARB_POINT_SPRITE
] = TRUE
;
633 } else if (strstr(ThisExtn
, "GL_ARB_vertex_program")) {
634 gl_info
->vs_arb_version
= VS_VERSION_11
;
635 TRACE_(d3d_caps
)(" FOUND: ARB Vertex Shader support - version=%02x\n", gl_info
->vs_arb_version
);
636 gl_info
->supported
[ARB_VERTEX_PROGRAM
] = TRUE
;
637 GL_EXTCALL(glGetProgramivARB(GL_VERTEX_PROGRAM_ARB
, GL_MAX_PROGRAM_ENV_PARAMETERS_ARB
, &gl_max
));
638 TRACE_(d3d_caps
)(" FOUND: ARB Vertex Shader support - max float constants=%u\n", gl_max
);
639 gl_info
->vs_arb_constantsF
= gl_max
;
640 } else if (strcmp(ThisExtn
, "GL_ARB_vertex_shader") == 0) {
641 gl_info
->supported
[ARB_VERTEX_SHADER
] = TRUE
;
642 glGetIntegerv(GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB
, &gl_max
);
643 TRACE_(d3d_caps
)(" FOUND: ARB_vertex_shader (GLSL) support - max float vs constants=%u\n", gl_max
);
644 gl_info
->vs_glsl_constantsF
= gl_max
;
645 } else if (strcmp(ThisExtn
, "GL_ARB_vertex_blend") == 0) {
646 glGetIntegerv(GL_MAX_VERTEX_UNITS_ARB
, &gl_max
);
647 TRACE_(d3d_caps
)(" FOUND: ARB Vertex Blend support GL_MAX_VERTEX_UNITS_ARB %d\n", gl_max
);
648 gl_info
->max_blends
= gl_max
;
649 gl_info
->supported
[ARB_VERTEX_BLEND
] = TRUE
;
650 } else if (strcmp(ThisExtn
, "GL_ARB_vertex_buffer_object") == 0) {
651 TRACE_(d3d_caps
)(" FOUND: ARB Vertex Buffer support\n");
652 gl_info
->supported
[ARB_VERTEX_BUFFER_OBJECT
] = TRUE
;
653 } else if (strcmp(ThisExtn
, "GL_ARB_occlusion_query") == 0) {
654 TRACE_(d3d_caps
)(" FOUND: ARB Occlusion Query support\n");
655 gl_info
->supported
[ARB_OCCLUSION_QUERY
] = TRUE
;
656 } else if (strcmp(ThisExtn
, "GL_ARB_point_parameters") == 0) {
657 TRACE_(d3d_caps
)(" FOUND: ARB Point parameters support\n");
658 gl_info
->supported
[ARB_POINT_PARAMETERS
] = TRUE
;
662 } else if (strcmp(ThisExtn
, "GL_EXT_fog_coord") == 0) {
663 TRACE_(d3d_caps
)(" FOUND: EXT Fog coord support\n");
664 gl_info
->supported
[EXT_FOG_COORD
] = TRUE
;
665 } else if (strcmp(ThisExtn
, "GL_EXT_framebuffer_object") == 0) {
666 TRACE_(d3d_caps
)(" FOUND: EXT Frame Buffer Object support\n");
667 gl_info
->supported
[EXT_FRAMEBUFFER_OBJECT
] = TRUE
;
668 } else if (strcmp(ThisExtn
, "GL_EXT_paletted_texture") == 0) { /* handle paletted texture extensions */
669 TRACE_(d3d_caps
)(" FOUND: EXT Paletted texture support\n");
670 gl_info
->supported
[EXT_PALETTED_TEXTURE
] = TRUE
;
671 } else if (strcmp(ThisExtn
, "GL_EXT_point_parameters") == 0) {
672 TRACE_(d3d_caps
)(" FOUND: EXT Point parameters support\n");
673 gl_info
->supported
[EXT_POINT_PARAMETERS
] = TRUE
;
674 } else if (strcmp(ThisExtn
, "GL_EXT_secondary_color") == 0) {
675 TRACE_(d3d_caps
)(" FOUND: EXT Secondary coord support\n");
676 gl_info
->supported
[EXT_SECONDARY_COLOR
] = TRUE
;
677 } else if (strcmp(ThisExtn
, "GL_EXT_stencil_two_side") == 0) {
678 TRACE_(d3d_caps
)(" FOUND: EXT Stencil two side support\n");
679 gl_info
->supported
[EXT_STENCIL_TWO_SIDE
] = TRUE
;
680 } else if (strcmp(ThisExtn
, "GL_EXT_stencil_wrap") == 0) {
681 TRACE_(d3d_caps
)(" FOUND: EXT Stencil wrap support\n");
682 gl_info
->supported
[EXT_STENCIL_WRAP
] = TRUE
;
683 } else if (strcmp(ThisExtn
, "GL_EXT_texture3D") == 0) {
684 TRACE_(d3d_caps
)(" FOUND: EXT_texture3D support\n");
685 gl_info
->supported
[EXT_TEXTURE3D
] = TRUE
;
686 } else if (strcmp(ThisExtn
, "GL_EXT_texture_compression_s3tc") == 0) {
687 TRACE_(d3d_caps
)(" FOUND: EXT Texture S3TC compression support\n");
688 gl_info
->supported
[EXT_TEXTURE_COMPRESSION_S3TC
] = TRUE
;
689 } else if (strcmp(ThisExtn
, "GL_EXT_texture_env_add") == 0) {
690 TRACE_(d3d_caps
)(" FOUND: EXT Texture Env Add support\n");
691 gl_info
->supported
[EXT_TEXTURE_ENV_ADD
] = TRUE
;
692 } else if (strcmp(ThisExtn
, "GL_EXT_texture_env_combine") == 0) {
693 TRACE_(d3d_caps
)(" FOUND: EXT Texture Env combine support\n");
694 gl_info
->supported
[EXT_TEXTURE_ENV_COMBINE
] = TRUE
;
695 } else if (strcmp(ThisExtn
, "GL_EXT_texture_env_dot3") == 0) {
696 TRACE_(d3d_caps
)(" FOUND: EXT Dot3 support\n");
697 gl_info
->supported
[EXT_TEXTURE_ENV_DOT3
] = TRUE
;
698 } else if (strcmp(ThisExtn
, "GL_EXT_texture_filter_anisotropic") == 0) {
699 gl_info
->supported
[EXT_TEXTURE_FILTER_ANISOTROPIC
] = TRUE
;
700 glGetIntegerv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT
, &gl_max
);
701 TRACE_(d3d_caps
)(" FOUND: EXT Texture Anisotropic filter support. GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT %d\n", gl_max
);
702 gl_info
->max_anisotropy
= gl_max
;
703 } else if (strcmp(ThisExtn
, "GL_EXT_texture_lod") == 0) {
704 TRACE_(d3d_caps
)(" FOUND: EXT Texture LOD support\n");
705 gl_info
->supported
[EXT_TEXTURE_LOD
] = TRUE
;
706 } else if (strcmp(ThisExtn
, "GL_EXT_texture_lod_bias") == 0) {
707 TRACE_(d3d_caps
)(" FOUND: EXT Texture LOD bias support\n");
708 gl_info
->supported
[EXT_TEXTURE_LOD_BIAS
] = TRUE
;
709 } else if (strcmp(ThisExtn
, "GL_EXT_vertex_weighting") == 0) {
710 TRACE_(d3d_caps
)(" FOUND: EXT Vertex weighting support\n");
711 gl_info
->supported
[EXT_VERTEX_WEIGHTING
] = TRUE
;
716 } else if (strstr(ThisExtn
, "GL_NV_fog_distance")) {
717 TRACE_(d3d_caps
)(" FOUND: NVIDIA (NV) Fog Distance support\n");
718 gl_info
->supported
[NV_FOG_DISTANCE
] = TRUE
;
719 } else if (strstr(ThisExtn
, "GL_NV_fragment_program")) {
720 gl_info
->ps_nv_version
= PS_VERSION_11
;
721 TRACE_(d3d_caps
)(" FOUND: NVIDIA (NV) Pixel Shader support - version=%02x\n", gl_info
->ps_nv_version
);
722 } else if (strcmp(ThisExtn
, "GL_NV_register_combiners") == 0) {
723 glGetIntegerv(GL_MAX_GENERAL_COMBINERS_NV
, &gl_max
);
724 gl_info
->max_texture_stages
= min(MAX_TEXTURES
, gl_max
);
725 TRACE_(d3d_caps
)(" FOUND: NVIDIA (NV) Register combiners (1) support - GL_MAX_GENERAL_COMBINERS_NV=%d\n", gl_max
);
726 gl_info
->supported
[NV_REGISTER_COMBINERS
] = TRUE
;
727 } else if (strcmp(ThisExtn
, "GL_NV_register_combiners2") == 0) {
728 TRACE_(d3d_caps
)(" FOUND: NVIDIA (NV) Register combiners (2) support\n");
729 gl_info
->supported
[NV_REGISTER_COMBINERS2
] = TRUE
;
730 } else if (strcmp(ThisExtn
, "GL_NV_texgen_reflection") == 0) {
731 TRACE_(d3d_caps
)(" FOUND: NVIDIA (NV) Texture Gen Reflection support\n");
732 gl_info
->supported
[NV_TEXGEN_REFLECTION
] = TRUE
;
733 } else if (strcmp(ThisExtn
, "GL_NV_texture_env_combine4") == 0) {
734 TRACE_(d3d_caps
)(" FOUND: NVIDIA (NV) Texture Env combine (4) support\n");
735 gl_info
->supported
[NV_TEXTURE_ENV_COMBINE4
] = TRUE
;
736 } else if (strcmp(ThisExtn
, "GL_NV_texture_shader") == 0) {
737 TRACE_(d3d_caps
)(" FOUND: NVIDIA (NV) Texture Shader (1) support\n");
738 gl_info
->supported
[NV_TEXTURE_SHADER
] = TRUE
;
739 } else if (strcmp(ThisExtn
, "GL_NV_texture_shader2") == 0) {
740 TRACE_(d3d_caps
)(" FOUND: NVIDIA (NV) Texture Shader (2) support\n");
741 gl_info
->supported
[NV_TEXTURE_SHADER2
] = TRUE
;
742 } else if (strcmp(ThisExtn
, "GL_NV_texture_shader3") == 0) {
743 TRACE_(d3d_caps
)(" FOUND: NVIDIA (NV) Texture Shader (3) support\n");
744 gl_info
->supported
[NV_TEXTURE_SHADER3
] = TRUE
;
745 } else if (strcmp(ThisExtn
, "GL_NV_occlusion_query") == 0) {
746 TRACE_(d3d_caps
)(" FOUND: NVIDIA (NV) Occlusion Query (3) support\n");
747 gl_info
->supported
[NV_OCCLUSION_QUERY
] = TRUE
;
748 } else if (strstr(ThisExtn
, "GL_NV_vertex_program")) {
749 gl_info
->vs_nv_version
= max(gl_info
->vs_nv_version
, (0 == strcmp(ThisExtn
, "GL_NV_vertex_program1_1")) ? VS_VERSION_11
: VS_VERSION_10
);
750 gl_info
->vs_nv_version
= max(gl_info
->vs_nv_version
, (0 == strcmp(ThisExtn
, "GL_NV_vertex_program2")) ? VS_VERSION_20
: VS_VERSION_10
);
751 TRACE_(d3d_caps
)(" FOUND: NVIDIA (NV) Vertex Shader support - version=%02x\n", gl_info
->vs_nv_version
);
752 gl_info
->supported
[NV_VERTEX_PROGRAM
] = TRUE
;
758 } else if (strcmp(ThisExtn
, "GL_ATI_separate_stencil") == 0) {
759 TRACE_(d3d_caps
)(" FOUND: ATI Separate stencil support\n");
760 gl_info
->supported
[ATI_SEPARATE_STENCIL
] = TRUE
;
761 } else if (strcmp(ThisExtn
, "GL_ATI_texture_env_combine3") == 0) {
762 TRACE_(d3d_caps
)(" FOUND: ATI Texture Env combine (3) support\n");
763 gl_info
->supported
[ATI_TEXTURE_ENV_COMBINE3
] = TRUE
;
764 } else if (strcmp(ThisExtn
, "GL_ATI_texture_mirror_once") == 0) {
765 TRACE_(d3d_caps
)(" FOUND: ATI Texture Mirror Once support\n");
766 gl_info
->supported
[ATI_TEXTURE_MIRROR_ONCE
] = TRUE
;
767 } else if (strcmp(ThisExtn
, "GL_EXT_vertex_shader") == 0) {
768 gl_info
->vs_ati_version
= VS_VERSION_11
;
769 TRACE_(d3d_caps
)(" FOUND: ATI (EXT) Vertex Shader support - version=%02x\n", gl_info
->vs_ati_version
);
770 gl_info
->supported
[EXT_VERTEX_SHADER
] = TRUE
;
774 if (*GL_Extensions
== ' ') GL_Extensions
++;
777 checkGLcall("extension detection\n");
779 gl_info
->max_sampler_stages
= max(gl_info
->max_samplers
, gl_info
->max_texture_stages
);
781 /* Load all the lookup tables
782 TODO: It may be a good idea to make minLookup and maxLookup const and populate them in wined3d_private.h where they are declared */
783 minLookup
[WINELOOKUP_WARPPARAM
] = D3DTADDRESS_WRAP
;
784 maxLookup
[WINELOOKUP_WARPPARAM
] = D3DTADDRESS_MIRRORONCE
;
786 minLookup
[WINELOOKUP_MAGFILTER
] = WINED3DTEXF_NONE
;
787 maxLookup
[WINELOOKUP_MAGFILTER
] = WINED3DTEXF_ANISOTROPIC
;
790 for (i
= 0; i
< MAX_LOOKUPS
; i
++) {
791 stateLookup
[i
] = HeapAlloc(GetProcessHeap(), 0, sizeof(*stateLookup
[i
]) * (1 + maxLookup
[i
] - minLookup
[i
]) );
794 stateLookup
[WINELOOKUP_WARPPARAM
][D3DTADDRESS_WRAP
- minLookup
[WINELOOKUP_WARPPARAM
]] = GL_REPEAT
;
795 stateLookup
[WINELOOKUP_WARPPARAM
][D3DTADDRESS_CLAMP
- minLookup
[WINELOOKUP_WARPPARAM
]] = GL_CLAMP_TO_EDGE
;
796 stateLookup
[WINELOOKUP_WARPPARAM
][D3DTADDRESS_BORDER
- minLookup
[WINELOOKUP_WARPPARAM
]] =
797 gl_info
->supported
[ARB_TEXTURE_BORDER_CLAMP
] ? GL_CLAMP_TO_BORDER_ARB
: GL_REPEAT
;
798 stateLookup
[WINELOOKUP_WARPPARAM
][D3DTADDRESS_BORDER
- minLookup
[WINELOOKUP_WARPPARAM
]] =
799 gl_info
->supported
[ARB_TEXTURE_BORDER_CLAMP
] ? GL_CLAMP_TO_BORDER_ARB
: GL_REPEAT
;
800 stateLookup
[WINELOOKUP_WARPPARAM
][D3DTADDRESS_MIRROR
- minLookup
[WINELOOKUP_WARPPARAM
]] =
801 gl_info
->supported
[ARB_TEXTURE_MIRRORED_REPEAT
] ? GL_MIRRORED_REPEAT_ARB
: GL_REPEAT
;
802 stateLookup
[WINELOOKUP_WARPPARAM
][D3DTADDRESS_MIRRORONCE
- minLookup
[WINELOOKUP_WARPPARAM
]] =
803 gl_info
->supported
[ATI_TEXTURE_MIRROR_ONCE
] ? GL_MIRROR_CLAMP_TO_EDGE_ATI
: GL_REPEAT
;
805 stateLookup
[WINELOOKUP_MAGFILTER
][WINED3DTEXF_NONE
- minLookup
[WINELOOKUP_MAGFILTER
]] = GL_NEAREST
;
806 stateLookup
[WINELOOKUP_MAGFILTER
][WINED3DTEXF_POINT
- minLookup
[WINELOOKUP_MAGFILTER
]] = GL_NEAREST
;
807 stateLookup
[WINELOOKUP_MAGFILTER
][WINED3DTEXF_LINEAR
- minLookup
[WINELOOKUP_MAGFILTER
]] = GL_LINEAR
;
808 stateLookup
[WINELOOKUP_MAGFILTER
][WINED3DTEXF_ANISOTROPIC
- minLookup
[WINELOOKUP_MAGFILTER
]] =
809 gl_info
->supported
[EXT_TEXTURE_FILTER_ANISOTROPIC
] ? GL_LINEAR
: GL_NEAREST
;
812 minMipLookup
[WINED3DTEXF_NONE
][WINED3DTEXF_NONE
] = GL_LINEAR
;
813 minMipLookup
[WINED3DTEXF_NONE
][WINED3DTEXF_POINT
] = GL_LINEAR
;
814 minMipLookup
[WINED3DTEXF_NONE
][WINED3DTEXF_LINEAR
] = GL_LINEAR
;
815 minMipLookup
[WINED3DTEXF_POINT
][WINED3DTEXF_NONE
] = GL_NEAREST
;
816 minMipLookup
[WINED3DTEXF_POINT
][WINED3DTEXF_POINT
] = GL_NEAREST_MIPMAP_NEAREST
;
817 minMipLookup
[WINED3DTEXF_POINT
][WINED3DTEXF_LINEAR
] = GL_NEAREST_MIPMAP_LINEAR
;
818 minMipLookup
[WINED3DTEXF_LINEAR
][WINED3DTEXF_NONE
] = GL_LINEAR
;
819 minMipLookup
[WINED3DTEXF_LINEAR
][WINED3DTEXF_POINT
] = GL_LINEAR_MIPMAP_NEAREST
;
820 minMipLookup
[WINED3DTEXF_LINEAR
][WINED3DTEXF_LINEAR
] = GL_LINEAR_MIPMAP_LINEAR
;
821 minMipLookup
[WINED3DTEXF_ANISOTROPIC
][WINED3DTEXF_NONE
] = gl_info
->supported
[EXT_TEXTURE_FILTER_ANISOTROPIC
] ?
822 GL_LINEAR_MIPMAP_LINEAR
: GL_LINEAR
;
823 minMipLookup
[WINED3DTEXF_ANISOTROPIC
][WINED3DTEXF_POINT
] = gl_info
->supported
[EXT_TEXTURE_FILTER_ANISOTROPIC
] ? GL_LINEAR_MIPMAP_NEAREST
: GL_LINEAR
;
824 minMipLookup
[WINED3DTEXF_ANISOTROPIC
][WINED3DTEXF_LINEAR
] = gl_info
->supported
[EXT_TEXTURE_FILTER_ANISOTROPIC
] ? GL_LINEAR_MIPMAP_LINEAR
: GL_LINEAR
;
826 /* TODO: config lookups */
828 if (display
!= NULL
) {
829 GLX_Extensions
= glXQueryExtensionsString(display
, DefaultScreen(display
));
830 TRACE_(d3d_caps
)("GLX_Extensions reported:\n");
832 if (NULL
== GLX_Extensions
) {
833 ERR(" GLX_Extensions returns NULL\n");
835 while (*GLX_Extensions
!= 0x00) {
836 const char *Start
= GLX_Extensions
;
839 memset(ThisExtn
, 0x00, sizeof(ThisExtn
));
840 while (*GLX_Extensions
!= ' ' && *GLX_Extensions
!= 0x00) {
843 memcpy(ThisExtn
, Start
, (GLX_Extensions
- Start
));
844 TRACE_(d3d_caps
)("- %s\n", ThisExtn
);
845 if (*GLX_Extensions
== ' ') GLX_Extensions
++;
850 /* If we created a dummy context, throw it away */
851 if (NULL
!= fake_ctx
) WineD3D_ReleaseFakeGLContext(fake_ctx
);
853 /* Only save the values obtained when a display is provided */
854 if (fake_ctx
== NULL
) {
861 /**********************************************************
862 * IWineD3D implementation follows
863 **********************************************************/
865 static UINT WINAPI
IWineD3DImpl_GetAdapterCount (IWineD3D
*iface
) {
866 IWineD3DImpl
*This
= (IWineD3DImpl
*)iface
;
868 /* FIXME: Set to one for now to imply the display */
869 TRACE_(d3d_caps
)("(%p): Mostly stub, only returns primary display\n", This
);
873 static HRESULT WINAPI
IWineD3DImpl_RegisterSoftwareDevice(IWineD3D
*iface
, void* pInitializeFunction
) {
874 IWineD3DImpl
*This
= (IWineD3DImpl
*)iface
;
875 FIXME("(%p)->(%p): stub\n", This
, pInitializeFunction
);
879 static HMONITOR WINAPI
IWineD3DImpl_GetAdapterMonitor(IWineD3D
*iface
, UINT Adapter
) {
880 IWineD3DImpl
*This
= (IWineD3DImpl
*)iface
;
881 POINT pt
= { -1, -1 };
883 if (Adapter
>= IWineD3DImpl_GetAdapterCount(iface
)) {
887 FIXME_(d3d_caps
)("(%p): returning the primary monitor for adapter %d\n", This
, Adapter
);
888 return MonitorFromPoint(pt
, MONITOR_DEFAULTTOPRIMARY
);
891 /* FIXME: GetAdapterModeCount and EnumAdapterModes currently only returns modes
892 of the same bpp but different resolutions */
894 /* Note: dx9 supplies a format. Calls from d3d8 supply D3DFMT_UNKNOWN */
895 static UINT WINAPI
IWineD3DImpl_GetAdapterModeCount(IWineD3D
*iface
, UINT Adapter
, WINED3DFORMAT Format
) {
896 IWineD3DImpl
*This
= (IWineD3DImpl
*)iface
;
897 TRACE_(d3d_caps
)("(%p}->(Adapter: %d, Format: %s)\n", This
, Adapter
, debug_d3dformat(Format
));
899 if (Adapter
>= IWineD3D_GetAdapterCount(iface
)) {
903 if (Adapter
== 0) { /* Display */
906 #if !defined( DEBUG_SINGLE_MODE )
909 /* Work out the current screen bpp */
910 HDC hdc
= CreateDCA("DISPLAY", NULL
, NULL
, NULL
);
911 int bpp
= GetDeviceCaps(hdc
, BITSPIXEL
);
914 while (EnumDisplaySettingsExW(NULL
, j
, &DevModeW
, 0)) {
921 case D3DFMT_X8R8G8B8
:
922 case D3DFMT_A8R8G8B8
:
923 if (min(DevModeW
.dmBitsPerPel
, bpp
) == 32) i
++;
924 if (min(DevModeW
.dmBitsPerPel
, bpp
) == 24) i
++;
926 case D3DFMT_X1R5G5B5
:
927 case D3DFMT_A1R5G5B5
:
929 if (min(DevModeW
.dmBitsPerPel
, bpp
) == 16) i
++;
932 /* Skip other modes as they do not match requested format */
940 TRACE_(d3d_caps
)("(%p}->(Adapter: %d) => %d (out of %d)\n", This
, Adapter
, i
, j
);
943 FIXME_(d3d_caps
)("Adapter not primary display\n");
948 /* Note: dx9 supplies a format. Calls from d3d8 supply D3DFMT_UNKNOWN */
949 static HRESULT WINAPI
IWineD3DImpl_EnumAdapterModes(IWineD3D
*iface
, UINT Adapter
, WINED3DFORMAT Format
, UINT Mode
, WINED3DDISPLAYMODE
* pMode
) {
950 IWineD3DImpl
*This
= (IWineD3DImpl
*)iface
;
951 TRACE_(d3d_caps
)("(%p}->(Adapter:%d, mode:%d, pMode:%p, format:%s)\n", This
, Adapter
, Mode
, pMode
, debug_d3dformat(Format
));
953 /* Validate the parameters as much as possible */
955 Adapter
>= IWineD3DImpl_GetAdapterCount(iface
) ||
956 Mode
>= IWineD3DImpl_GetAdapterModeCount(iface
, Adapter
, Format
)) {
957 return WINED3DERR_INVALIDCALL
;
960 if (Adapter
== 0) { /* Display */
961 #if !defined( DEBUG_SINGLE_MODE )
965 /* Work out the current screen bpp */
966 HDC hdc
= CreateDCA("DISPLAY", NULL
, NULL
, NULL
);
967 int bpp
= GetDeviceCaps(hdc
, BITSPIXEL
);
970 /* If we are filtering to a specific format, then need to skip all unrelated
971 modes, but if mode is irrelevant, then we can use the index directly */
972 if (Format
== D3DFMT_UNKNOWN
)
978 DEVMODEW DevModeWtmp
;
981 while (i
<(Mode
) && EnumDisplaySettingsExW(NULL
, j
, &DevModeWtmp
, 0)) {
988 case D3DFMT_X8R8G8B8
:
989 case D3DFMT_A8R8G8B8
:
990 if (min(DevModeWtmp
.dmBitsPerPel
, bpp
) == 32) i
++;
991 if (min(DevModeWtmp
.dmBitsPerPel
, bpp
) == 24) i
++;
993 case D3DFMT_X1R5G5B5
:
994 case D3DFMT_A1R5G5B5
:
996 if (min(DevModeWtmp
.dmBitsPerPel
, bpp
) == 16) i
++;
999 /* Skip other modes as they do not match requested format */
1006 /* Now get the display mode via the calculated index */
1007 if (EnumDisplaySettingsExW(NULL
, ModeIdx
, &DevModeW
, 0))
1009 pMode
->Width
= DevModeW
.dmPelsWidth
;
1010 pMode
->Height
= DevModeW
.dmPelsHeight
;
1011 bpp
= min(DevModeW
.dmBitsPerPel
, bpp
);
1012 pMode
->RefreshRate
= D3DADAPTER_DEFAULT
;
1013 if (DevModeW
.dmFields
& DM_DISPLAYFREQUENCY
)
1015 pMode
->RefreshRate
= DevModeW
.dmDisplayFrequency
;
1018 if (Format
== D3DFMT_UNKNOWN
)
1021 case 8: pMode
->Format
= D3DFMT_R3G3B2
; break;
1022 case 16: pMode
->Format
= D3DFMT_R5G6B5
; break;
1023 case 24: /* Robots and EVE Online need 24 and 32 bit as A8R8G8B8 to start */
1024 case 32: pMode
->Format
= D3DFMT_A8R8G8B8
; break;
1025 default: pMode
->Format
= D3DFMT_UNKNOWN
;
1028 pMode
->Format
= Format
;
1033 TRACE_(d3d_caps
)("Requested mode out of range %d\n", Mode
);
1034 return WINED3DERR_INVALIDCALL
;
1038 /* Return one setting of the format requested */
1039 if (Mode
> 0) return WINED3DERR_INVALIDCALL
;
1041 pMode
->Height
= 600;
1042 pMode
->RefreshRate
= D3DADAPTER_DEFAULT
;
1043 pMode
->Format
= (Format
== D3DFMT_UNKNOWN
) ? D3DFMT_A8R8G8B8
: Format
;
1046 TRACE_(d3d_caps
)("W %d H %d rr %d fmt (%x - %s) bpp %u\n", pMode
->Width
, pMode
->Height
,
1047 pMode
->RefreshRate
, pMode
->Format
, debug_d3dformat(pMode
->Format
), bpp
);
1050 FIXME_(d3d_caps
)("Adapter not primary display\n");
1056 static HRESULT WINAPI
IWineD3DImpl_GetAdapterDisplayMode(IWineD3D
*iface
, UINT Adapter
, WINED3DDISPLAYMODE
* pMode
) {
1057 IWineD3DImpl
*This
= (IWineD3DImpl
*)iface
;
1058 TRACE_(d3d_caps
)("(%p}->(Adapter: %d, pMode: %p)\n", This
, Adapter
, pMode
);
1060 if (NULL
== pMode
||
1061 Adapter
>= IWineD3D_GetAdapterCount(iface
)) {
1062 return WINED3DERR_INVALIDCALL
;
1065 if (Adapter
== 0) { /* Display */
1069 EnumDisplaySettingsExW(NULL
, (DWORD
)-1, &DevModeW
, 0);
1070 pMode
->Width
= DevModeW
.dmPelsWidth
;
1071 pMode
->Height
= DevModeW
.dmPelsHeight
;
1072 bpp
= DevModeW
.dmBitsPerPel
;
1073 pMode
->RefreshRate
= D3DADAPTER_DEFAULT
;
1074 if (DevModeW
.dmFields
&DM_DISPLAYFREQUENCY
)
1076 pMode
->RefreshRate
= DevModeW
.dmDisplayFrequency
;
1080 case 8: pMode
->Format
= D3DFMT_R3G3B2
; break;
1081 case 16: pMode
->Format
= D3DFMT_R5G6B5
; break;
1082 case 24: pMode
->Format
= D3DFMT_X8R8G8B8
; break; /* Robots needs 24bit to be X8R8G8B8 */
1083 case 32: pMode
->Format
= D3DFMT_X8R8G8B8
; break; /* EVE online and the Fur demo need 32bit AdapterDisplatMode to return X8R8G8B8 */
1084 default: pMode
->Format
= D3DFMT_UNKNOWN
;
1088 FIXME_(d3d_caps
)("Adapter not primary display\n");
1091 TRACE_(d3d_caps
)("returning w:%d, h:%d, ref:%d, fmt:%s\n", pMode
->Width
,
1092 pMode
->Height
, pMode
->RefreshRate
, debug_d3dformat(pMode
->Format
));
1096 static Display
* WINAPI
IWineD3DImpl_GetAdapterDisplay(IWineD3D
*iface
, UINT Adapter
) {
1099 /* only works with one adapter at the moment... */
1101 /* Get the display */
1102 device_context
= GetDC(0);
1103 display
= get_display(device_context
);
1104 ReleaseDC(0, device_context
);
1108 /* NOTE: due to structure differences between dx8 and dx9 D3DADAPTER_IDENTIFIER,
1109 and fields being inserted in the middle, a new structure is used in place */
1110 static HRESULT WINAPI
IWineD3DImpl_GetAdapterIdentifier(IWineD3D
*iface
, UINT Adapter
, DWORD Flags
,
1111 WINED3DADAPTER_IDENTIFIER
* pIdentifier
) {
1112 IWineD3DImpl
*This
= (IWineD3DImpl
*)iface
;
1114 TRACE_(d3d_caps
)("(%p}->(Adapter: %d, Flags: %lx, pId=%p)\n", This
, Adapter
, Flags
, pIdentifier
);
1116 if (Adapter
>= IWineD3D_GetAdapterCount(iface
)) {
1117 return WINED3DERR_INVALIDCALL
;
1120 if (Adapter
== 0) { /* Display - only device supported for now */
1122 BOOL isGLInfoValid
= This
->isGLInfoValid
;
1124 /* FillGLCaps updates gl_info, but we only want to store and
1125 reuse the values once we have a context which is valid. Values from
1126 a temporary context may differ from the final ones */
1127 if (isGLInfoValid
== FALSE
) {
1128 WineD3D_Context
*fake_ctx
= NULL
;
1129 if (glXGetCurrentContext() == NULL
) fake_ctx
= WineD3D_CreateFakeGLContext();
1130 /* If we don't know the device settings, go query them now */
1131 isGLInfoValid
= IWineD3DImpl_FillGLCaps(iface
, IWineD3DImpl_GetAdapterDisplay(iface
, Adapter
));
1132 if (fake_ctx
!= NULL
) WineD3D_ReleaseFakeGLContext(fake_ctx
);
1135 /* If it worked, return the information requested */
1136 if (isGLInfoValid
) {
1137 TRACE_(d3d_caps
)("device/Vendor Name and Version detection using FillGLCaps\n");
1138 strcpy(pIdentifier
->Driver
, "Display");
1139 strcpy(pIdentifier
->Description
, "Direct3D HAL");
1141 /* Note dx8 doesn't supply a DeviceName */
1142 if (NULL
!= pIdentifier
->DeviceName
) strcpy(pIdentifier
->DeviceName
, "\\\\.\\DISPLAY"); /* FIXME: May depend on desktop? */
1143 /* Current Windows drivers have versions like 6.14.... (some older have an earlier version) */
1144 pIdentifier
->DriverVersion
->u
.HighPart
= MAKEDWORD_VERSION(6, 14);
1145 pIdentifier
->DriverVersion
->u
.LowPart
= This
->gl_info
.gl_driver_version
;
1146 *(pIdentifier
->VendorId
) = This
->gl_info
.gl_vendor
;
1147 *(pIdentifier
->DeviceId
) = This
->gl_info
.gl_card
;
1148 *(pIdentifier
->SubSysId
) = 0;
1149 *(pIdentifier
->Revision
) = 0;
1153 /* If it failed, return dummy values from an NVidia driver */
1154 WARN_(d3d_caps
)("Cannot get GLCaps for device/Vendor Name and Version detection using FillGLCaps, currently using NVIDIA identifiers\n");
1155 strcpy(pIdentifier
->Driver
, "Display");
1156 strcpy(pIdentifier
->Description
, "Direct3D HAL");
1157 if (NULL
!= pIdentifier
->DeviceName
) strcpy(pIdentifier
->DeviceName
, "\\\\.\\DISPLAY"); /* FIXME: May depend on desktop? */
1158 /* Current Windows Nvidia drivers have versions like e.g. 6.14.10.5672 */
1159 pIdentifier
->DriverVersion
->u
.HighPart
= MAKEDWORD_VERSION(6, 14);
1160 /* 71.74 is a current Linux Nvidia driver version */
1161 pIdentifier
->DriverVersion
->u
.LowPart
= MAKEDWORD_VERSION(10, (71*100+74));
1162 *(pIdentifier
->VendorId
) = VENDOR_NVIDIA
;
1163 *(pIdentifier
->DeviceId
) = CARD_NVIDIA_GEFORCE4_TI4600
;
1164 *(pIdentifier
->SubSysId
) = 0;
1165 *(pIdentifier
->Revision
) = 0;
1168 /*FIXME: memcpy(&pIdentifier->DeviceIdentifier, ??, sizeof(??GUID)); */
1169 if (Flags
& D3DENUM_NO_WHQL_LEVEL
) {
1170 *(pIdentifier
->WHQLLevel
) = 0;
1172 *(pIdentifier
->WHQLLevel
) = 1;
1176 FIXME_(d3d_caps
)("Adapter not primary display\n");
1182 static BOOL
IWineD3DImpl_IsGLXFBConfigCompatibleWithRenderFmt(WineD3D_Context
* ctx
, GLXFBConfig cfgs
, WINED3DFORMAT Format
) {
1183 #if 0 /* This code performs a strict test between the format and the current X11 buffer depth, which may give the best performance */
1185 int rb
, gb
, bb
, ab
, type
, buf_sz
;
1187 gl_test
= glXGetFBConfigAttrib(ctx
->display
, cfgs
, GLX_RED_SIZE
, &rb
);
1188 gl_test
= glXGetFBConfigAttrib(ctx
->display
, cfgs
, GLX_GREEN_SIZE
, &gb
);
1189 gl_test
= glXGetFBConfigAttrib(ctx
->display
, cfgs
, GLX_BLUE_SIZE
, &bb
);
1190 gl_test
= glXGetFBConfigAttrib(ctx
->display
, cfgs
, GLX_ALPHA_SIZE
, &ab
);
1191 gl_test
= glXGetFBConfigAttrib(ctx
->display
, cfgs
, GLX_RENDER_TYPE
, &type
);
1192 gl_test
= glXGetFBConfigAttrib(ctx
->display
, cfgs
, GLX_BUFFER_SIZE
, &buf_sz
);
1195 case WINED3DFMT_X8R8G8B8
:
1196 case WINED3DFMT_R8G8B8
:
1197 if (8 == rb
&& 8 == gb
&& 8 == bb
) return TRUE
;
1199 case WINED3DFMT_A8R8G8B8
:
1200 if (8 == rb
&& 8 == gb
&& 8 == bb
&& 8 == ab
) return TRUE
;
1202 case WINED3DFMT_A2R10G10B10
:
1203 if (10 == rb
&& 10 == gb
&& 10 == bb
&& 2 == ab
) return TRUE
;
1205 case WINED3DFMT_X1R5G5B5
:
1206 if (5 == rb
&& 5 == gb
&& 5 == bb
) return TRUE
;
1208 case WINED3DFMT_A1R5G5B5
:
1209 if (5 == rb
&& 5 == gb
&& 5 == bb
&& 1 == ab
) return TRUE
;
1211 case WINED3DFMT_X4R4G4B4
:
1212 if (16 == buf_sz
&& 4 == rb
&& 4 == gb
&& 4 == bb
) return TRUE
;
1214 case WINED3DFMT_R5G6B5
:
1215 if (5 == rb
&& 6 == gb
&& 5 == bb
) return TRUE
;
1217 case WINED3DFMT_R3G3B2
:
1218 if (3 == rb
&& 3 == gb
&& 2 == bb
) return TRUE
;
1220 case WINED3DFMT_A8P8
:
1221 if (type
& GLX_COLOR_INDEX_BIT
&& 8 == buf_sz
&& 8 == ab
) return TRUE
;
1224 if (type
& GLX_COLOR_INDEX_BIT
&& 8 == buf_sz
) return TRUE
;
1227 ERR("unsupported format %s\n", debug_d3dformat(Format
));
1231 #else /* Most of the time performance is less of an issue than compatibility, this code allows for most common opengl/d3d formats */
1233 case WINED3DFMT_X8R8G8B8
:
1234 case WINED3DFMT_R8G8B8
:
1235 case WINED3DFMT_A8R8G8B8
:
1236 case WINED3DFMT_A2R10G10B10
:
1237 case WINED3DFMT_X1R5G5B5
:
1238 case WINED3DFMT_A1R5G5B5
:
1239 case WINED3DFMT_R5G6B5
:
1240 case WINED3DFMT_R3G3B2
:
1241 case WINED3DFMT_A8P8
:
1245 ERR("unsupported format %s\n", debug_d3dformat(Format
));
1252 static BOOL
IWineD3DImpl_IsGLXFBConfigCompatibleWithDepthFmt(WineD3D_Context
* ctx
, GLXFBConfig cfgs
, WINED3DFORMAT Format
) {
1253 #if 0/* This code performs a strict test between the format and the current X11 buffer depth, which may give the best performance */
1257 gl_test
= glXGetFBConfigAttrib(ctx
->display
, cfgs
, GLX_DEPTH_SIZE
, &db
);
1258 gl_test
= glXGetFBConfigAttrib(ctx
->display
, cfgs
, GLX_STENCIL_SIZE
, &sb
);
1261 case WINED3DFMT_D16
:
1262 case WINED3DFMT_D16_LOCKABLE
:
1263 if (16 == db
) return TRUE
;
1265 case WINED3DFMT_D32
:
1266 if (32 == db
) return TRUE
;
1268 case WINED3DFMT_D15S1
:
1269 if (15 == db
) return TRUE
;
1271 case WINED3DFMT_D24S8
:
1272 if (24 == db
&& 8 == sb
) return TRUE
;
1274 case WINED3DFMT_D24FS8
:
1275 if (24 == db
&& 8 == sb
) return TRUE
;
1277 case WINED3DFMT_D24X8
:
1278 if (24 == db
) return TRUE
;
1280 case WINED3DFMT_D24X4S4
:
1281 if (24 == db
&& 4 == sb
) return TRUE
;
1283 case WINED3DFMT_D32F_LOCKABLE
:
1284 if (32 == db
) return TRUE
;
1287 ERR("unsupported format %s\n", debug_d3dformat(Format
));
1291 #else /* Most of the time performance is less of an issue than compatibility, this code allows for most common opengl/d3d formats */
1293 case WINED3DFMT_D16
:
1294 case WINED3DFMT_D16_LOCKABLE
:
1295 case WINED3DFMT_D32
:
1296 case WINED3DFMT_D15S1
:
1297 case WINED3DFMT_D24S8
:
1298 case WINED3DFMT_D24FS8
:
1299 case WINED3DFMT_D24X8
:
1300 case WINED3DFMT_D24X4S4
:
1301 case WINED3DFMT_D32F_LOCKABLE
:
1304 ERR("unsupported format %s\n", debug_d3dformat(Format
));
1311 static HRESULT WINAPI
IWineD3DImpl_CheckDepthStencilMatch(IWineD3D
*iface
, UINT Adapter
, WINED3DDEVTYPE DeviceType
,
1312 WINED3DFORMAT AdapterFormat
,
1313 WINED3DFORMAT RenderTargetFormat
,
1314 WINED3DFORMAT DepthStencilFormat
) {
1315 IWineD3DImpl
*This
= (IWineD3DImpl
*)iface
;
1316 HRESULT hr
= WINED3DERR_NOTAVAILABLE
;
1317 WineD3D_Context
* ctx
= NULL
;
1318 GLXFBConfig
* cfgs
= NULL
;
1322 WARN_(d3d_caps
)("(%p)-> (STUB) (Adptr:%d, DevType:(%x,%s), AdptFmt:(%x,%s), RendrTgtFmt:(%x,%s), DepthStencilFmt:(%x,%s))\n",
1324 DeviceType
, debug_d3ddevicetype(DeviceType
),
1325 AdapterFormat
, debug_d3dformat(AdapterFormat
),
1326 RenderTargetFormat
, debug_d3dformat(RenderTargetFormat
),
1327 DepthStencilFormat
, debug_d3dformat(DepthStencilFormat
));
1329 if (Adapter
>= IWineD3D_GetAdapterCount(iface
)) {
1330 TRACE("(%p) Failed: Atapter (%u) higher than supported adapters (%u) returning WINED3DERR_INVALIDCALL\n", This
, Adapter
, IWineD3D_GetAdapterCount(iface
));
1331 return WINED3DERR_INVALIDCALL
;
1333 /* TODO: use the real context if it's available */
1334 ctx
= WineD3D_CreateFakeGLContext();
1336 cfgs
= glXGetFBConfigs(ctx
->display
, DefaultScreen(ctx
->display
), &nCfgs
);
1338 TRACE_(d3d_caps
)("(%p) : Unable to create a fake context at this time (there may already be an active context)\n", This
);
1342 for (it
= 0; it
< nCfgs
; ++it
) {
1343 if (IWineD3DImpl_IsGLXFBConfigCompatibleWithRenderFmt(ctx
, cfgs
[it
], RenderTargetFormat
)) {
1344 if (IWineD3DImpl_IsGLXFBConfigCompatibleWithDepthFmt(ctx
, cfgs
[it
], DepthStencilFormat
)) {
1353 /* If there's a corrent context then we cannot create a fake one so pass everything */
1358 WineD3D_ReleaseFakeGLContext(ctx
);
1360 if (hr
!= WINED3D_OK
)
1361 TRACE_(d3d_caps
)("Failed to match stencil format to device\b");
1363 TRACE_(d3d_caps
)("(%p) : Returning %lx\n", This
, hr
);
1367 static HRESULT WINAPI
IWineD3DImpl_CheckDeviceMultiSampleType(IWineD3D
*iface
, UINT Adapter
, WINED3DDEVTYPE DeviceType
,
1368 WINED3DFORMAT SurfaceFormat
,
1369 BOOL Windowed
, WINED3DMULTISAMPLE_TYPE MultiSampleType
, DWORD
* pQualityLevels
) {
1371 IWineD3DImpl
*This
= (IWineD3DImpl
*)iface
;
1372 TRACE_(d3d_caps
)("(%p)-> (STUB) (Adptr:%d, DevType:(%x,%s), SurfFmt:(%x,%s), Win?%d, MultiSamp:%x, pQual:%p)\n",
1375 DeviceType
, debug_d3ddevicetype(DeviceType
),
1376 SurfaceFormat
, debug_d3dformat(SurfaceFormat
),
1381 if (Adapter
>= IWineD3D_GetAdapterCount(iface
)) {
1382 return WINED3DERR_INVALIDCALL
;
1385 if (pQualityLevels
!= NULL
) {
1386 static int s_single_shot
= 0;
1387 if (!s_single_shot
) {
1388 FIXME("Quality levels unsupported at present\n");
1391 *pQualityLevels
= 1; /* Guess at a value! */
1394 if (WINED3DMULTISAMPLE_NONE
== MultiSampleType
) return WINED3D_OK
;
1395 return WINED3DERR_NOTAVAILABLE
;
1398 static HRESULT WINAPI
IWineD3DImpl_CheckDeviceType(IWineD3D
*iface
, UINT Adapter
, WINED3DDEVTYPE CheckType
,
1399 WINED3DFORMAT DisplayFormat
, WINED3DFORMAT BackBufferFormat
, BOOL Windowed
) {
1401 IWineD3DImpl
*This
= (IWineD3DImpl
*)iface
;
1402 TRACE_(d3d_caps
)("(%p)-> (STUB) (Adptr:%d, CheckType:(%x,%s), DispFmt:(%x,%s), BackBuf:(%x,%s), Win?%d): stub\n",
1405 CheckType
, debug_d3ddevicetype(CheckType
),
1406 DisplayFormat
, debug_d3dformat(DisplayFormat
),
1407 BackBufferFormat
, debug_d3dformat(BackBufferFormat
),
1410 if (Adapter
>= IWineD3D_GetAdapterCount(iface
)) {
1411 return WINED3DERR_INVALIDCALL
;
1415 GLXFBConfig
* cfgs
= NULL
;
1418 HRESULT hr
= WINED3DERR_NOTAVAILABLE
;
1420 WineD3D_Context
* ctx
= WineD3D_CreateFakeGLContext();
1422 cfgs
= glXGetFBConfigs(ctx
->display
, DefaultScreen(ctx
->display
), &nCfgs
);
1423 for (it
= 0; it
< nCfgs
; ++it
) {
1424 if (IWineD3DImpl_IsGLXFBConfigCompatibleWithRenderFmt(ctx
, cfgs
[it
], DisplayFormat
)) {
1431 WineD3D_ReleaseFakeGLContext(ctx
);
1436 return WINED3DERR_NOTAVAILABLE
;
1439 static HRESULT WINAPI
IWineD3DImpl_CheckDeviceFormat(IWineD3D
*iface
, UINT Adapter
, WINED3DDEVTYPE DeviceType
,
1440 WINED3DFORMAT AdapterFormat
, DWORD Usage
, WINED3DRESOURCETYPE RType
, WINED3DFORMAT CheckFormat
) {
1441 IWineD3DImpl
*This
= (IWineD3DImpl
*)iface
;
1442 TRACE_(d3d_caps
)("(%p)-> (STUB) (Adptr:%d, DevType:(%u,%s), AdptFmt:(%u,%s), Use:(%lu,%s,%s), ResTyp:(%x,%s), CheckFmt:(%u,%s)) ",
1445 DeviceType
, debug_d3ddevicetype(DeviceType
),
1446 AdapterFormat
, debug_d3dformat(AdapterFormat
),
1447 Usage
, debug_d3dusage(Usage
), debug_d3dusagequery(Usage
),
1448 RType
, debug_d3dresourcetype(RType
),
1449 CheckFormat
, debug_d3dformat(CheckFormat
));
1451 if (Adapter
>= IWineD3D_GetAdapterCount(iface
)) {
1452 return WINED3DERR_INVALIDCALL
;
1455 /* TODO: Check support against more of the WINED3DUSAGE_QUERY_* constants
1456 * See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/directx9_c/IDirect3D9__CheckDeviceFormat.asp
1457 * and http://msdn.microsoft.com/library/default.asp?url=/library/en-us/directx9_c/D3DUSAGE_QUERY.asp */
1458 if (Usage
& WINED3DUSAGE_QUERY_VERTEXTEXTURE
) {
1459 TRACE_(d3d_caps
)("[FAILED]\n");
1460 return WINED3DERR_NOTAVAILABLE
; /* Enable when fully supported */
1463 if(Usage
& WINED3DUSAGE_DEPTHSTENCIL
) {
1464 switch (CheckFormat
) {
1465 case WINED3DFMT_D16_LOCKABLE
:
1466 case WINED3DFMT_D32
:
1467 case WINED3DFMT_D15S1
:
1468 case WINED3DFMT_D24S8
:
1469 case WINED3DFMT_D24X8
:
1470 case WINED3DFMT_D24X4S4
:
1471 case WINED3DFMT_D16
:
1472 case WINED3DFMT_L16
:
1473 case WINED3DFMT_D32F_LOCKABLE
:
1474 case WINED3DFMT_D24FS8
:
1475 TRACE_(d3d_caps
)("[OK]\n");
1478 TRACE_(d3d_caps
)("[FAILED]\n");
1479 return WINED3DERR_NOTAVAILABLE
;
1481 } else if(Usage
& WINED3DUSAGE_RENDERTARGET
) {
1482 switch (CheckFormat
) {
1483 case WINED3DFMT_R8G8B8
:
1484 case WINED3DFMT_A8R8G8B8
:
1485 case WINED3DFMT_X8R8G8B8
:
1486 case WINED3DFMT_R5G6B5
:
1487 case WINED3DFMT_X1R5G5B5
:
1488 case WINED3DFMT_A1R5G5B5
:
1489 case WINED3DFMT_A4R4G4B4
:
1490 case WINED3DFMT_R3G3B2
:
1491 case WINED3DFMT_X4R4G4B4
:
1492 case WINED3DFMT_A8B8G8R8
:
1493 case WINED3DFMT_X8B8G8R8
:
1495 TRACE_(d3d_caps
)("[OK]\n");
1498 TRACE_(d3d_caps
)("[FAILED]\n");
1499 return WINED3DERR_NOTAVAILABLE
;
1503 if (GL_SUPPORT(EXT_TEXTURE_COMPRESSION_S3TC
)) {
1504 switch (CheckFormat
) {
1510 TRACE_(d3d_caps
)("[OK]\n");
1513 break; /* Avoid compiler warnings */
1517 /* This format is nothing special and it is supported perfectly.
1518 * However, ati and nvidia driver on windows do not mark this format
1519 * supported(tested with the dxCapsViewer) and pretending to
1520 * support this format uncovers a bug in Battlefield 1942(fonts are missing)
1521 * So do the same as Windows drivers and pretend not to support it on dx8 and 9
1522 * Enable it on dx7. It will need additional checking on dx10 when we support it.
1524 if(This
->dxVersion
> 7 && CheckFormat
== WINED3DFMT_R8G8B8
) {
1525 TRACE_(d3d_caps
)("[FAILED]\n");
1526 return WINED3DERR_NOTAVAILABLE
;
1529 switch (CheckFormat
) {
1532 * supported: RGB(A) formats
1534 case WINED3DFMT_R8G8B8
: /* Enable for dx7, blacklisted for 8 and 9 above */
1535 case WINED3DFMT_A8R8G8B8
:
1536 case WINED3DFMT_X8R8G8B8
:
1537 case WINED3DFMT_R5G6B5
:
1538 case WINED3DFMT_X1R5G5B5
:
1539 case WINED3DFMT_A1R5G5B5
:
1540 case WINED3DFMT_A4R4G4B4
:
1541 case WINED3DFMT_R3G3B2
:
1543 case WINED3DFMT_A8R3G3B2
:
1544 case WINED3DFMT_X4R4G4B4
:
1545 case WINED3DFMT_A8B8G8R8
:
1546 case WINED3DFMT_X8B8G8R8
:
1547 case WINED3DFMT_A2R10G10B10
:
1548 case WINED3DFMT_A2B10G10R10
:
1549 TRACE_(d3d_caps
)("[OK]\n");
1553 * supported: Palettized
1556 TRACE_(d3d_caps
)("[OK]\n");
1560 * Supported: (Alpha)-Luminance
1563 case WINED3DFMT_A8L8
:
1564 case WINED3DFMT_A4L4
:
1565 TRACE_(d3d_caps
)("[OK]\n");
1569 * Not supported for now: Bump mapping formats
1570 * Enable some because games often fail when they are not available
1571 * and are still playable even without bump mapping
1573 case WINED3DFMT_V8U8
:
1574 case WINED3DFMT_V16U16
:
1575 case WINED3DFMT_L6V5U5
:
1576 case WINED3DFMT_X8L8V8U8
:
1577 case WINED3DFMT_Q8W8V8U8
:
1578 case WINED3DFMT_W11V11U10
:
1579 case WINED3DFMT_A2W10V10U10
:
1580 WARN_(d3d_caps
)("[Not supported, but pretended to do]\n");
1584 * DXTN Formats: Handled above
1593 * Odd formats - not supported
1595 case WINED3DFMT_VERTEXDATA
:
1596 case WINED3DFMT_INDEX16
:
1597 case WINED3DFMT_INDEX32
:
1598 case WINED3DFMT_Q16W16V16U16
:
1599 TRACE_(d3d_caps
)("[FAILED]\n"); /* Enable when implemented */
1600 return WINED3DERR_NOTAVAILABLE
;
1603 * Float formats: Not supported right now
1605 case WINED3DFMT_R16F
:
1606 case WINED3DFMT_G16R16F
:
1607 case WINED3DFMT_A16B16G16R16F
:
1608 case WINED3DFMT_R32F
:
1609 case WINED3DFMT_G32R32F
:
1610 case WINED3DFMT_A32B32G32R32F
:
1611 case WINED3DFMT_CxV8U8
:
1612 TRACE_(d3d_caps
)("[FAILED]\n"); /* Enable when implemented */
1613 return WINED3DERR_NOTAVAILABLE
;
1616 case WINED3DFMT_G16R16
:
1617 case WINED3DFMT_A16B16G16R16
:
1618 TRACE_(d3d_caps
)("[FAILED]\n"); /* Enable when implemented */
1619 return WINED3DERR_NOTAVAILABLE
;
1625 TRACE_(d3d_caps
)("[FAILED]\n");
1626 return WINED3DERR_NOTAVAILABLE
;
1629 static HRESULT WINAPI
IWineD3DImpl_CheckDeviceFormatConversion(IWineD3D
*iface
, UINT Adapter
, WINED3DDEVTYPE DeviceType
,
1630 WINED3DFORMAT SourceFormat
, WINED3DFORMAT TargetFormat
) {
1631 IWineD3DImpl
*This
= (IWineD3DImpl
*)iface
;
1633 FIXME_(d3d_caps
)("(%p)-> (STUB) (Adptr:%d, DevType:(%u,%s), SrcFmt:(%u,%s), TgtFmt:(%u,%s))\n",
1636 DeviceType
, debug_d3ddevicetype(DeviceType
),
1637 SourceFormat
, debug_d3dformat(SourceFormat
),
1638 TargetFormat
, debug_d3dformat(TargetFormat
));
1642 /* Note: d3d8 passes in a pointer to a D3DCAPS8 structure, which is a true
1643 subset of a D3DCAPS9 structure. However, it has to come via a void *
1644 as the d3d8 interface cannot import the d3d9 header */
1645 static HRESULT WINAPI
IWineD3DImpl_GetDeviceCaps(IWineD3D
*iface
, UINT Adapter
, WINED3DDEVTYPE DeviceType
, WINED3DCAPS
* pCaps
) {
1647 IWineD3DImpl
*This
= (IWineD3DImpl
*)iface
;
1649 TRACE_(d3d_caps
)("(%p)->(Adptr:%d, DevType: %x, pCaps: %p)\n", This
, Adapter
, DeviceType
, pCaps
);
1651 if (Adapter
>= IWineD3D_GetAdapterCount(iface
)) {
1652 return WINED3DERR_INVALIDCALL
;
1655 /* FIXME: both the gl_info and the shader_mode should be made per adapter */
1657 /* If we don't know the device settings, go query them now */
1658 if (This
->isGLInfoValid
== FALSE
) {
1659 /* use the desktop window to fill gl caps */
1660 BOOL rc
= IWineD3DImpl_FillGLCaps(iface
, IWineD3DImpl_GetAdapterDisplay(iface
, Adapter
));
1662 /* We are running off a real context, save the values */
1663 if (rc
) This
->isGLInfoValid
= TRUE
;
1665 select_shader_mode(&This
->gl_info
, DeviceType
,
1666 &wined3d_settings
.ps_selected_mode
, &wined3d_settings
.vs_selected_mode
);
1667 select_shader_max_constants(&This
->gl_info
);
1669 /* ------------------------------------------------
1670 The following fields apply to both d3d8 and d3d9
1671 ------------------------------------------------ */
1672 *pCaps
->DeviceType
= (DeviceType
== WINED3DDEVTYPE_HAL
) ? WINED3DDEVTYPE_HAL
: WINED3DDEVTYPE_REF
; /* Not quite true, but use h/w supported by opengl I suppose */
1673 *pCaps
->AdapterOrdinal
= Adapter
;
1676 *pCaps
->Caps2
= D3DCAPS2_CANRENDERWINDOWED
;
1677 *pCaps
->Caps3
= WINED3DDEVCAPS_HWTRANSFORMANDLIGHT
;
1678 *pCaps
->PresentationIntervals
= D3DPRESENT_INTERVAL_IMMEDIATE
;
1680 *pCaps
->CursorCaps
= 0;
1683 *pCaps
->DevCaps
= WINED3DDEVCAPS_FLOATTLVERTEX
|
1684 WINED3DDEVCAPS_EXECUTESYSTEMMEMORY
|
1685 WINED3DDEVCAPS_TLVERTEXSYSTEMMEMORY
|
1686 WINED3DDEVCAPS_TLVERTEXVIDEOMEMORY
|
1687 WINED3DDEVCAPS_DRAWPRIMTLVERTEX
|
1688 WINED3DDEVCAPS_HWTRANSFORMANDLIGHT
|
1689 WINED3DDEVCAPS_EXECUTEVIDEOMEMORY
|
1690 WINED3DDEVCAPS_PUREDEVICE
|
1691 WINED3DDEVCAPS_HWRASTERIZATION
|
1692 WINED3DDEVCAPS_TEXTUREVIDEOMEMORY
|
1693 WINED3DDEVCAPS_TEXTURESYSTEMMEMORY
|
1694 WINED3DDEVCAPS_CANRENDERAFTERFLIP
|
1695 WINED3DDEVCAPS_DRAWPRIMITIVES2
|
1696 WINED3DDEVCAPS_DRAWPRIMITIVES2EX
;
1698 *pCaps
->PrimitiveMiscCaps
= D3DPMISCCAPS_CULLNONE
|
1699 D3DPMISCCAPS_CULLCCW
|
1700 D3DPMISCCAPS_CULLCW
|
1701 D3DPMISCCAPS_COLORWRITEENABLE
|
1702 D3DPMISCCAPS_CLIPTLVERTS
|
1703 D3DPMISCCAPS_CLIPPLANESCALEDPOINTS
|
1704 D3DPMISCCAPS_MASKZ
|
1705 D3DPMISCCAPS_BLENDOP
;
1707 D3DPMISCCAPS_NULLREFERENCE
1708 D3DPMISCCAPS_INDEPENDENTWRITEMASKS
1709 D3DPMISCCAPS_FOGANDSPECULARALPHA
1710 D3DPMISCCAPS_SEPARATEALPHABLEND
1711 D3DPMISCCAPS_MRTINDEPENDENTBITDEPTHS
1712 D3DPMISCCAPS_MRTPOSTPIXELSHADERBLENDING
1713 D3DPMISCCAPS_FOGVERTEXCLAMPED */
1715 /* The caps below can be supported but aren't handled yet in utils.c 'd3dta_to_combiner_input', disable them until support is fixed */
1717 if (GL_SUPPORT(NV_REGISTER_COMBINERS
))
1718 *pCaps
->PrimitiveMiscCaps
|= D3DPMISCCAPS_TSSARGTEMP
;
1719 if (GL_SUPPORT(NV_REGISTER_COMBINERS2
))
1720 *pCaps
->PrimitiveMiscCaps
|= D3DPMISCCAPS_PERSTAGECONSTANT
;
1723 *pCaps
->RasterCaps
= WINED3DPRASTERCAPS_DITHER
|
1724 WINED3DPRASTERCAPS_PAT
|
1725 WINED3DPRASTERCAPS_WFOG
|
1726 WINED3DPRASTERCAPS_ZFOG
|
1727 WINED3DPRASTERCAPS_FOGVERTEX
|
1728 WINED3DPRASTERCAPS_FOGTABLE
|
1729 WINED3DPRASTERCAPS_FOGRANGE
|
1730 WINED3DPRASTERCAPS_STIPPLE
|
1731 WINED3DPRASTERCAPS_SUBPIXEL
|
1732 WINED3DPRASTERCAPS_ZTEST
|
1733 WINED3DPRASTERCAPS_SCISSORTEST
|
1734 WINED3DPRASTERCAPS_SLOPESCALEDEPTHBIAS
|
1735 WINED3DPRASTERCAPS_DEPTHBIAS
;
1737 if (GL_SUPPORT(EXT_TEXTURE_FILTER_ANISOTROPIC
)) {
1738 *pCaps
->RasterCaps
|= WINED3DPRASTERCAPS_ANISOTROPY
|
1739 WINED3DPRASTERCAPS_ZBIAS
|
1740 WINED3DPRASTERCAPS_MIPMAPLODBIAS
;
1743 WINED3DPRASTERCAPS_COLORPERSPECTIVE
1744 WINED3DPRASTERCAPS_STRETCHBLTMULTISAMPLE
1745 WINED3DPRASTERCAPS_ANTIALIASEDGES
1746 WINED3DPRASTERCAPS_ZBUFFERLESSHSR
1747 WINED3DPRASTERCAPS_WBUFFER */
1749 *pCaps
->ZCmpCaps
= D3DPCMPCAPS_ALWAYS
|
1751 D3DPCMPCAPS_GREATER
|
1752 D3DPCMPCAPS_GREATEREQUAL
|
1754 D3DPCMPCAPS_LESSEQUAL
|
1756 D3DPCMPCAPS_NOTEQUAL
;
1758 *pCaps
->SrcBlendCaps
= D3DPBLENDCAPS_BLENDFACTOR
|
1759 D3DPBLENDCAPS_BOTHINVSRCALPHA
|
1760 D3DPBLENDCAPS_BOTHSRCALPHA
|
1761 D3DPBLENDCAPS_DESTALPHA
|
1762 D3DPBLENDCAPS_DESTCOLOR
|
1763 D3DPBLENDCAPS_INVDESTALPHA
|
1764 D3DPBLENDCAPS_INVDESTCOLOR
|
1765 D3DPBLENDCAPS_INVSRCALPHA
|
1766 D3DPBLENDCAPS_INVSRCCOLOR
|
1768 D3DPBLENDCAPS_SRCALPHA
|
1769 D3DPBLENDCAPS_SRCALPHASAT
|
1770 D3DPBLENDCAPS_SRCCOLOR
|
1773 *pCaps
->DestBlendCaps
= D3DPBLENDCAPS_BLENDFACTOR
|
1774 D3DPBLENDCAPS_BOTHINVSRCALPHA
|
1775 D3DPBLENDCAPS_BOTHSRCALPHA
|
1776 D3DPBLENDCAPS_DESTALPHA
|
1777 D3DPBLENDCAPS_DESTCOLOR
|
1778 D3DPBLENDCAPS_INVDESTALPHA
|
1779 D3DPBLENDCAPS_INVDESTCOLOR
|
1780 D3DPBLENDCAPS_INVSRCALPHA
|
1781 D3DPBLENDCAPS_INVSRCCOLOR
|
1783 D3DPBLENDCAPS_SRCALPHA
|
1784 D3DPBLENDCAPS_SRCALPHASAT
|
1785 D3DPBLENDCAPS_SRCCOLOR
|
1788 *pCaps
->AlphaCmpCaps
= D3DPCMPCAPS_ALWAYS
|
1790 D3DPCMPCAPS_GREATER
|
1791 D3DPCMPCAPS_GREATEREQUAL
|
1793 D3DPCMPCAPS_LESSEQUAL
|
1795 D3DPCMPCAPS_NOTEQUAL
;
1797 *pCaps
->ShadeCaps
= WINED3DPSHADECAPS_SPECULARGOURAUDRGB
|
1798 WINED3DPSHADECAPS_COLORGOURAUDRGB
|
1799 WINED3DPSHADECAPS_ALPHAFLATBLEND
|
1800 WINED3DPSHADECAPS_ALPHAGOURAUDBLEND
|
1801 WINED3DPSHADECAPS_COLORFLATRGB
|
1802 WINED3DPSHADECAPS_FOGFLAT
|
1803 WINED3DPSHADECAPS_FOGGOURAUD
|
1804 WINED3DPSHADECAPS_SPECULARFLATRGB
;
1806 *pCaps
->TextureCaps
= WINED3DPTEXTURECAPS_ALPHA
|
1807 WINED3DPTEXTURECAPS_ALPHAPALETTE
|
1808 WINED3DPTEXTURECAPS_BORDER
|
1809 WINED3DPTEXTURECAPS_MIPMAP
|
1810 WINED3DPTEXTURECAPS_PROJECTED
|
1811 WINED3DPTEXTURECAPS_PERSPECTIVE
|
1812 WINED3DPTEXTURECAPS_NONPOW2CONDITIONAL
;
1814 if( GL_SUPPORT(EXT_TEXTURE3D
)) {
1815 *pCaps
->TextureCaps
|= WINED3DPTEXTURECAPS_VOLUMEMAP
|
1816 WINED3DPTEXTURECAPS_MIPVOLUMEMAP
|
1817 WINED3DPTEXTURECAPS_VOLUMEMAP_POW2
;
1820 if (GL_SUPPORT(ARB_TEXTURE_CUBE_MAP
)) {
1821 *pCaps
->TextureCaps
|= WINED3DPTEXTURECAPS_CUBEMAP
|
1822 WINED3DPTEXTURECAPS_MIPCUBEMAP
|
1823 WINED3DPTEXTURECAPS_CUBEMAP_POW2
;
1827 *pCaps
->TextureFilterCaps
= WINED3DPTFILTERCAPS_MAGFLINEAR
|
1828 WINED3DPTFILTERCAPS_MAGFPOINT
|
1829 WINED3DPTFILTERCAPS_MINFLINEAR
|
1830 WINED3DPTFILTERCAPS_MINFPOINT
|
1831 WINED3DPTFILTERCAPS_MIPFLINEAR
|
1832 WINED3DPTFILTERCAPS_MIPFPOINT
|
1833 WINED3DPTFILTERCAPS_LINEAR
|
1834 WINED3DPTFILTERCAPS_LINEARMIPLINEAR
|
1835 WINED3DPTFILTERCAPS_LINEARMIPNEAREST
|
1836 WINED3DPTFILTERCAPS_MIPLINEAR
|
1837 WINED3DPTFILTERCAPS_MIPNEAREST
|
1838 WINED3DPTFILTERCAPS_NEAREST
;
1840 *pCaps
->CubeTextureFilterCaps
= 0;
1841 *pCaps
->VolumeTextureFilterCaps
= 0;
1843 *pCaps
->TextureAddressCaps
= D3DPTADDRESSCAPS_INDEPENDENTUV
|
1844 D3DPTADDRESSCAPS_CLAMP
|
1845 D3DPTADDRESSCAPS_WRAP
;
1847 if (GL_SUPPORT(ARB_TEXTURE_BORDER_CLAMP
)) {
1848 *pCaps
->TextureAddressCaps
|= D3DPTADDRESSCAPS_BORDER
;
1850 if (GL_SUPPORT(ARB_TEXTURE_MIRRORED_REPEAT
)) {
1851 *pCaps
->TextureAddressCaps
|= D3DPTADDRESSCAPS_MIRROR
;
1853 if (GL_SUPPORT(ATI_TEXTURE_MIRROR_ONCE
)) {
1854 *pCaps
->TextureAddressCaps
|= D3DPTADDRESSCAPS_MIRRORONCE
;
1857 *pCaps
->VolumeTextureAddressCaps
= 0;
1859 *pCaps
->LineCaps
= D3DLINECAPS_TEXTURE
|
1863 D3DLINECAPS_ALPHACMP
1866 *pCaps
->MaxTextureWidth
= GL_LIMITS(texture_size
);
1867 *pCaps
->MaxTextureHeight
= GL_LIMITS(texture_size
);
1869 *pCaps
->MaxVolumeExtent
= 0;
1871 *pCaps
->MaxTextureRepeat
= 32768;
1872 *pCaps
->MaxTextureAspectRatio
= 32768;
1873 *pCaps
->MaxVertexW
= 1.0;
1875 *pCaps
->GuardBandLeft
= 0;
1876 *pCaps
->GuardBandTop
= 0;
1877 *pCaps
->GuardBandRight
= 0;
1878 *pCaps
->GuardBandBottom
= 0;
1880 *pCaps
->ExtentsAdjust
= 0;
1882 *pCaps
->StencilCaps
= D3DSTENCILCAPS_DECRSAT
|
1883 D3DSTENCILCAPS_INCRSAT
|
1884 D3DSTENCILCAPS_INVERT
|
1885 D3DSTENCILCAPS_KEEP
|
1886 D3DSTENCILCAPS_REPLACE
|
1887 D3DSTENCILCAPS_ZERO
;
1888 if (GL_SUPPORT(EXT_STENCIL_WRAP
)) {
1889 *pCaps
->StencilCaps
|= D3DSTENCILCAPS_DECR
|
1890 D3DSTENCILCAPS_INCR
;
1892 if ( This
->dxVersion
> 8 &&
1893 ( GL_SUPPORT(EXT_STENCIL_TWO_SIDE
) ||
1894 GL_SUPPORT(ATI_SEPARATE_STENCIL
) ) ) {
1895 *pCaps
->StencilCaps
|= D3DSTENCILCAPS_TWOSIDED
;
1898 *pCaps
->FVFCaps
= D3DFVFCAPS_PSIZE
| 0x0008; /* 8 texture coords */
1900 *pCaps
->TextureOpCaps
= D3DTEXOPCAPS_ADD
|
1901 D3DTEXOPCAPS_ADDSIGNED
|
1902 D3DTEXOPCAPS_ADDSIGNED2X
|
1903 D3DTEXOPCAPS_MODULATE
|
1904 D3DTEXOPCAPS_MODULATE2X
|
1905 D3DTEXOPCAPS_MODULATE4X
|
1906 D3DTEXOPCAPS_SELECTARG1
|
1907 D3DTEXOPCAPS_SELECTARG2
|
1908 D3DTEXOPCAPS_DISABLE
;
1909 #if defined(GL_VERSION_1_3)
1910 *pCaps
->TextureOpCaps
|= D3DTEXOPCAPS_DOTPRODUCT3
|
1911 D3DTEXOPCAPS_SUBTRACT
;
1913 if (GL_SUPPORT(ARB_TEXTURE_ENV_COMBINE
) ||
1914 GL_SUPPORT(EXT_TEXTURE_ENV_COMBINE
) ||
1915 GL_SUPPORT(NV_TEXTURE_ENV_COMBINE4
)) {
1916 *pCaps
->TextureOpCaps
|= D3DTEXOPCAPS_BLENDDIFFUSEALPHA
|
1917 D3DTEXOPCAPS_BLENDTEXTUREALPHA
|
1918 D3DTEXOPCAPS_BLENDFACTORALPHA
|
1919 D3DTEXOPCAPS_BLENDCURRENTALPHA
|
1922 if (GL_SUPPORT(NV_TEXTURE_ENV_COMBINE4
)) {
1923 *pCaps
->TextureOpCaps
|= D3DTEXOPCAPS_ADDSMOOTH
|
1924 D3DTEXOPCAPS_MULTIPLYADD
|
1925 D3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR
|
1926 D3DTEXOPCAPS_MODULATECOLOR_ADDALPHA
|
1927 D3DTEXOPCAPS_BLENDTEXTUREALPHAPM
;
1931 *pCaps
->TextureOpCaps
|= D3DTEXOPCAPS_BUMPENVMAP
;
1933 D3DTEXOPCAPS_BUMPENVMAPLUMINANCE
1934 D3DTEXOPCAPS_PREMODULATE */
1937 *pCaps
->MaxTextureBlendStages
= GL_LIMITS(texture_stages
);
1938 *pCaps
->MaxSimultaneousTextures
= GL_LIMITS(textures
);
1939 *pCaps
->MaxUserClipPlanes
= GL_LIMITS(clipplanes
);
1940 *pCaps
->MaxActiveLights
= GL_LIMITS(lights
);
1944 #if 0 /* TODO: Blends support in drawprim */
1945 *pCaps
->MaxVertexBlendMatrices
= GL_LIMITS(blends
);
1947 *pCaps
->MaxVertexBlendMatrices
= 0;
1949 *pCaps
->MaxVertexBlendMatrixIndex
= 1;
1951 *pCaps
->MaxAnisotropy
= GL_LIMITS(anisotropy
);
1952 *pCaps
->MaxPointSize
= GL_LIMITS(pointsize
);
1955 *pCaps
->VertexProcessingCaps
= WINED3DVTXPCAPS_DIRECTIONALLIGHTS
|
1956 WINED3DVTXPCAPS_MATERIALSOURCE7
|
1957 WINED3DVTXPCAPS_POSITIONALLIGHTS
|
1958 WINED3DVTXPCAPS_LOCALVIEWER
|
1959 WINED3DVTXPCAPS_VERTEXFOG
|
1960 WINED3DVTXPCAPS_TEXGEN
;
1962 D3DVTXPCAPS_TWEENING */
1964 *pCaps
->MaxPrimitiveCount
= 0xFFFFFFFF;
1965 *pCaps
->MaxVertexIndex
= 0xFFFFFFFF;
1966 *pCaps
->MaxStreams
= MAX_STREAMS
;
1967 *pCaps
->MaxStreamStride
= 1024;
1969 /* FIXME: the shader mode should be per adapter */
1970 if (wined3d_settings
.vs_selected_mode
== SHADER_GLSL
) {
1971 *pCaps
->VertexShaderVersion
= D3DVS_VERSION(3,0);
1972 TRACE_(d3d_caps
)("Hardware vertex shader version 3.0 enabled (GLSL)\n");
1973 } else if (wined3d_settings
.vs_selected_mode
== SHADER_ARB
) {
1974 *pCaps
->VertexShaderVersion
= D3DVS_VERSION(1,1);
1975 TRACE_(d3d_caps
)("Hardware vertex shader version 1.1 enabled (ARB_PROGRAM)\n");
1976 } else if (wined3d_settings
.vs_selected_mode
== SHADER_SW
) {
1977 *pCaps
->VertexShaderVersion
= D3DVS_VERSION(3,0);
1978 TRACE_(d3d_caps
)("Software vertex shader version 3.0 enabled\n");
1980 *pCaps
->VertexShaderVersion
= 0;
1981 TRACE_(d3d_caps
)("Vertex shader functionality not available\n");
1984 *pCaps
->MaxVertexShaderConst
= GL_LIMITS(vshader_constantsF
);
1986 /* FIXME: the shader ode should be per adapter */
1987 if (wined3d_settings
.ps_selected_mode
== SHADER_GLSL
) {
1988 *pCaps
->PixelShaderVersion
= D3DPS_VERSION(3,0);
1989 /* FIXME: The following line is card dependent. -1.0 to 1.0 is a safe default clamp range for now */
1990 *pCaps
->PixelShader1xMaxValue
= 1.0;
1991 TRACE_(d3d_caps
)("Hardware pixel shader version 3.0 enabled (GLSL)\n");
1992 } else if (wined3d_settings
.ps_selected_mode
== SHADER_ARB
) {
1993 *pCaps
->PixelShaderVersion
= D3DPS_VERSION(1,4);
1994 *pCaps
->PixelShader1xMaxValue
= 1.0;
1995 TRACE_(d3d_caps
)("Hardware pixel shader version 1.4 enabled (ARB_PROGRAM)\n");
1996 /* FIXME: Uncomment this when there is support for software Pixel Shader 3.0 and PS_SW is defined
1997 } else if (wined3d_settings.ps_selected_mode = SHADER_SW) {
1998 *pCaps->PixelShaderVersion = D3DPS_VERSION(3,0);
1999 *pCaps->PixelShader1xMaxValue = 1.0;
2000 TRACE_(d3d_caps)("Software pixel shader version 3.0 enabled\n"); */
2002 *pCaps
->PixelShaderVersion
= 0;
2003 *pCaps
->PixelShader1xMaxValue
= 0.0;
2004 TRACE_(d3d_caps
)("Pixel shader functionality not available\n");
2007 /* ------------------------------------------------
2008 The following fields apply to d3d9 only
2009 ------------------------------------------------ */
2010 if (This
->dxVersion
> 8) {
2011 GLint max_buffers
= 1;
2012 FIXME("Caps support for directx9 is nonexistent at the moment!\n");
2013 *pCaps
->DevCaps2
= 0;
2014 /* TODO: D3DDEVCAPS2_CAN_STRETCHRECT_FROM_TEXTURES */
2015 *pCaps
->MaxNpatchTessellationLevel
= 0;
2016 *pCaps
->MasterAdapterOrdinal
= 0;
2017 *pCaps
->AdapterOrdinalInGroup
= 0;
2018 *pCaps
->NumberOfAdaptersInGroup
= 1;
2019 *pCaps
->DeclTypes
= 0;
2020 #if 0 /*FIXME: Simultaneous render targets*/
2021 GL_MAX_DRAW_BUFFERS_ATI
0x00008824
2022 if (GL_SUPPORT(GL_MAX_DRAW_BUFFERS_ATI
)) {
2024 glEnable(GL_MAX_DRAW_BUFFERS_ATI
);
2025 glGetIntegerv(GL_MAX_DRAW_BUFFERS_ATI
, &max_buffers
);
2026 glDisable(GL_MAX_DRAW_BUFFERS_ATI
);
2030 *pCaps
->NumSimultaneousRTs
= max_buffers
;
2031 *pCaps
->StretchRectFilterCaps
= 0;
2032 *pCaps
->VS20Caps
.Caps
= 0;
2033 *pCaps
->PS20Caps
.Caps
= 0;
2034 *pCaps
->VertexTextureFilterCaps
= 0;
2035 *pCaps
->MaxVShaderInstructionsExecuted
= 0;
2036 *pCaps
->MaxPShaderInstructionsExecuted
= 0;
2037 *pCaps
->MaxVertexShader30InstructionSlots
= 0;
2038 *pCaps
->MaxPixelShader30InstructionSlots
= 0;
2045 /* Note due to structure differences between dx8 and dx9 D3DPRESENT_PARAMETERS,
2046 and fields being inserted in the middle, a new structure is used in place */
2047 static HRESULT WINAPI
IWineD3DImpl_CreateDevice(IWineD3D
*iface
, UINT Adapter
, WINED3DDEVTYPE DeviceType
, HWND hFocusWindow
,
2048 DWORD BehaviourFlags
, IWineD3DDevice
** ppReturnedDeviceInterface
,
2051 IWineD3DDeviceImpl
*object
= NULL
;
2052 IWineD3DImpl
*This
= (IWineD3DImpl
*)iface
;
2054 HRESULT temp_result
;
2056 /* Validate the adapter number */
2057 if (Adapter
>= IWineD3D_GetAdapterCount(iface
)) {
2058 return WINED3DERR_INVALIDCALL
;
2061 /* Create a WineD3DDevice object */
2062 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IWineD3DDeviceImpl
));
2063 *ppReturnedDeviceInterface
= (IWineD3DDevice
*)object
;
2064 TRACE("Created WineD3DDevice object @ %p\n", object
);
2065 if (NULL
== object
) {
2066 return WINED3DERR_OUTOFVIDEOMEMORY
;
2069 /* Set up initial COM information */
2070 object
->lpVtbl
= &IWineD3DDevice_Vtbl
;
2072 object
->wineD3D
= iface
;
2073 IWineD3D_AddRef(object
->wineD3D
);
2074 object
->parent
= parent
;
2076 /* Set the state up as invalid until the device is fully created */
2077 object
->state
= WINED3DERR_DRIVERINTERNALERROR
;
2079 TRACE("(%p)->(Adptr:%d, DevType: %x, FocusHwnd: %p, BehFlags: %lx, RetDevInt: %p)\n", This
, Adapter
, DeviceType
,
2080 hFocusWindow
, BehaviourFlags
, ppReturnedDeviceInterface
);
2082 /* Save the creation parameters */
2083 object
->createParms
.AdapterOrdinal
= Adapter
;
2084 object
->createParms
.DeviceType
= DeviceType
;
2085 object
->createParms
.hFocusWindow
= hFocusWindow
;
2086 object
->createParms
.BehaviorFlags
= BehaviourFlags
;
2088 /* Initialize other useful values */
2089 object
->adapterNo
= Adapter
;
2090 object
->devType
= DeviceType
;
2092 TRACE("(%p) : Creating stateblock\n", This
);
2093 /* Creating the startup stateBlock - Note Special Case: 0 => Don't fill in yet! */
2094 if (WINED3D_OK
!= IWineD3DDevice_CreateStateBlock((IWineD3DDevice
*)object
,
2096 (IWineD3DStateBlock
**)&object
->stateBlock
,
2097 NULL
) || NULL
== object
->stateBlock
) { /* Note: No parent needed for initial internal stateblock */
2098 WARN("Failed to create stateblock\n");
2099 goto create_device_error
;
2101 TRACE("(%p) : Created stateblock (%p)\n", This
, object
->stateBlock
);
2102 object
->updateStateBlock
= object
->stateBlock
;
2103 IWineD3DStateBlock_AddRef((IWineD3DStateBlock
*)object
->updateStateBlock
);
2104 /* Setup surfaces for the backbuffer, frontbuffer and depthstencil buffer */
2106 /* Setup some defaults for creating the implicit swapchain */
2108 /* FIXME: both of those should be made per adapter */
2109 IWineD3DImpl_FillGLCaps(iface
, IWineD3DImpl_GetAdapterDisplay(iface
, Adapter
));
2111 select_shader_mode(&This
->gl_info
, DeviceType
,
2112 &wined3d_settings
.ps_selected_mode
, &wined3d_settings
.vs_selected_mode
);
2113 select_shader_max_constants(&This
->gl_info
);
2115 temp_result
= allocate_shader_constants(object
->updateStateBlock
);
2116 if (WINED3D_OK
!= temp_result
)
2119 /* set the state of the device to valid */
2120 object
->state
= WINED3D_OK
;
2122 /* Get the initial screen setup for ddraw */
2123 object
->ddraw_width
= GetSystemMetrics(SM_CXSCREEN
);
2124 object
->ddraw_height
= GetSystemMetrics(SM_CYSCREEN
);
2125 hDC
= CreateDCA("DISPLAY", NULL
, NULL
, NULL
);
2126 object
->ddraw_format
= pixelformat_for_depth(GetDeviceCaps(hDC
, BITSPIXEL
) * GetDeviceCaps(hDC
, PLANES
));
2130 create_device_error
:
2132 /* Set the device state to error */
2133 object
->state
= WINED3DERR_DRIVERINTERNALERROR
;
2135 if (object
->updateStateBlock
!= NULL
) {
2136 IWineD3DStateBlock_Release((IWineD3DStateBlock
*)object
->updateStateBlock
);
2137 object
->updateStateBlock
= NULL
;
2139 if (object
->stateBlock
!= NULL
) {
2140 IWineD3DStateBlock_Release((IWineD3DStateBlock
*)object
->stateBlock
);
2141 object
->stateBlock
= NULL
;
2143 if (object
->renderTarget
!= NULL
) {
2144 IWineD3DSurface_Release(object
->renderTarget
);
2145 object
->renderTarget
= NULL
;
2147 if (object
->stencilBufferTarget
!= NULL
) {
2148 IWineD3DSurface_Release(object
->stencilBufferTarget
);
2149 object
->stencilBufferTarget
= NULL
;
2151 if (object
->stencilBufferTarget
!= NULL
) {
2152 IWineD3DSurface_Release(object
->stencilBufferTarget
);
2153 object
->stencilBufferTarget
= NULL
;
2155 HeapFree(GetProcessHeap(), 0, object
);
2156 *ppReturnedDeviceInterface
= NULL
;
2157 return WINED3DERR_INVALIDCALL
;
2161 static HRESULT WINAPI
IWineD3DImpl_GetParent(IWineD3D
*iface
, IUnknown
**pParent
) {
2162 IWineD3DImpl
*This
= (IWineD3DImpl
*)iface
;
2163 IUnknown_AddRef(This
->parent
);
2164 *pParent
= This
->parent
;
2168 /**********************************************************
2169 * IWineD3D VTbl follows
2170 **********************************************************/
2172 const IWineD3DVtbl IWineD3D_Vtbl
=
2175 IWineD3DImpl_QueryInterface
,
2176 IWineD3DImpl_AddRef
,
2177 IWineD3DImpl_Release
,
2179 IWineD3DImpl_GetParent
,
2180 IWineD3DImpl_GetAdapterCount
,
2181 IWineD3DImpl_RegisterSoftwareDevice
,
2182 IWineD3DImpl_GetAdapterMonitor
,
2183 IWineD3DImpl_GetAdapterModeCount
,
2184 IWineD3DImpl_EnumAdapterModes
,
2185 IWineD3DImpl_GetAdapterDisplayMode
,
2186 IWineD3DImpl_GetAdapterIdentifier
,
2187 IWineD3DImpl_CheckDeviceMultiSampleType
,
2188 IWineD3DImpl_CheckDepthStencilMatch
,
2189 IWineD3DImpl_CheckDeviceType
,
2190 IWineD3DImpl_CheckDeviceFormat
,
2191 IWineD3DImpl_CheckDeviceFormatConversion
,
2192 IWineD3DImpl_GetDeviceCaps
,
2193 IWineD3DImpl_CreateDevice